使用发布复制文件夹和包

Copy in folder and package with publish

有没有办法将 package.json 中包含的文件(在 File 字段中)复制到一个文件夹中,以便与 npm publish 一起打包?

我的仓库:

.
├── package.json
└── folder0
    ├── file0
    └── folder1
       └── file1

我的package.json:

{
  "name": "example",
  "version": "0.2.0",
  "files": [
    "folder0/file0",
    "folder0/folder1/file1"
  ],
  "author": "cruiz"
}

期望输出:

我想要在我的包裹中:

.
├── package.json
└── build
    ├── file0
    └── file1

编辑:

非常感谢您的回复。我正在尝试使用 npm 来打包 VHDL 代码,所以我真的是菜鸟:(

可不可以把要打包的文件放在package.json的字段里,然后从脚本中读取?

{ 
  "name": "example",
  "version": "0.2.0",
  "customField": [
    "folder0/file0",
    "folder0/folder1/file1"
  ],
  "scripts": {
    "prepublishOnly": "mkdirp build && copyfiles -f [..read CustomField...] build"
  },
  "author": "cruiz"
}

您基本上想要的是构建步骤。您可以在 prepublish 脚本中执行所有这些操作,例如:

package.json

{
  "scripts": {
    "prepublish": "mkdir -p build && cp folder0/file0 folder0/folder1/file1 build"
  }
}

但是你也应该改变你的files,除非你真的想要两个结构,在buildfolder0/*中。

修改后的答案:

根据 OP 的编辑进行编辑。

Is it possible to put the files to be packaged in a field of package.json and read them from the script.

是的,这是可能的,但是您需要使用自定义节点脚本来执行此操作。据我所知,目前没有可用于实现此目的的软件包。

解法:

  1. 首先,cd 到您的项目目录并卸载我在原始答案中提到的包,因为我们不会使用它们。您可以通过 运行 执行以下命令来执行此操作:

    npm un -D mkdirp copyfile
    
  2. 使用以下命令安装 shelljs

    npm i -D shelljs
    

    注意:现在将使用 shelljs 而不是 mkdirpcopyfile 来创建目录,然后复制 package.json.

  3. 接下来创建一个包含以下内容的节点脚本。让我们将文件命名为 copy-files.js 并将其保存到项目目录顶层名为 .scripts 的隐藏目录中。即

    目录结构

    project
    ├── .scripts
    │   └── copy-files.js
    ├── node_modules
    │   └── ...
    ├── package.json
    ├── folder0
    │   ├── file0.js
    │   └── folder1
    │      └── file1.js
    └── ...
    

    copy-files.js

    的内容
    const shell = require('shelljs');
    const pkg = require('../package.json');
    
    // The path to the directory to copy the file(s) to.
    const DEST_DIR = './build';
    
    // NOTE: `customField` below should be replaced with the
    // actual key name in the final `package.json`.
    const srcFilePaths = pkg.customField;
    
    // Create a new destination directory and intermediate
    // directories if necessary.
    if (!shell.test('-d', DEST_DIR)) {
      shell.mkdir('-p', DEST_DIR);
    }
    
    // Recursively copy each file listed in the `customField` Array.
    // Logs and error if the file listed cannot be found.
    srcFilePaths.forEach(function (srcPath) {
      if (!shell.test('-e', srcPath)) {
        shell.echo('Error: Cannot find file listed in package.json: %s', srcPath);
        process.exit(1);
      }
      shell.cp(srcPath, DEST_DIR);
    });
    

    注意const srcFilePaths = pkg.customField;中的customField部分(在上面copy-files.js的第9行)需要替换为您决定在最终 package.json.

  4. 中使用的实际真实密钥名称
  5. 最后,更新您的 prepublishOnly 脚本以调用自定义节点脚本(即 copy-file.js),如 package.json 的以下摘录所示:

    {
      ...
      "customField": [
        "folder0/file0.js",
        "folder0/folder1/file1.js"
      ],
      "scripts": {
        "prepublishOnly": "node .scripts/copy-files",
      },
      ...
    }
    

原答案

这可以通过在您的 package.json 文件中使用自定义 npm-script 来实现。如您所述,使用 pre 脚本也将满足您的要求:

package them together with npm publish


1。在 npm 脚本中使用 prepost 钩子:

所有 npm 脚本都支持所谓的 prepost 挂钩。任何 pre 脚本将 运行 在其各自的脚本(或命令)之前,任何 post 脚本将 运行 在其各自的脚本(或命令)之后。

为了更好地理解此功能,假设我们的 package.json 包含以下摘录中显示的人为脚本:

...
"scripts": {
  "prefoo": "...",
  "foo": "...",
  "postfoo": "..."
},
...

如你所见:

  1. 有一个名为 foo 的脚本,它有一个相应的带有 pre 前缀的脚本,即 prefoo.
  2. 同样的,同样的foo脚本还有另外一个对应的脚本,只不过这个脚本的前缀是post,即postfoo.

以这种方式指定脚本将在您通过 运行ning npm run foo 通过 CLI 调用 foo 脚本时产生以下结果:

  1. prefoo 脚本会在 foo 脚本执行前自动 运行。
  2. postfoo会在foo完成后自动运行。

有关 prepost 挂钩的更多信息,请参见 here


2。那么我应该使用哪个 pre 脚本?

有几个 built-in pre 脚本可能会满足您的要求;那些 prepublishprepublishOnly。 npm 文档为这些挂钩提供了以下描述:

  • prepublish: Run BEFORE the package is packed and published, as well as on local npm install without any arguments. (See below)

  • prepublishOnly: Run BEFORE the package is prepared and packed, ONLY on npm publish...

注意:以下解决方案使用 prepublishOnly,因为我很确定当用户 运行 时您不希望此脚本 运行 npm install。但是,您需要决定是使用它还是将其换成 prepublish。有关每个 pre 挂钩的详细信息,请参阅 docs


3。解决方案

  1. 对于 跨平台 的解决方案,您需要首先 cd 到您的项目目录并安装几个额外的 npm 包.

    • 通过 运行ning 安装 mkdirpnpm i -D mkdirp

    • 通过 运行ning 安装 copyfilenpm i -D copyfiles

  2. package.json 文件的 scripts 部分添加以下内容:

    ...
    "scripts": {
      "prepublishOnly": "mkdirp build && copyfiles -f folder0/file0.js folder0/folder1/file1.js build"
    },
    ...
    

现在当你运行; npm run publishprepublishOnly 脚本将自动 运行,(即复制文件以满足您所需的目录结构),然后再准备好并打包发布。

当然可以运行; npm run prepublishOnly,如果你想在运行ning之前测试脚本的结果:npm run publish