如何使用npm脚本重命名文件

11

我正在使用 copyfiles 作为npm的scirptcopyfiles -u 2 /src/app/conf.dev.json dist/config/,但最终我想将文件重命名。

您如何将输入文件重命名为类似于conf.json的某物?

我查看了文档,发现使用copyfiles无法实现。有什么想法吗?

更新: 我按照Rename file with NPM进行操作,但在执行npm run copy时出现错误:

"copy": "copyfiles -u 2 /src/app/conf.dev.json dist/config/ && node -e require('fs').rename('dist/config/conf.prod.json','dist/config/conf.json')"

fs.js:137 throw new ERR_INVALID_CALLBACK(); ^

TypeError [ERR_INVALID_CALLBACK]: Callback必须是一个函数

4个回答

21

以下是几种成功满足您要求的解决方案:

方案A

@vitorlui的答案中所述,使用内置的nodejs fs.rename()必须提供回调参数。

此外,当通过npm脚本使用node -e命令时,需要将要评估的脚本用JSON转义的双引号括起来,即\"...\"

  1. 例如,将package.json文件中的scripts部分配置如下:

    "scripts": {
      "rename": "node -e \"require('fs').rename('dist/config/conf.dev.json', 'dist/config/conf.json', function(err) { if (err) console.log(err); console.log('File successfully renamed!') })\"",
      "copy": "copyfiles -u 2 \"src/app/conf.dev.json\" \"dist/config/\"",
      "copy-and-rename": "npm run copy && npm run rename"
    },
    
  2. 然后运行以下npm命令:

  3. npm run copy-and-rename
    
  4. 成功完成后,文件被复制并重命名后,您应该在控制台上看到以下内容:

    文件已成功重命名!


解决方案B

您还可以考虑安装并使用renamer来重命名文件。如果您的重命名要求比问题中提供的示例更复杂,或者希望获得比解决方案A更简洁的工具,则可能会有所帮助。

安装并检查版本:

  1. cd到您的项目目录,并运行以下命令安装renamer

  2. npm i -D renamer
    
    然后运行以下命令来检查已安装的renamer版本。
    npm ls renamer
    

注意:我要求您检查已安装的版本,因为这将确定您应使用哪些renamer命令。如果安装的版本是<0.7.0或>=0.7.0,则略有不同:


如果安装的renamer版本是<0.7.0

  1. package.jsonscripts 部分设置为以下内容:

"scripts": {
  "rename": "renamer --dry-run -f --regex \"^conf.dev.json$\" -r \"conf.json\" \"dist/config/*\"",
  "copy": "copyfiles -u 2 \"src/app/conf.dev.json\" \"dist/config/\"",
  "copy-and-rename": "npm run copy && npm run rename"
},
  • 然后运行以下npm命令:

    npm run copy-and-rename
    
  • 您应该在控制台上看到类似以下内容的记录;

    √ dist\config\conf.dev.json -> dist\config\conf.json

    以指示已更改哪个路径名。

  • 您还会注意到复制文件的实际文件名未更改,这是因为我们包含了--dry-run选项。只需从脚本中省略--dry-run选项并再次运行命令,即可更改实际文件名。


  • 如果安装的renamer版本>=0.7.0

    自v0.7.0以来,发生了破坏性变化,其中包括删除--regex选项(有关详细信息,请参见此处。自此版本起,提供了一个正则表达式字面量。

    对API的此更改导致rename脚本(如先前所示)需要重新定义如下:

    "rename": "renamer -f \"/^conf.dev.json$/\" -r \"conf.json\" \"dist/config/*\"",
                            ^               ^
    

    注意: --regex 选项已被省略,正则表达式现在是文字,即现在用前向和后向斜杠包裹。此外,在此示例中,已删除 --dry-run 选项,因此请为测试目的重新启用它。


    附加说明

    • 对于 Solution ASolution B,复制和重命名逻辑已添加到单独的 npm 脚本中(分别为 copyrename),以便更清晰地解释。但是,您也可以使用 && 运算符将两个命令链接在一起,形成一个 npm 脚本 - 不过单行代码可能会很长 :)

    • 对于 Solution B,我经常使用版本 0.6.1renamer,因此我运行以下命令进行安装:npm i -D renamer@0.6.1,因为我通常需要支持较早版本的nodejs。在这种情况下,我使用 --regex 标志,就像前面提到的子部分标题为: "If the version of renamer installed is <0.7.0" 的示例一样。


    你可能还想看看shx。它基本上是shelljs,但用于npm包脚本中的命令,因此它是可移植/跨平台的。看起来你可以用一个单一的shx mv ....命令完成它。非常简洁;) - RobC
    像重命名一个文件这样的操作真的应该需要重新编译内核才行。 - Dem Pilafian
    @DemPilafian - 我不认为在本地文件系统上重命名文件是“极端”的。为什么这会“需要从头编译内核”?……我不理解你在这个问答环境中提出的观点。 - RobC
    1
    RobC,这只是一个讽刺性的评论,关于一些本应非常简单的事情,比如重命名文件,最终变得相当复杂,并需要两页的答案。 - Dem Pilafian

    3

    您必须定义回调函数:

    fs.rename('oldFile.txt', 'newFile.txt', (err) => {
      if (err) throw err;
      console.log('Rename complete!');
    });
    

    类似这样的:

    "copy": "copyfiles -u 2 /src/app/conf.dev.json dist/config/ && node -e require('fs').rename('dist/config/conf.prod.json','dist/config/conf.json' , (err) => { (err? console.log(err) : console.log('Rename complete!') ) } )"
    

    @see https://nodejs.org/api/fs.html#fs_fs_rename_oldpath_newpath_callback

    该链接是关于Node.js中fs模块的一个方法——rename()。此方法用于重命名文件或目录,具体使用说明请参考链接。

    1

    1
    @Suxio 你会如何在npm脚本中使用move-file?能否提供一个例子? - Robert Wildling

    0

    解决方案

    您可以使用一个名为move-file-cli的npm包,通过(跨平台)命令行界面来重命名文件,然后在您的npm脚本中使用"move-file"命令来重命名文件。

    安装

    npm install move-file-cli

    使用方法

    move-file <源路径> <目标路径>

    可选 - 不覆盖已存在的目标文件:--no-overwrite


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