前端工程之npm
package.json是npm package的配置文件,存储当前项目相关的信息。如果下载npm中的包,包内会自带该文件。
具体属性
{ "name" : "underscore", //当前包(项目)的名字 "description" : "JavaScript's functional programming helper library.", "homepage" : "http://documentcloud.github.com/underscore/", "keywords" : ["util", "functional", "server", "client", "browser"], "author" : "Jeremy Ashkenas", "contributors" : [], "dependencies" : [],//生产依赖 "devDependencies”:[],//开发依赖 "repository" : {"type": "git", "url": "git://github.com/documentcloud/underscore.git"}, "scripts": { "build": "node build.js" } "main" : "underscore.js", //当前项目(包)的入口文件,该文件的导出对象作为该模块的导出对象 "version" : "1.1.6" }
main:the main entry point for the libary; when someone runs require(<library name>), require resolves this call to require(<package.json:main>).
dependencies :used to list all the dependencies of your project that are available on npm. When someone installs your project through npm, all the dependencies listed will be installed as well. Additionally, if someone runs npm install in the root directory of your project, it will install all the dependencies to ./node_modules.
devDependencies :these are dependencies not required for normal operation, but required/recommended if you want to patch or modify the project. If you built your unit tests using a testing framework, for example, it would be appropriate to put the testing framework you used in your devDependencies field. To install a project's devDependencies, simply pass the --dev option when you use npm install.
scripts:每一个属性,对应一段脚本。每当执行npm run xxx 时就会自动新建一个 Shell,在这个 Shell 里面执行指定的脚本命令。npm run新建的Shell会将当前目录的node_modules/.bin子目录append到PATH变量,执行结束后,再恢复原样。所以当前目录的node_modules/.bin子目录里面的所有脚本,都可以直接用脚本名调用,在没有全局安装时也不必加上路径。所以只要是 Shell可以运行的命令,都可以写在 npm 脚本里面。
传入参数:npm run <command> [-- <args>] ,所以在scripts中要用 -- 双中线分隔传给npm命令的参数和传给脚本的参数。node server.js --port=8888 转换成 npm run server -- --port=8888
执行多个脚本:并行执行多个命令使用&符号,顺序执行(前一个任务成功才执行下一个任务)使用&&符号。
全局安装vs本地安装:
Global packages are for anything that you need to access from the shell. By contrast local packages are for using within your apps.
npm install xxx -g :属于全局安装,将包安装在C:\Users\admin\AppData\Roaming\npm\node_modules目录下,同时在node_modules平级目录生成批处理文件,这样可以在任何地方执行xxx的CIL命令。否则需要cd到项目的cmd命令所在目录再执行/双引号包含可执行命令的全路径,很繁琐。全局安装时的包不可以通过 require() 来引入。

@IF EXIST "%~dp0\node.exe" ( "%~dp0\node.exe" "%~dp0\node_modules\gulp\bin\gulp.js" %* ) ELSE ( @SETLOCAL //变量本地化 @SET PATHEXT=%PATHEXT:;.JS;=;% //删除js后缀的默认执行文件,不直接执行gulp.js node "%~dp0\node_modules\gulp\bin\gulp.js" %* //在命令行输入gulp时,实际上调用的是这条命令:用node解释器调用批处理文件所在目录下的js文件 )
npm install xxx –save-dev :属于本地安装,将包安装在项目根目录下的node_modules目录下的.bin目录下,生成对应的cmd命令,在项目根目录下可以直接运行。可以通过 require() 来引入本地安装的模块。
@IF EXIST "%~dp0\node.exe" ( "%~dp0\node.exe" "%~dp0\..\._gulp@3.9.1@gulp\bin\gulp.js" %* //"执行其他目录下的文件" "node执行的js文件地址" %*其他任意变量 ) ELSE ( @SETLOCAL @SET PATHEXT=%PATHEXT:;.JS;=;% node "%~dp0\..\._gulp@3.9.1@gulp\bin\gulp.js" %* //%~dp0代表的是bat文件所在的文件目录,不可变;指向当前项目依赖的gulp模块的js )
如果不安装全局包,则在pro目录下是不能执行对应的命令行命令,必须cd到.bin目录下,或者通过npm link命令或通过package.json的scripts字段设置:
"scripts" : { "build" : "webpack ./entry.js bundle.js", "deploy": "export NODE_ENV=production && `npm bin`/webpack --config webpack.config.production.js && npm start", }
然后运行npm run build命令。
require()查找文件的顺序
当require一个文件模块时,先从当前执行文件平级的的node_modules目录中查找;然后查找上一级的node_modules目录;依次迭代,直到根目录下的node_modules目录。如果还没有查找到指定模块的话,就会去NODE_PATH注册的路径中查找。
require绝对路径的文件,查找时不用去遍历每一个node_modules目录,其速度最快。
为什么要全局安装和本地安装两次?
本地安装可以让每个项目依赖独立的包,不受全局包的影响,保证不同版本的包之间的相互依赖,可以通过require()使用引入的模块。是npm的默认安装模式。
全局安装并不依赖引入的模块。它会在'C:\Users\admin\AppData\Roaming\npm'生成对应的cmd文件,保证在任何地方都可以通过命令行执行该程序,不用cd到项目目录执行。如全局安装gulp是为了在任何地方都可以执行gulp任务,本地安装gulp则是为了调用gulp插件的功能。
npm 常用命令
安装模块
npm install //安装package.json中定义的所有依赖的包 npm install [<@scope>/]<name>@<version> //安装指定版本的包,如不指定版本,默认安装最新的包 alias: npm i options: -S|--save //保存版本信息到package.json文件的dep字段中 -D|--save-dev //保存版本信息到package.json文件的devDep字段中
npm install --production # 添加了production参数后将仅仅安装package.json中dependencies 里面的包,不会安装devDependencies 里的模块,否则get alldependencies&devDependenciesinstalled。一个模块不能同时在两种环境中安装。
卸载模块
npm uninstall <pkg> aliases: remove, rm, r, un, unlink options: -S|--save //删除package.json中dev字段对应的信息 -D|--save-dev //删除package.json中devDep字段对应的信息
更新模块
npm outdated [<pkg>] //列出所有过时的包 npm update [-g] [<pkg>...] //更新指定到包到最新版本;如果未指定,则更新所有包,包括全局和本地 aliases: up, upgrade options:同上
其他命令
npm config get prefix //获取全局模块安装路径; where node //获取node所在路径; npm <command> -h //查看该命令的所有使用帮助信息; npm view package@2.3.1 [version|dependencies] //查看远程包内的package.json信息 npm config ls –l //查看npm内置的配置参数 npm install 或者 npm install –save-dev //自动将所在目录的package.json中的模块安装到node-modules文件夹下,不用一个一个安装模块。 npm ls xxx [–depth=0] //查看本地安装的模块版本信息,只看当前目录,不遍历子目录。注意:子模块的devdependency依赖包不会被安装,只安装dep包。

cnpm
因为npm是从国外服务器下载,经常出现异常,可以使用淘宝团队开发的镜像cnpm,cnpm跟npm用法一样。
安装命令:npm install cnpm -g --registry=https://registry.npm.taobao.org
create-react-app安装模块慢,可以设置永久使用cnpm:
$:npm config set registry https://registry.npm.taobao.org
$:npm config set registry http://registry.npmjs.org #官方地址
使用nrm管理registry地址:
1.安装nrm:npm install -g nrm
2.注册registry地址:
nrm add npm http://registry.npmjs.org
nrm add cnpm https://registry.npm.taobao.org
3.切换registry地址
nrm use npm/cnmp
依赖包版本管理
包版本号为X.Y.Z三位,代表主版本号、次版本号和补丁版本号。当代码变更时,按以下原则更新版本号:
主版本号:有不兼容的API 修改时;
次版本号:有向下兼容的功能性新增时;
补丁版本号:做了向下兼容的bug修正时。
依赖包版本号管理(固定写死需要手动更新):
~匹配最近的小版本依赖包,比如~1.2.3会匹配所有1.2.x的包,但是不包括1.3.0。
^匹配最新的大版本依赖包,比如^1.2.3会匹配所有1.x.x的包,但是不包括2.0.0。
配置npm仅安装精确版本号的模块: npm config set save-exact true

浙公网安备 33010602011771号