我如何使用安装后编辑 package.json

How can i edit a package.json with postinstall

我在 npm 上创建了一个包,它创建了一个 "scss directory stucture",我想 copy/add 自定义脚本到项目根目录下的 package.json 文件。

MY-PROJECT
├── node_modules
├── scss
└── package.json <--

我所能做的就是将文件名 "package.json" 复制到本地目录,但如果已有文件,它将覆盖它。

显然我不想覆盖那个文件,而只是添加像 "npm run watch" 这样的脚本。因此,用户可以立即开始其项目,而无需自己编写这些脚本。

感谢帮助

您可以编写小脚本并在脚本中添加命令或修改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))'"
  },
}

利用以下 node.js 脚本:

post-install.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 文件位于同一目录中。


解释:

  1. 在读取的代码行中:

    const pkgJsonPath = require.main.paths[0].split('node_modules')[0] + 'package.json'
    

    我们为正在使用您的 npm 包的项目获取 package.json 的路径,并将其分配给 pkgJsonPath 变量。

    • require.main.paths returns 路径名数组。

    • 我们在索引 0split() 处获取路径名,使用 node_modules 作为分隔符。

    • 索引 0 处的结果数组元素为我们提供了项目目录的路径名(即正在使用您的 npm 包的项目的路径名)。

    • 最后使用加号运算符 (+) 连接 package.json 字符串。

  2. 接下来我们 require package.json 文件并将解析的 JSON 分配给 json变量.

  3. 然后我们检查 package.json 是否有一个 scripts 键,如果没有我们创建一个新的scripts property/key 并为其分配一个空对象,即

    if (!json.hasOwnProperty('scripts')) {
      json.scripts = {};
    }
    
  4. 以下部分是我们定义要添加到 package.json 文件的自定义 npm 脚本的地方 - 您需要更改此部分根据需要部分:

    json.scripts['watch'] = '<some_commands_here>';
    
  5. 最后我们JSON.stringify() the json object and overwrite the original package.json file with the new data using fs.writeFileSync().

我遇到了类似的问题。如果您需要编辑 root package.json,而带有“postinstall”脚本的模块作为 npm 依赖项安装在某些消费者项目中,那么您需要在父目录中查找,只要没有 package.json resolved

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');