如何使用 postinstall 编辑 package.json
Posted
技术标签:
【中文标题】如何使用 postinstall 编辑 package.json【英文标题】:How can i edit a package.json with postinstall 【发布时间】:2020-08-20 10:24:19 【问题描述】:我在 npm 上创建了一个包,它创建了一个“scss 目录结构”,我想将自定义脚本复制/添加到项目根目录下的 package.json 文件中。
MY-PROJECT
├── node_modules
├── scss
└── package.json <--
我所能做的就是将一个文件名“package.json”复制到本地目录,但如果已经有一个,它将覆盖它。
显然我不想覆盖该文件,而只想添加诸如“npm run watch”之类的脚本。这样用户就可以立即开始其项目,而无需自己编写这些脚本。
感谢您的帮助
【问题讨论】:
【参考方案1】:利用以下 node.js 脚本:
安装后.js
const saveFile = require('fs').writeFileSync;
const pkgJsonPath = require.main.paths[0].split('node_modules')[0] + 'package.json';
const json = require(pkgJsonPath);
if (!json.hasOwnProperty('scripts'))
json.scripts = ;
json.scripts['watch'] = '<some_commands_here>';
saveFile(pkgJsonPath, JSON.stringify(json, null, 2));
package.json
在 package.json 的 scripts
部分中,按如下方式定义 postinstall
脚本:
"scripts":
"postinstall": "node post-install"
注意: npm 脚本(上图)假定 post-install.js
与您的 package.json
文件位于同一目录中。
说明:
在代码行中:
const pkgJsonPath = require.main.paths[0].split('node_modules')[0] + 'package.json'
我们为正在使用您的 npm 包的项目获取 package.json 的路径,并将其分配给 pkgJsonPath
变量。
require.main.paths
返回一个路径名数组。
我们使用node_modules
作为分隔符在索引0
和split()
获取路径名。
索引0
处的结果数组元素为我们提供了项目目录的路径名(即,正在使用您的 npm 包的项目的路径名)。
最后,package.json
字符串使用加号运算符 (+
) 连接起来。
接下来我们 require
package.json 文件并将解析后的 JSON 分配给 json
变量。
然后我们检查 package.json 是否有scripts
键,如果没有,我们创建一个新的scripts
属性/键并为其分配一个空对象,即
if (!json.hasOwnProperty('scripts'))
json.scripts = ;
以下部分是我们定义要添加到 package.json 文件的自定义 npm 脚本的地方 - 您需要根据需要更改此部分:
json.scripts['watch'] = '<some_commands_here>';
最后我们JSON.stringify()
json
对象并使用fs.writeFileSync()
用新数据覆盖原始package.json 文件。
【讨论】:
【参考方案2】:您可以编写小脚本并在脚本中添加命令或修改package.json
script.js
const json = require("./package.json")
json.scripts["run:watch"] = "npm run watch"
require("fs").writeFileSync(process.cwd() + "/package.json", JSON.stringify(json, null, 2))
package.json
"scripts":
"postinstall": "node script.js"
您也可以编写示例脚本内联字符串,并使用node -e
运行
"scripts":
"postinstall": "node -e 'const json = require(\"./package.json\"); json.scripts[\"run:watch\"] = \"npm run watch\";require(\"fs\").writeFileSync(process.cwd() + \"/package.json\", JSON.stringify(json, null, 2))'"
,
【讨论】:
几乎是我需要的。但我想将该脚本复制到项目根级别的 package.json 中,而不是 node_modules/my_package 中的那个。有没有办法用上面的代码来定位这个文件?谢谢【参考方案3】:我遇到了类似的问题。如果您需要编辑根 package.json,而您的带有“postinstall”脚本的模块作为 npm 依赖项安装在某些使用者项目中,那么只要没有解析 package.json,您就需要在父目录中查找
const fs = require('fs');
const path = require('path');
let rootPath = '../';
while (!fs.existsSync(path.resolve(rootPath, 'package.json')))
rootPath += '../';
const pkgJsonPath = path.resolve(rootPath, 'package.json');
【讨论】:
以上是关于如何使用 postinstall 编辑 package.json的主要内容,如果未能解决你的问题,请参考以下文章
如何通过 postinstall npm 脚本自动将文件从包复制到本地目录?
如何postinstall优雅地更改node_modules里的包
如何postinstall优雅地更改node_modules里的包
electron-quick-start卡在postinstall的解决办法