节点:如何避免安装全局软件包

时间:2019-03-11 07:59:33

标签: node.js npm jestjs npm-scripts npx

我正在寻找一种模式来避免在使用节点时需要全局软件包,我想使用npm install安装所需的一切,然后仅使用npm run xxx运行每个命令,没有安装任何全局软件包。

例如,我配置了玩笑来运行测试。

这些是我package.json中的依赖项:

[...]
},
"author": "",
"license": "ISC",
"dependencies": {
  "@types/express": "^4.16.1",
  "@types/node": "^11.10.5",
  "express": "^4.16.4",
  "ts-node-dev": "^1.0.0-pre.32",
  "typescript": "^3.3.3333"
},
"devDependencies": {
  "@types/jest": "^24.0.9",
  "@types/supertest": "^2.0.7",
  "jest": "^24.3.1",
  "nodemon": "^1.18.10",
  "supertest": "^4.0.0",
  "ts-jest": "^24.0.0"
}
[...]

这些是我配置的一些脚本:

[...]
"scripts": {
  "test": "jest --coverage",
  "tsc": "tsc",
  "watch": "nodemon --watch 'src/**/*.ts' --exec 'ts-node' src/server.ts"
},
[...]

但是当我发出npm run test时,出现此错误:

$ npm run test
> ci-test@0.0.1 test /home/sas/devel/apps/vue/ci-test
> jest --coverage
sh: 1: jest: not found
npm ERR! file sh
[...]

如果我用npm install -g jest全局安装了jest,一切运行正常,但这正是我要避免的事情。

我做出的一些假设可能是错误的:

  • 在运行脚本时,节点首先在node_modules / .bin中查找命令(以使用本地安装的软件包)

  • 当我发出npm install时,每个命令行命令都安装到node_modules / .bin

这最后一个不起作用,因为即使我的devDependencies中有笑话,但我的项目中也没有node_modules / .bin / jest文件

$ ls node_modules/.bin/
acorn  cdl        esgenerate  esvalidate            is-ci  json5    loose-envify  mime    nodetouch  parser  semver      sshpk-sign    strip-indent  watch
atob   escodegen  esparse     import-local-fixture  jsesc  js-yaml  marked        mkdirp  nopt       rc      sshpk-conv  sshpk-verify  uglifyjs

另一方面,作为一种解决方法,以下方法似乎可行:

"scripts": {
  "test": "npx jest --coverage",

但是每次我运行npm run test

时,npx安装笑话都需要10秒钟以上

那么,实现它的正确方法是什么? O如何告诉npm将jest安装到node_modules / .bin并在我的脚本中引用它时使用它?

1 个答案:

答案 0 :(得分:2)

似乎比预期的要容易,我只需要发布:

it('Read a note for a user', (done) => {
  request(graphqlURL)
    .post('/graphql')
    .set(baseHeaders())
    .send({
      query: graphQLQuery
    })
    .end((err, res) => {
      try {
        expect(res.status).toBe(200);
      } catch (err) {
        // --- add additional data to the error message here ---
        err.message = `${err.message}\n\nfailing query: ${graphQLQuery}`;
        throw err;  // throw the error so test fails as expected
      }
      done();
    })
});

默认情况下,npm似乎不会安装开发依赖项


我还进行了一些测试,使用了NODE_ENV var,并且取消设置import Link from 'next/link' ... const pluckRoute = (Router: any) => Router ? Router.pathname : '/'; ... const currentRoute = pluckRoute(Router.router); const NavPortfolio = currentRoute === '/' ? NavActive : NavLink; const NavAbout = currentRoute === '/about' ? NavActive : NavLink; ... <li> <Link href={`/`}> <NavPortfolio>Portfolio</NavPortfolio> </Link> </li> <li> <Link href={`/about`}> <NavAbout>About</NavAbout> </Link> </li> 后似乎还安装了devDependencies以及node_modules / .bin / jest中的jest。似乎以某种方式假设我处于生产模式。


我学会了避免安装全局依赖项的另一个技巧是使用--save-dev安装它,然后添加脚本以使用npm install --only=dev 运行它。例如,为了避免在全球范围内安装玩笑,但仍然可以从命令行使用它,您应该:

npm install

然后将以下内容添加到package.json

npm run

然后您可以使用npm install jest --save-dev 从命令行运行它。要从命令行传递参数,您必须在参数之前添加“-”,例如:scripts: { "jest": "jest" } 。或者,您也可以发出npm run jest,如果已安装,则npx将使用来自node_modules / .bin的笑话。 (请查看this了解更多信息)

顺便说一句,这个answer(类似问题)可能有用