代码之家  ›  专栏  ›  技术社区  ›  Matt

在package.json中使用shx删除和复制文件

  •  0
  • Matt  · 技术社区  · 5 年前

    我有两个npm项目,一个是 Gatsby 项目名称 web-project 另一个是 Express 项目名称 server-project .

    这是项目的文件结构:

    - projects
       - web-project
          - public
          - package.json
       - server-project
          - package.json
          - public
    

    如果我运行命令 npm run build 在里面 web-project/package.json ,我想为web项目生成构建文件,删除文件夹中的内容 server-project/public 并从以下位置复制内容 web-project/public 服务器项目/公共 .

    我试着用 shx ,它安装在本地 网络项目 ,但它不起作用。Gatsby生成构建文件,但shx不会复制它们。

    web项目/package.json

    "scripts": {
        "build": "gatsby build && (shx find ../server-project/public -type f -delete && shx cp -R public/* ../server-project/public)"
        ...
      },
    

    npm调试日志文件:

    0 info it worked if it ends with ok
    1 verbose cli [
    1 verbose cli   '/usr/local/Cellar/node/12.1.0/bin/node',
    1 verbose cli   '/usr/local/bin/npm',
    1 verbose cli   'run',
    1 verbose cli   'build'
    1 verbose cli ]
    2 info using npm@6.9.0
    3 info using node@v12.1.0
    4 verbose run-script [ 'prebuild', 'build', 'postbuild' ]
    5 info lifecycle tau@1.0.0~prebuild: tau@1.0.0
    6 info lifecycle tau@1.0.0~build: tau@1.0.0
    7 verbose lifecycle tau@1.0.0~build: unsafe-perm in lifecycle true
    8 verbose lifecycle tau@1.0.0~build: PATH: /usr/local/lib/node_modules/npm/node_modules/npm-lifecycle/node-gyp-bin:/Users/and/devel/tau/web-project/node_modules/.bin:/usr/local/bin:/usr/bin:/bin:/usr/sbin:/sbin
    9 verbose lifecycle tau@1.0.0~build: CWD: /Users/and/devel/tau/web-project
    10 silly lifecycle tau@1.0.0~build: Args: [
    10 silly lifecycle   '-c',
    10 silly lifecycle   'gatsby build && (shx find ../server-project/public -type ' +
    10 silly lifecycle     'f -delete && shx cp -R public/* ../server-project/public)'
    10 silly lifecycle ]
    11 silly lifecycle tau@1.0.0~build: Returned: code: 1  signal: null
    12 info lifecycle tau@1.0.0~build: Failed to exec build script
    13 verbose stack Error: tau@1.0.0 build: `gatsby build && (shx find ../server-project/public -type f -delete && shx cp -R public/* ../server-project/public)`
    13 verbose stack Exit status 1
    13 verbose stack     at EventEmitter.<anonymous> (/usr/local/lib/node_modules/npm/node_modules/npm-lifecycle/index.js:301:16)
    13 verbose stack     at EventEmitter.emit (events.js:196:13)
    13 verbose stack     at ChildProcess.<anonymous> (/usr/local/lib/node_modules/npm/node_modules/npm-lifecycle/lib/spawn.js:55:14)
    13 verbose stack     at ChildProcess.emit (events.js:196:13)
    13 verbose stack     at maybeClose (internal/child_process.js:1000:16)
    13 verbose stack     at Process.ChildProcess._handle.onexit (internal/child_process.js:267:5)
    14 verbose pkgid tau@1.0.0
    15 verbose cwd /Users/and/devel/tau/web-project
    16 verbose Darwin 18.7.0
    17 verbose argv "/usr/local/Cellar/node/12.1.0/bin/node" "/usr/local/bin/npm" "run" "build"
    18 verbose node v12.1.0
    19 verbose npm  v6.9.0
    20 error code ELIFECYCLE
    21 error errno 1
    22 error tau@1.0.0 build: `gatsby build && (shx find ../server-project/public -type f -delete && shx cp -R public/* ../server-project/public)`
    22 error Exit status 1
    23 error Failed at the tau@1.0.0 build script.
    23 error This is probably not a problem with npm. There is likely additional logging output above.
    24 verbose exit [ 1, true ]
    

    我试图将构建命令更改为仅将文件从一个文件夹复制到另一个文件夹:

    web项目/package.json

    {
      "name": "tau",
      "version": "1.0.0",
      "description": "",
      "main": "index.js",
      "scripts": {
        "develop": "gatsby develop",
        "build": "shx cp -R public/* ../server-project/public",
        "serve": "gatsby serve",
        "start": "node server.js",
        "gh-pages": "gatsby build --prefix-paths && gh-pages -d public",
        "lint": "eslint src --fix",
        "dev": "(shx --silent rm -rf public .cache || shx true) && gatsby develop",
        "server": "cross-env NODE_ENV=development DEBUG=api nodemon server.js"
      },
      "author": "PI",
      "license": "MIT",
      "dependencies": {
        "@fortawesome/fontawesome-svg-core": "^1.2.25",
        "@fortawesome/free-brands-svg-icons": "^5.12.0",
        "@fortawesome/free-solid-svg-icons": "^5.11.2",
        "@fortawesome/react-fontawesome": "^0.1.7",
        "@kunukn/react-collapse": "1",
        "@material-ui/core": "^4.9.5",
        "@popperjs/core": "^2.3.3",
        "add": "^2.0.6",
        "axios": "^0.19.0",
        "basic-auth": "^2.0.1",
        "bootstrap": "4.2.1",
        "chart.js": "^2.9.3",
        "d3-node": "^2.2.1",
        "debug": "^4.1.1",
        "font-awesome": "4.7.0",
        "framer-motion": "^1.10.3",
        "gatsby": "^2.18.12",
        "gatsby-plugin-canonical-urls": "^2.3.0",
        "gatsby-plugin-dark-mode": "^1.1.0",
        "gatsby-source-prismic-graphql": "^3.5.0",
        "gatsby-transformer-remark": "^2.6.53",
        "lodash.get": "^4.4.2",
        "lodash.groupby": "^4.6.0",
        "lodash.pickby": "^4.6.0",
        "marked": "^0.8.0",
        "moment": "^2.24.0",
        "prismic-reactjs": "^1.3.1",
        "prop-types": "^15.7.2",
        "react-chartjs-2": "^2.8.0",
        "react-collapsible": "^2.6.3",
        "react-d3-components": "^0.9.1",
        "react-d3-library": "^1.1.8",
        "react-headroom": "^3.0.0",
        "react-helmet": "^5.2.0",
        "react-lazyload": "^2.6.5",
        "react-moment": "^0.9.6",
        "react-onclickout": "^2.0.8",
        "react-popper": "^2.2.3",
        "react-popper-tooltip": "^2.11.1",
        "react-responsive": "^8.0.1",
        "react-scroll-to": "^3.0.0-beta.3",
        "react-sidebar": "^3.0.2",
        "react-slick": "^0.25.2",
        "react-svg-donuts": "^1.0.0",
        "react-telegram-embed": "^0.0.10",
        "react-toastify": "^5.4.1",
        "react-twitter-embed": "^3.0.3",
        "react-window": "^1.8.5",
        "reactstrap": "^8.4.1",
        "slick-carousel": "^1.8.1",
        "underscore": "^1.9.1",
        "yarn": "^1.21.1"
      },
      "devDependencies": {
        "@prototype-interactive/eslint-config": "^0.1.1",
        "autoprefixer": "^9.4.4",
        "dotenv": "^8.2.0",
        "eslint": "^5.12.0",
        "gatsby-plugin-google-analytics": "^2.3.0",
        "gatsby-plugin-postcss": "^2.0.2",
        "gatsby-plugin-postcss-sass": "^1.0.22",
        "gatsby-plugin-react-helmet": "^3.0.5",
        "gatsby-plugin-sass": "^2.0.7",
        "gatsby-source-filesystem": "^2.2.2",
        "gatsby-transformer-json": "^2.1.7",
        "gh-pages": "^2.0.1",
        "husky": "^1.3.1",
        "prettier": "^1.15.3",
        "pretty-quick": "^1.8.0",
        "react": "^16.7.0",
        "react-dom": "^16.7.0",
        "shx": "^0.3.2",
        "svg-sprite-loader": "^4.1.3"
      },
      "repository": {
        "type": "git",
        "url": "git+https://github.com/PI/gatsby-react-boilerplate.git"
      },
      "bugs": {
        "url": "https://github.com/PI/gatsby-react-boilerplate/issues"
      },
      "homepage": "https://github.com/PI/gatsby-react-boilerplate#readme"
    }
    

    npm调试日志文件:

    0 info it worked if it ends with ok
    1 verbose cli [
    1 verbose cli   '/usr/local/Cellar/node/12.1.0/bin/node',
    1 verbose cli   '/usr/local/bin/npm',
    1 verbose cli   'run',
    1 verbose cli   'build'
    1 verbose cli ]
    2 info using npm@6.9.0
    3 info using node@v12.1.0
    4 verbose run-script [ 'prebuild', 'build', 'postbuild' ]
    5 info lifecycle tau@1.0.0~prebuild: tau@1.0.0
    6 info lifecycle tau@1.0.0~build: tau@1.0.0
    7 verbose lifecycle tau@1.0.0~build: unsafe-perm in lifecycle true
    8 verbose lifecycle tau@1.0.0~build: PATH: /usr/local/lib/node_modules/npm/node_modules/npm-lifecycle/node-gyp-bin:/Users/and/devel/tau/web-project/node_modules/.bin:/usr/local/bin:/usr/bin:/bin:/usr/sbin:/sbin
    9 verbose lifecycle tau@1.0.0~build: CWD: /Users/and/devel/tau/web-project
    10 silly lifecycle tau@1.0.0~build: Args: [ '-c', 'shx cp -R public/* ../web-project-project/public' ]
    11 silly lifecycle tau@1.0.0~build: Returned: code: 1  signal: null
    12 info lifecycle tau@1.0.0~build: Failed to exec build script
    13 verbose stack Error: tau@1.0.0 build: `shx cp -R public/* ../web-project-project/public`
    13 verbose stack Exit status 1
    13 verbose stack     at EventEmitter.<anonymous> (/usr/local/lib/node_modules/npm/node_modules/npm-lifecycle/index.js:301:16)
    13 verbose stack     at EventEmitter.emit (events.js:196:13)
    13 verbose stack     at ChildProcess.<anonymous> (/usr/local/lib/node_modules/npm/node_modules/npm-lifecycle/lib/spawn.js:55:14)
    13 verbose stack     at ChildProcess.emit (events.js:196:13)
    13 verbose stack     at maybeClose (internal/child_process.js:1000:16)
    13 verbose stack     at Process.ChildProcess._handle.onexit (internal/child_process.js:267:5)
    14 verbose pkgid tau@1.0.0
    15 verbose cwd /Users/and/devel/tau/web-project
    16 verbose Darwin 18.7.0
    17 verbose argv "/usr/local/Cellar/node/12.1.0/bin/node" "/usr/local/bin/npm" "run" "build"
    18 verbose node v12.1.0
    19 verbose npm  v6.9.0
    20 error code ELIFECYCLE
    21 error errno 1
    22 error tau@1.0.0 build: `shx cp -R public/* ../web-project-project/public`
    22 error Exit status 1
    23 error Failed at the tau@1.0.0 build script.
    23 error This is probably not a problem with npm. There is likely additional logging output above.
    24 verbose exit [ 1, true ]
    
    0 回复  |  直到 5 年前
        1
  •  2
  •   RobC Manuel Gonzalez    5 年前

    主要问题存在于这一部分:

    shx find ../server-project/public -type f -delete
    

    这个 -type f 中不支持标志 shx (参见 issue #177 ). 据推测 -delete 该标志也不受支持。

    考虑用执行以下操作的node.js脚本替换该部分:

    1. 利用 shelljs find 方法。
    2. 使用以下命令迭代已找到的路径名数组 forEach() .
    3. 在身体的 forEach 回调检查它是否是一个文件并相应地删除。

    例如,将其全部放入一个名为的npm脚本中 build :

    "scripts": {
      ...
      "build": "gatsby build && node -e \"var sh = require('shelljs'), fs = require('fs'); sh.find('../server-project/public').forEach(function (file) { if (!fs.statSync(file).isDirectory()) { sh.rm(file); }});\" && shx cp -R \"public\" \"../server-project/public\""
      ...
    }
    

    笔记:

    1. 您尝试使用 find ../server-project/public -type f -delete 在您的OP中意味着您的意图是(仅)从中删除所有文件 ../server-project/public ( n 级别深)-但不要删除中的任何文件夹 ../服务器项目/公共 (再次 n 深层次)。这就是 node -e \"...\" 上述示例中的命令进行了复制。

    2. nodejs命令行选项 -e 用于评估内联Javascript,本质上是这样的:

      var sh = require('shelljs'),
          fs = require('fs');
      
      sh.find('../server-project/public').forEach(function (file) {
          if (!fs.statSync(file).isDirectory()) {
              sh.rm(file);
          }
      });
      
    3. 环球之星( * )在你的期末考试中 shx cp -R ... 命令和括号 (...) 省略了封装复合命令的部分。

        2
  •  1
  •   nrako    5 年前

    您可以从以下位置删除通配符 shx cp -R public/* ../server-project/public ,因为递归标志将拾取源目录中的所有内容。这应该能让你得到你想要的东西-

    shx cp -R public ../server-project/public
    
        3
  •  1
  •   Wes    5 年前

    看起来你已经在使用了 find 在您的构建系统中。我利用tar,在我维护的一些构建系统中发现了很多,这对我来说很有效。tar很好地处理了各种各样的边缘情况,因为它最初是作为备份实用程序编写的。

    在tar中,-是表示stdin或stdout的文件名,-T指定要备份的文件列表,-C指定其工作目录。这可以让你用管道把一堆东西粘在一起,完成一些非常酷的事情。例如,

    (cd /path/to/src/files && find . -type f -name) \
    | tar -T - -cf - \
    | tar -C /path/to/dest -xvf -
    
    • 子shell允许我在不影响其他命令的情况下查找目录
    • find在stdout上生成文件列表
    • 第一个tar读取stdin上要存档的文件列表
    • 第一个tar在stdout上生成存档
    • 第二个tar将目录更改为/path/to/dest
    • 然后提取stdin上的存档
    • 'v'在执行此操作时打印其提取的文件列表

    这将为您保留所有权、组成员资格、权限、符号链接、目录结构以及整个九码。即使是带有空格的文件名也不会把它弄乱。:)

    推荐文章