开发环境-NPM
前言
在现代软件开发中,NPM(Node Package Manager)成为了一项不可或缺的工具,它提供了丰富的开发资源和依赖管理能力。本文将介绍如何搭建NPM开发环境,并探讨其在项目开发中的重要性。通过合理配置和利用NPM,开发者能够更高效地管理项目依赖、共享代码、提升开发速度,为软件开发带来了巨大的便利和效益。
安装
安装 nvm, 方便在同一台机器上管理多个不同版本的Node.js.
curl -o- https://raw.githubusercontent.com/nvm-sh/nvm/v0.38.0/install.sh | bash
export NVM_DIR="$HOME/.nvm"
[ -s "$NVM_DIR/nvm.sh" ] && \. "$NVM_DIR/nvm.sh" # This loads nvm
[ -s "$NVM_DIR/bash_completion" ] && \. "$NVM_DIR/bash_completion" # This loads nvm bash_completion
NVM镜像加速
Windows目录中 \AppData\Roaming\nvm, 打开settings.txt, 文本最后行中加入
node_mirror: https://npm.taobao.org/mirrors/node/
npm_mirror: https://npm.taobao.org/mirrors/npm/
或者在控制台修改镜像
nvm node_mirror http://npm.taobao.org/mirrors/node/
nvm npm_mirror https://npm.taobao.org/mirrors/npm/
安装Node
nvm list available #Windows中列出
nvm ls-remote #Linux中列出
nvm install [version]
指定项目Node版本
项目存在.nvmrc 的文件时,会自动检测并读取该文件中指定的Node版本,并自动切换到该版本.
创建一个.nvmrc文件, 内容写入任意版本号, 如:
v10.16.2
找不到的修复
如果在Linux上通过npm -g全局安装pm2、yarn、pnpm等命令后无法找到它们,可以尝试通过export PATH来解决。以下是解决方法:
确定安装路径
默认情况下,它们会被安装在/usr/local/bin或/usr/bin目录下。使用以下命令来查看并记下安装路径:
npm bin -g
导出路径
使用export命令将全局包的安装路径添加到系统的环境变量中。
例如,如果全局包的安装路径是/usr/local/bin,使用以下命令将其添加到PATH环境变量中
export PATH="/usr/local/bin:$PATH"
检查命令
现在,尝试在终端中运行这些命令,如pm2、yarn或pnpm, 确保能够正常运行。
NPM源管理
源管理
nrm / yrm 是快速切换npm/yarn注册服务商,如npm、cnpm、nj、taobao等,也可以切换到内部的npm源. pnpm 可比yarn,npm 更节省了大量与项目和依赖成比例的硬盘空间。
YRM
# 安装
npm install -g yrm
# yrm ls
npm ----- https://registry.npmjs.org/
cnpm ---- http://r.cnpmjs.org/
taobao -- https://registry.npm.taobao.org/
nj ------ https://registry.nodejitsu.com/
rednpm -- http://registry.mirror.cqupt.edu.cn
skimdb -- https://skimdb.npmjs.com/registry
yarn ---- https://registry.yarnpkg.com
最后,切换与测试
$ yrm use taobao
$ yrm test taobao
NPM应用
.npmrc
.npmrc (npm running cnfiguration),即npm运行时配置文件, 能配置 Registry, 代理设置, 认证信息, 依赖解析和版本控制, 缓存路径等. 它的读取顺序是:
项目配置文件 -> 用户配置文件 -> 全局配置文件
.npmrc (项目根目录) -> ~/.npmrc (用户目录) -> /etc/npmrc
目录位置查询
npm config get prefix #用户目录
npm config get prefix #全局目录
.npmrc 设置
.npmrc 文件是以 key=value 格式进行配置, 而 .yarnrc是没有 =
, 例:
registry=https://registry.npm.taobao.org
也可以用命令方式:
npm config set registry https://registry.npm.taobao.org
scope
scope相当于npm包的命名空间,如果以@开头,那它就是一个scope package。 这样分类之后就会使结构更加清晰,
@aa:registry=https://repo.huaweicloud.com/repository/npm/
NPM镜像加速
方案一
在项目目录下配置.yarnrc(或者.npmrc文件), 通常能解决项目依赖安装失败, 下面的代码选择你需要的配置哦
registry "https://registry.npm.taobao.org"
sharp_binary_host "https://npm.taobao.org/mirrors/sharp"
sharp_libvips_binary_host "https://npm.taobao.org/mirrors/sharp-libvips"
disturl "https://npm.taobao.org/dist"
sass_binary_site "https://npm.taobao.org/mirrors/node-sass/"
phantomjs_cdnurl "http://cnpmjs.org/downloads"
electron_mirror "https://npm.taobao.org/mirrors/electron/"
sqlite3_binary_host_mirror "https://foxgis.oss-cn-shanghai.aliyuncs.com/"
profiler_binary_host_mirror "https://npm.taobao.org/mirrors/node-inspector/"
chromedriver_cdnurl "https://cdn.npm.taobao.org/dist/chromedriver"
nvm_nodejs_org_mirror "http://npm.taobao.org/mirrors/node"
NODEJS_ORG_MIRROR "http://npm.taobao.org/mirrors/node"
SQLITE3_BINARY_SITE "http://npm.taobao.org/mirrors/sqlite3"
node_inspector_cdnurl "https://npm.taobao.org/mirrors/node-inspector"
selenium_cdnurl "http://npm.taobao.org/mirrors/selenium"
puppeteer_download_host "https://npm.taobao.org/mirrors"
operadriver_cdnurl "https://npm.taobao.org/mirrors/operadriver"
fse_binary_host_mirror "https://npm.taobao.org/mirrors/fsevents"
如果上传到github上,可用命令快速下载:
$ wget https://gist.githubusercontent.com/Rick2077/a115d9bbce45d7183a5a06fe16aa1cea/raw/48b51adbcd449384c200ff79bb652f41a85acb9a/.yarnrc
方案二
使用命令配置sharp的镜像地址
# npm
npm config set sharp_binary_host "https://npm.taobao.org/mirrors/sharp"
npm config set sharp_libvips_binary_host "https://npm.taobao.org/mirrors/sharp-libvips"
npm install sharp
# yarn
yarn config set sharp_binary_host "https://npm.taobao.org/mirrors/sharp"
yarn config set sharp_libvips_binary_host "https://npm.taobao.org/mirrors/sharp-libvips"
yarn add sharp
有时在Linux上遇到sharp的奇怪问题, 可以通过`yarn add --platform=linux --arch=x64 sharp` 解决.
NPM常用命令
npm config set <key> <value> [-g|--global] #给配置参数key设置值为value;
npm config get <key> #获取配置参数key的值;
npm config delete <key> #删除置参数key及其值;
npm config list [-l] #显示npm的所有配置参数的信息;
npm config edit #编辑配置文件
npm get <key> #获取配置参数key的值;
npm set <key> <value> [-g|--global] #给配置参数key设置值为value;
运行多脚本
项目开发中通常有执行单个或多个脚本情景,会是以下:
串行
用 && 把多条脚本按先后串起来. 执行时,如前其中一命令失败,后续全部命令将终止.
$ npm run build && npm run start
并行
为提高效率,用& 把多条脚本按先后串起来.
$ npm run build & npm run start
更好的两种方式
npm-run-all
使用方式只需要加上一参数, --parelle 或 -p. 更多用法,查看文档 npm-run-all.
它提供了三个命令: npm-run-all / run-s / run-p, 后两者是all带参数简写.
# 安装
$ npm i npm-run-all -D
# package.json script中添加
"scripts": {
"frotend": "echo \"Frontend service started\"",
"server": "echo \"Backend service started\"",
"all": "npm-run-all frotend server",
}
其中串行的方式还可以使用通配符,如:
"scripts": {
"test": "npm-run-all test:*",
"test:unit": "mocha",
"test:integration": "jasmine",
"test:system": "codecept"
}
运行 npm run test 将按该顺序执行 test:unit 、 test:integration 和 test:system.
concurrently
功能类似,详情查看文档 concurrently
# 安装
$ npm i concurrently -D
# package.json script中添加
"scripts": {
"frotend": "echo \"Frontend service started\"",
"server": "echo \"Backend service started\"",
"all": "concurrently \"npm run frotend\" \"npm run server\""
}
如果运行的script在子目录,可以这样:
"scripts": {
"client": "cd client && npm start",
"server": "cd server && npm start",
"assets": "cd assets && ionic serve",
"start": "concurrently \"npm run client\" \"npm run server\" \"npm run assets\" ",
},
...
"devDependencies": {
"concurrently": "^1.0.0"
}
npm script 传参
为简化配置,可通过传参减少配置条目,提高灵活度。 如代码检测:
"lint": "eslint js/*.js",
"lint:fix": "eslint js/*.js --fix"
通过传参后,只需保留一条命令, 然后执行npm run lint -- fix
"lint": "eslint js/*.js",
script 日志控制
如果不加日志参数得到的输出 ,能显示执行的命令与结果.
更少的
如需显示更少,只需在运行时传 --loglevel silent 或者 --silent 或更简单的 -s.
$ npm run all -s
更多的
只需在运行script
的时传--loglevel verbose
或者 --verbose
或者更简单的 -d
$ npm run all -d
script 钩子
钩子的设计目的是增加生命周期的机制,通常是 pre 与 post钩子脚本. 这特性可帮助某些操作前后的检查或清理. 例:
"lint": "eslint js/*.js",
"prelint": "eslint js/*.js --fix",
"postlint": "echo \"eslint执行完毕\""
只执行 npm run lint, 它将执行三条命令: npm run prelint, npm run lint, npm run postlint.
script 变量
npm script 中可使用预定义变量与自定义变量.
预定义变量
通过解析整个package.json 获取各字段与值. 运行 npm run env 能拿到完整的列表, 但太长.
可使用 npm run env | grep npm_package | sort
拿到部分排序后的预定义变量.
npm_package_json=/home/jojo/devs/react-app/package.json
npm_package_name=react-app
npm_package_version=0.1.0
使用方法遵循 shell
语法,在 npm script
给要引用的变量前面加上 $
符号即可.
"scripts": {
"getName": "echo $npm_package_name"
},
运行getName, 结果如下:
jojo@JoJo_PC:~/devs/react-app$ npm run getName -s
react-app
自定义变量
在config字段时可添加自定义变量.
"config": {
"say": "hello jojo"
},
运行结果如下:
jojo@JoJo_PC:~/devs/react-app$ npm run sayName
> react-app@0.1.0 sayName
> echo $npm_package_config_say
hello jojo
linux / mac下使用 $npm_package_name, windows下用 %npm_package_name%
跨平台
由于Linux / Mac / Windows 引用变量方式不同, 这时就需要处理兼容问题.
暴力的方式为各写一份:
{
"name": "test",
"scripts": {
"bash-script": "echo Hello $npm_package_name",
"win-script": "echo Hello %npm_package_name%"
}
}
以下有更好的方式:
Cross-var
#安装
$ npm i cross-var -D
#命令添加
"var3": "cross-var echo %npm_package_config_say%",
"var4": "cross-var echo $npm_package_config_say"
Cross-env
$ npm i cross-env -D
设置环境变量的时候,加上cross-env 即可.
"envDev": "cross-env NODE_ENV=development"
命令列表
对于快速了解项目, 有简单快捷方式罗列 scripts 对象中的所有命令, 即 npm run:
jojo@JoJo_PC:~/devs/react-app$ npm run
Lifecycle scripts included in react-app@0.1.0:
start
react-scripts start
test
react-scripts test
available via `npm run-script`:
build
react-scripts build
eject
react-scripts eject
getName
echo $npm_package_name
sayName
echo $npm_package_config_say
npm run xxx机制
执行 npm run xxx
命令时,会在项目的 package.json
文件中的 scripts
部分查找对应的 xxx
命令并执行。例如,运行 npm run serve
实际上是执行 vue-cli-service serve
命令。
使用 npm run xxx 而不是直接执行命令的原因是,直接执行 vue-cli-service serve 会报错,因为操作系统中没有对应的指令。
npm run xxx 的执行方式是先在项目的 node_modules/.bin 目录中查找命令,如果找到则执行,否则在全局的 node_modules/.bin 目录中查找。如果仍未找到,会检查系统的 PATH 环境变量中是否有其他同名的可执行程序。当安装依赖时,npm 会在 node_modules/.bin/ 目录中创建对应的可执行文件。
因此,执行 npm run serve 实际上是在 ./node_modules/.bin 目录中找到 vue-cli-service 文件并执行,相当于执行了 ./node_modules/.bin/vue-cli-service serve。
全局安装依赖时(使用 npm i -g xxx),会在全局的 node_modules/.bin 目录中创建可执行程序,从而可以在任何目录下运行相应的命令。
其他
Exit
exit 用来执行后退出的指令,相当于process.exit(1)
"scripts": {
"test": "echo \"Error: no test specified\" && exit 1"
},
Wait
并行执行多条命令, 在命名最后跟上 wait 可阻塞当前进程, 直到所有并行命令执行完毕才会结束进程
"scripts": {
"print": "node ./src/script_3.js & node ./src/script_2.js & node ./src/script_1.js & wait"
}
规范校验
使用以下工具可实现git提交前的 eslint 校验, 与及commit 信息的规范校验:
husky
现代化的本地Git钩子使操作更加轻松
pre-commit
自动在您的git储存库中安装git pre-commit脚本,该脚本在pre-commit上运行您的npm test