我创建了一个cli应用程序,它使用下面的代码从package.json读取其版本号
const packageJson = JSON.parse(fs.readFileSync(path.resolve('./package.json'), 'utf8'))
如果我在开发过程中使用yarn start
或类似命令运行应用程序,这可以正常工作。但是在使用npm install --global app-name
安装包后,用户应该使用系统上任何路径的declare可执行文件。因此,如果我想在/Users/myUser/Desktop
中运行它,我会收到如下错误
Error: ENOENT: no such file or directory, open '/Users/myUser/Desktop/package.json'
那么,在我的CLI中加载这个package.json的好协议是什么呢?或者有没有更好的方法来实现这一点?
稍后编辑:为了清楚起见,我的包json包含以下内容
{
...
"bin": {
"clip": "./bin/clip.js"
},
...
}
所以我的问题是指,在使用npm publish
之后,从不同的路径运行可执行文件“clip
经过一番研究,我尝试了以下代码(使用path.dirname函数):
const __filename = fileURLToPath(import.meta.url)
const __dirname = path.dirname(__filename)
export const packageJsonLocation = path.join(__dirname, './../package.json')
const packageJson = JSON.parse(fs.readFileSync(packageJsonLocation, 'utf8'))
和这个(使用node的标准import关键字将文件导入为json)
import * as packageJson from './../package.json' assert { type: 'json' }
在这两种情况下,我得到了相同的结果,生成了可执行文件,并尝试从当前目录读取package.json。特别是,如果我尝试使用console.log()路径,我会得到我正在执行全局可执行文件的当前路径(在我的情况下是clip)
2条答案
按热度按时间ttisahbt1#
使用
__dirname
是因为它总是引用包含此变量的文件的路径,而./
提供的是工作目录,例如process.cwd()
。如果您使用ES模块,也要获取
__dirname
编辑:
您使用bin全局安装了软件包,但使用CLI调用的bin是一个符号链接,位于路径
<npm_glob_path>/node_modules/bin
内,而不是<npm_glob_path>/node_modules/app-name/bin
内。应用的package.json
位于<npm_glob_path>/node_modules/app-name
内。不要使用./
,始终使用path
调用因此,请尝试以下操作(将
app-name
替换为您的应用名称):请在定义
__dirname
之后添加console.log('__dirname:' + __dirname)
。运行CLI应用程序时,您看到的是哪个路径?mu0hgdu02#
有没有更好的方法来处理这个问题?
是的-你应该把版本号保存在实际的软件包中,这样它就可以随时访问,并且不会有package.json版本和安装版本不同步的风险。例如,如果有人把你的软件包添加到一个项目中,然后运行
yarn install
,但后来使用git pull
来获取本地文件的最新版本,其中恰好包含您的软件包的版本提升,则会出现一个窗口,其中package.json的版本号与已安装版本不同。