# NPM
执行npm install命令之后,首先检查config,获取npm配置,优先级为:项目级.npmrc文件 > 用户级.npmrc文件 > 全局.npmrc文件 > npm内置的.npmrc文件。
然后检查项目中有无package-lock.json文件(简称为lock文件)。如有则检查package-lock.json文件和package.json文件中声明的版本是否一致。
一致,直接使用package-lock.json中的信息,从缓存或网络资源中加载依赖。
不一致,则根据npm版本进行处理(不同npm版本处理会有所不同,如图所示)。
如果没有package-lock.json文件,则根据package.json文件递归构建依赖树,然后按照构建好的依赖树下载完整的依赖资源,在下载时会检查是否有相关缓存。
有,则将缓存内容解压到node_modules中。没有,则先从npm远程仓库下载包资源,检查包的完整性,并将其添加到缓存,同时解压到node_modules中。最后生成package-lock.json文件。
构建依赖树时,当前依赖项目无论是直接依赖还是子依赖的依赖,我们都应该遵循扁平化原则优先将其放置在node_modules根目录下(遵循最新版本的npm规范)。在这个过程中,遇到相同模块应先判断已放置在依赖树中的模块版本是否符合对新模块版本的要求,如果符合就跳过,不符合则在当前模块的node_modules下放置该模块(遵循最新版本的npm规范)。
图中标注了更细节的内容,这里就不再赘述了。要格外注意图中标明的不同npm版本的处理情况,并学会从这种“历史问题”中总结npm使用的在最佳实践:在同一个项目团队中,应该保证npm版本一致。在前端工程中,依赖嵌套依赖,一个中型项目的node_moduels安装包可能已是海量。
如果安装包每次都通过网络下载获取,这无疑会增加安装时间成本。对于这个问题,借助缓存始终是一个好的解决思路。
# 常用npm命令
npm -v #查看 npm 的版本号
npm ls #查看当前目录安装的包的信息
npm install --help #查看 npm install 可使用的参数形式
npm install lodash@4.0.1 #安装 4.0.1 版本的 lodash
npm uninstall lodash #卸载 lodash
npm update lodash #更新 lodash
npm search lodash #搜索 lodash
npm publish lodash #发布 lodash
# package.json
快速创建 package.json 文件的命令 npm init
使用 npm init 创建的 package.json 文件中包含了 scripts 字段:
"scripts": {
"test": "echo \"Error: no test specified\" && exit 1"
},
npm 是如何管理和执行各种 scripts?作为 npm 内置的核心功能之一,npm run 实际上是 npm run-script 命令的简写。当我们运行 npm run xxx 时,步骤如下:
- 从 package.json 文件中读取 scripts 对象里面的全部配置;
- 以传给 npm run 的第一个参数作为键,本例中为 xxx,在 scripts 对象里面获取对应的值作为接下来要执行的命令,如果没找到直接报错;
- 在系统默认的 shell 中执行上述命令,系统默认 shell 通常是 bash,windows 环境下可能略有不同。
如果命令是start,可以简写npm start 不加run也可以运行
{
"name": "hello-npm-script",
"devDependencies": {
"eslint": "latest"
},
"scripts": {
"eslint": "eslint **.js"
}
}
eslint 命令是从哪里来的?其实,npm 在执行指定 script 之前会把 node_modules/.bin 加到环境变量 $PATH 的前面,这意味着任何内含可执行文件的 npm 依赖都可以在 npm script 中直接调用,换句话说,你不需要在 npm script 中加上可执行文件的完整路径,比如 ./node_modules/.bin/eslint **.js。
# npm 串行和并行
npm run lint:js && npm run lint:css && npm run lint:json && npm run lint:markdown && mocha tests/
//eslint ==> stylelint ==> jsonlint ==> markdownlint ==> mocha
"test": "npm run lint:js & npm run lint:css & npm run lint:json & npm run lint:markdown & mocha tests/"
//并行
也可以安装npm-run-all进行管理
"test": "npm-run-all lint:js lint:css lint:json lint:markdown mocha"
# package.json启动代码
项目有多个环境的情况下,在mac和win中,写法不同
"scripts": {
"dev-mac": "export NODE_ENV=development && node dev.js",
"dev-win": "set NODE_ENV=development && node dev.js"
}
这种写法是可以修改对应的环境变量的值
console.log(process.env.NODE_ENV)
如果要生成.env.xx文件进行管理的话,则可以--mode xx这样进行设置
"scripts": {
"serve": "vue-cli-service serve --mode test",
"build": "vue-cli-service build",
"test":"vue-cli-service build --mode test",
"other":"set NODE_ENV=other && vue-cli-service build --mode test"
}
# cnpm run test
# .env.test
# 在这里默认的--mode-test的NODE_ENV是test,不过可以手动更改成skt
NODE_ENV=skt
VUE_APP_BASE_API ='Other'
VUE_APP_BASE_API1='T111'
s=10000
# s数据是不会展示在vue生成的前端项目中,不过后台node中其实是可以查看到这个数据
{NODE_ENV: 'skt', VUE_APP_BASE_API: 'TEST', VUE_APP_BASE_API1: 'T1', BASE_URL: ''}
skt
TEST
当运行同时有设置和模式的other命令,得到的环境是other,即使.env.test文件修改了也无效,但test自定义的变量符合格式的还是可以成功接收到
{NODE_ENV: 'other', VUE_APP_BASE_API: 'TEST', VUE_APP_BASE_API1: 'T1', BASE_URL: ''}
other
TEST
# concurrently和nodemon
- 安装concurrently可以并行解决同时需要启动的命令,下面到dev就会同时执行"dev:build/dev:start"
- nodemona检测项目下文件的变化,如果不需要检测的,可以添加nodemonConfig中的ignore进行忽略处理
- tsc -w 表示监听并且打包ts成js
{
"name": "typescript",
"version": "1.0.0",
"description": "",
"main": "index.js",
"scripts": {
"dev:build": "tsc -w",
"dev:start": "nodemon node ./build/crowller.js",
"dev": "concurrently npm:dev:*"
},
"nodemonConfig": {
"ignore": [
"data/*"
]
},
"keywords": [],
"author": "",
"license": "ISC",
"devDependencies": {
"@types/cheerio": "^0.22.14",
"@types/superagent": "^4.1.4",
"concurrently": "^5.0.0",
"nodemon": "^2.0.1",
"ts-node": "^8.5.2",
"typescript": "^3.7.2"
},
"dependencies": {
"cheerio": "^1.0.0-rc.3",
"superagent": "^5.1.1"
}
}
# npm 快速下载避免cnpmbug
避免因为使用cnpm导致可能会出现的各种诡异问题
npm install --registry=https://registry.npm.taobao.org
# npm需要安装的插件
- @vue/cli
- cnpm (npm install -g cnpm --registry=https://registry.npm.taobao.org)
- vuepress
- nodemon
- typescript
# npx
npx(npm package executor)是一个 npm 5.2.0+ 版本的工具,用于在不全局安装 npm 包的情况下执行它们。npx 解决了全局安装 npm 包可能带来的依赖冲突问题,因为它为每个包创建了一个隔离的环境来运行它们。
npx 的主要用途包括:
- 执行项目本地的二进制文件:如果你的项目依赖于某个包,并且该包提供了可执行的二进制文件,你可以使用 npx 来运行它,而无需全局安装该包。
示例:如果你的项目依赖了 create-react-app,你可以使用 npx create-react-app my-app 来创建一个新的 React 应用,而无需全局安装 create-react-app。
- 临时使用 npm 包:如果你只想临时使用某个 npm 包,而不想将其添加到项目的依赖项中,你可以使用 npx 来直接运行它。
示例:使用 npx http-server 来临时启动一个 HTTP 服务器,而无需全局安装 http-server。
← express