Angular和NPM依赖项与devDependencies的区别

12

在研究了这个问题并跟随这篇非常有用的文章之后:npm package.json文件中dependencies、devDependencies和peerDependencies之间的区别是什么?

我知道dependencies应该引用每个运行时库,而devDependencies应该引用每个有助于开发的依赖项。

但是现在我感到困惑了。对于生产环境使用,我将不得不ng build --production我的Angular应用程序。如果我执行npm install --production,我甚至无法编译ng build --production。我需要执行npm install并安装所有的devDependencies。基于此,我尝试将所有内容都放在devDependencies下,然后进行了ng build --prod,生成的[dist]文件夹包含了所需的一切,可以作为完整的Angular应用程序提供服务。

所以第一个问题是:除了在纸面上区分运行时库和开发库之外,为什么我要使用dependencies?

其他问题:为了避免依赖项漏洞,我可以通过在package.json中放置此库来强制使用特定版本(只要主要版本相同)。但我想避免将此库放在dependencies或devDependencies下,我应该将此库放在peerDependencies还是optionalDependencies或bundledDependencies下?

感谢任何关于此问题的输入。

编辑

需要示例package.json:

{
  "name": "ANGULAR_PROJECT",
  "version": "X.Y.Z",
  "repository": {
    "type": "git",
    "url": "A_GIT_URL"
  },
  "scripts": {
    "ng": "ng",
    "test": "ng test",
    "e2e": "protractor e2e/conf/protractor.conf.js",
    "e2e:dev": "protractor e2e/conf/protractor-dev.conf.js",
  },
  "private": true,
  "dependencies": {
  },
  "devDependencies": {
    "@angular/pwa": "^0.12.4",
    "@angular/animations": "^8.2.11",
    "@angular/cdk": "^8.2.3",
    "@angular/common": "^8.2.11",
    "@angular/compiler": "^8.2.11",
    "@angular/core": "^8.2.11",
    "@angular/forms": "^8.2.11",
    "@angular/material": "^8.2.3",
    "@angular/material-moment-adapter": "^8.2.3",
    "@angular/platform-browser": "^8.2.11",
    "@angular/platform-browser-dynamic": "^8.2.11",
    "@angular/platform-server": "^8.2.11",
    "@angular/router": "^8.2.11",
    "@angular/service-worker": "^8.2.11",
    "@mat-datetimepicker/core": "^2.0.1",
    "@mat-datetimepicker/moment": "^2.0.1",
    "@ngrx/effects": "8.4.0",
    "@ngrx/router-store": "8.4.0",
    "@ngrx/schematics": "8.4.0",
    "@ngrx/store": "8.4.0",
    "@ngrx/store-devtools": "8.4.0",
    "@swimlane/ngx-charts": "12.0.1",
    "angular-gridster2": "^8.2.0",
    "angular-particle": "^1.0.4",
    "array-flat-polyfill": "^1.0.1",
    "apollo-angular": "^1.8.0",
    "apollo-angular-link-http": "^1.9.0",
    "apollo-cache-inmemory": "^1.6.3",
    "apollo-client": "^2.6.4",
    "apollo-link": "^1.2.13",
    "classlist.js": "^1.1.20150312",
    "core-js": "^2.5.4",
    "graphql": "14.0.0",
    "graphql-tag": "^2.10.1",
    "hammerjs": "^2.0.8",
    "json-server": "^0.14.2",
    "jsonpath": "^1.0.2",
    "moment": "^2.22.2",
    "ngrx-store-freeze": "^0.2.4",
    "ngrx-store-localstorage": "^8.0.0",
    "ngx-cacheable": "^1.2.5",
    "ngx-parallax": "^4.0.0",
    "node-sass": "4.13.1",
    "rxjs": "^6.5.3",
    "web-animations-js": "^2.3.2-pr208",
    "xlsx": "^0.14.2",
    "zone.js": "~0.9.1",
    ----------------------------------------------- REAL DEV DEPENDENCIES UNDER
    "@angular-devkit/build-angular": "^0.803.10",
    "@angular/cli": "^8.3.10",
    "@angular/compiler-cli": "^8.2.11",
    "@angular/language-service": "^8.2.11",
    "@commitlint/cli": "^7.2.1",
    "@types/chai": "^4.2.6",
    "@types/cucumber": "^6.0.0",
    "@types/jasmine": "~3.4.6",
    "@types/jasminewd2": "~2.0.8",
    "@types/node": "~8.9.4",
    "chai": "^4.2.0",
    "codelyzer": "~5.2.0",
    "commitizen": "^4.0.3",
    "conventional-changelog-cli": "^2.0.1",
    "cucumber": "5.1.0",
    "cucumber-html-reporter": "^5.0.2",
    "cz-customizable": "^5.3.0",
    "cz-customizable-ghooks": "^1.5.0",
    "husky": "^4.2.1",
    "jasmine-core": "~3.5.0",
    "jasmine-spec-reporter": "~4.2.1",
    "karma": "~4.4.1",
    "karma-chrome-launcher": "~3.1.0",
    "karma-coverage-istanbul-reporter": "~2.1.0",
    "karma-jasmine": "~2.0.1",
    "karma-jasmine-html-reporter": "^1.4.2",
    "karma-sonarqube-reporter": "^1.2.5",
    "karma-sonarqube-unit-reporter": "^0.0.21",
    "karma-spec-reporter": "0.0.32",
    "lint-staged": "^8.1.0",
    "mkdirp": "^0.5.1",
    "ng-mocks": "^8.1.0",
    "prettier": "^1.15.3",
    "protractor": "5.4.2",
    "protractor-cucumber-framework": "^6.2.0",
    "rxjs-compat": "^6.3.3",
    "ts-comparators": "^1.0.0",
    "ts-mockery": "1.2.0",
    "ts-node": "~7.0.1",
    "tslint": "~5.11.0",
    "tslint-config-prettier": "^1.18.0",
    "tslint-plugin-prettier": "^2.0.1",
    "typescript": "^3.1.6"
  },
  "peerDependencies": {

  }
}


