从命令行编辑package.json

77

我想从一个Shell脚本中添加或编辑我的package.json文件中的变量。如果我的package.json文件是这样的:

{
  "name": "my-project",
  "description": "Project by @DerZyklop",
  "version": "0.0.0",
  ...

我希望你能提供一个类似的命令

npm config set foo bar

添加一个类似于的新字段

{
  "name": "my-project",
  "description": "Project by @DerZyklop",
  "foo": "bar",
  "version": "0.0.0",
  ...

...但不幸的是,npm config set 只编辑了 ~/.npmrc 而没有编辑我的 package.json 文件。


你可以使用nano打开它,并手动编辑它... - MightyPork
@MightyPork 抱歉如果我表达得不够清楚。最终我想要一个shell脚本,它可以(除了其他任务之外)编辑package.json中的一个值。 - DerZyklop
7个回答

106

package.json 是一个 json 文件,所以你可以使用工具 json。要安装它,请使用以下命令:

npm install -g json

然后你可以原地编辑文件。更多信息在这里

示例

$ cat package.json
{
  "name": "my-project",
  "description": "Project by @DerZyklop",
  "version": "0.0.0"
}

$ json -I -f package.json -e "this.foo=\"bar\""
json: updated "package.json" in-place

$ cat package.json
{
  "name": "my-project",
  "description": "Project by @DerZyklop",
  "version": "0.0.0",
  "foo": "bar"
}

1
非常感谢您的帮助。虽然我已经用Node编写了我的脚本像这样,但我也测试了您的建议,它也可以正常工作。 - DerZyklop
2
@masimakopoulos:假设你在谈论bash,那么字符串插值仅适用于双引号字符串。因此,您需要交换单引号和双引号,如下所示:"this.foo='$A'"。(这是正常的bash行为,因此您可以使用echo "this.foo='$A'"进行测试) - enrico.bacis
谢谢。我采用了您的方法,在我的package.json中添加了默认的“start”键,指向一个index.js脚本(这不是Yarn的默认包含,但在运行我的Docker镜像时被调用)npm install -g json; json --in-place -f package.json -e 'this.scripts={"start": "node index.js"}' - Luke Schoen
5
示例对我没有起作用(可能是由于引用问题),在此处描述:https://github.com/trentm/json/issues/117#issuecomment-322848900 - 对我有效的命令是像这样使用双引号:json -I -f package.json -e "this.foo="bar""。 - Elijah Lofgren
如果你的项目只安装了json包作为依赖,运行该命令时请使用npx json - silkfire
显示剩余2条评论

48

你确实有一个原生的NPM命令:

npm pkg set 'scripts.test'='jest'

当你想分享一个命令时,这将非常有帮助。你可以直接分享这个命令,而不是要求别人安装一些CLI工具。

顺便说一下,如果你使用NPM工作区,那么它会更加有用,因为在这种情况下,你可以同时更改所有的包:

npm pkg set 'scripts.test'='jest' -ws

13
2022年了,这应该是被接受的答案。它最简单,完全按照问题要求执行,不使用任何额外的工具。 - noamtm
在yarn中有相等的命令吗? - Dulaj Ariyaratne
是的。也可以使用yarn:https://yarnpkg.com/cli/config/set (yarn config set 'scripts.test' 'jest') - Shl
对于任何JSON文件呢? - undefined

19

如果您不想安装任何东西,也可以使用一行脚本来修改 package.json 文件:

node -e "let pkg=require('./package.json'); pkg.homepage='${CI_PAGES_URL}'; require('fs').writeFileSync('package.json', JSON.stringify(pkg, null, 2));"

14

如果您不想安装spongejson,也可以执行以下操作

echo "`jq '.foo="bar"' package.json`" > package.json

我喜欢这个 ;) - benCat

10
你也可以像这样使用 sponge(moreutils 软件包):
jq '.foo="bar"' package.json | sponge package.json

通过环境变量:

jq --arg h "$HOMEPAGE" '.homepage=$h' package.json | sponge package.json

10

我只想更新package.json中的version属性,这是我的解决方案:

# this sets the version 
# in package.json to 1.0.2
npm version 1.0.2 # creates a git-tag too
npm version 1.0.2 --no-git-tag-version # only changes the version without creating a git-tag

4
请记住,它还为该版本创建标签。如果不需要这些标签,请使用“--no-git-tag-version”选项。 - Zebiano

4

此外,还有一个名为npe的npm包可用于执行此操作:https://github.com/zeke/npe

cd some/node/project

# Get stuff from package.json
npe name
npe scripts
npe scripts.test
npe repository.url
open $(npe repository.url)

# Set stuff in package.json
npe name foo
npe scripts.start "node index.js"

# Keywords string will be turned into an array
# If commas are present, they'll be the delimiter. Otherwise spaces.
npe keywords "foo, bar, cheese whiz"
npe keywords "foo bar baz"

# The current working directory's package.json is used by default,
# but you can point to another package file with a flag:
npe name --package=some/other/package.json
npe name other --package=some/other/package.json

可以删除一个键吗? - ulmas

网页内容由stack overflow 提供, 点击上面的
可以查看英文原文,
原文链接