如何使用 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.jsonscripts 部分中,按如下方式定义 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作为分隔符在索引0split()获取路径名。

    索引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的解决办法

sh Cisco AnyConnect Postinstall

json Heroku的postinstall和启动脚本