前端工程之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
&devDependencies
installed。一个模块不能同时在两种环境中安装。
卸载模块
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