如果没有看到你的package.json文件,我们无法评估你的问题。看起来你在devDependencies下错误地分配了依赖项。 - mamichels
我在这里谈论原则,但我可以举一个例子package.json,在生产环境下将正确构建,其中所有内容都在devDependencies下。 - Deunz
1
在使用 ng build --prod 进行构建过程时,您会在“开发过程”中编译项目及其所有所需的包。然后,您将编译静态文件,无需再进行打包。但是,我认为这对于服务器端渲染可能不起作用。我也在等待社区的答案。 - jafar_mnkd
1
我可以回答:这是有效的:我实际上有一个express node.js应用程序在项目中提供此[dist],因为[dist]文件夹已经编译了所有需要的内容。我只将express和node.js库放在依赖项下以减少我的node_modules大小。这是一个真正的生产案例使用。我知道这不是理想的,我们将删除express/node来实际使用真正的Web服务器。但是,再次强调我正在谈论原则:D - Deunz
这显然不是一个鼓舞人心的问题 :( - Deunz
1个回答

3
除了在运行时库和开发库之间进行“纸上”区别之外,为什么我要使用依赖项?
回答:无论你想做什么都没有关系。但要知道:
- 即使这只是一个“纸上”的区别,了解依赖项是生产环境还是开发环境的很重要,所以尽量准确。 - 要确定一个依赖项是否真正被用于最终构建中,可以使用特殊的库来实现。我更喜欢https://www.npmjs.com/package/webpack-bundle-analyzer,因为它可以通过搜索字段来查找依赖项。 - 如果你需要使用一些带有--prod参数的npm命令,它们将只使用package.json中的“dependencies”堆栈。如果这个依赖项在“devDependencies”中,npm ls @angular-devkit/build-angular --json --prod将不会返回任何结果。但如果@angular-devkit/build-angular在“dependencies”中,它将返回一个结果。
而对于另一个问题: 为了避免依赖关系的漏洞,我可以通过将此库放在package.json中来强制使用特定版本(只要主要版本相同)。但是我不想将此库放在dependencies或devDependencies中,我应该将此库放在peerDependencies?optionalDependencies?bundledDependencies?
回答:最好的方法是使用npm工具:npm-force-resolutions,并且不要在这些条目中引用这些依赖项。
有关npm-force-resolutions的更多信息,请参考此处的示例:https://dev59.com/XGUo5IYBdhLWcg3wvBiX#62956076

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