一 前言
这是从头创建前端工程的系列文章的开篇,在构建现代的前端工程时:
(1)git 托管代码
(2)webpack 前端代码打包工具
(3)react/vue 等前端框架
(4) ESLint 前端代码风格校验工具
(5)TypeScript 前端代码结构和类型静态编译校验工具
本篇文章主要介绍下列相关概念:
(1)和git结合
(2)创建工程必备的package.json文件
(3)npm包相关知识
二 正文
1.使用git
git init
文件夹内会自动生成.git文件夹,里面存放着git跟踪文件。这样你就可以对工程代码进行git相关操作了,比如推送到远程仓库。
2.package.json文件
每个项目的根目录下面,一般都有一个package.json文件,定义了这个项目所需要的各种模块,以及项目的配置信息(比如名称、版本、许可证等元数据)。npm install命令根据这个配置文件,自动下载所需的模块,也就是配置项目所需的运行和开发环境。这里主要介绍初始化工程常用到的.
初始化工程:
npm init
然后会让你填写一些信息:
init提示信息: 知识点: package name -> name version -> versin description -> description entry point -> main test command -> scripts git repository -> repository keywords -> keywords author -> author license -> license
2-1 name
name就是项目名称
2-2 version
version是版本(遵守“大版本.次要版本.小版本”的格式),后面会有详细的介绍。
{ "name" : "xxx","version" : "0.0.0",}
2-3 description
对这个项目的描述
2-4 keywords
关键词
2-5 repository
仓库,例如git:
"repository": { "type": "git","url": "git@github.com:git/webpack_test.git" }
2-6 author
工程所有者
2-7 license
开源协议
2-8 scripts
scripts指定了运行脚本命令的npm命令行缩写,比如start指定了运行npm run start时,所要执行的命令。
下面的设置指定了npm (run) start,npm (run) test时,所要执行的命令。
"scripts": { "start": "npm run dev.js","test": "node test.js" }
2-9 dependencies、devDependencies
1)执行:
npm install module --save
会将模块名和版本号放在dependencies下面;
2)执行:
npm install module --save -dev
会将模块名和版本号放在devDependencies下面.
dependencies字段指定了项目运行所依赖的模块,devDependencies指定项目开发所需要的模块。
它们都指向一个对象。该对象的各个成员,分别由模块名和对应的版本要求组成,表示依赖的模块及其版本范围。
{ "devDependencies": { "browserify": "~13.0.0","karma-browserify": "~5.0.1" } } // 版本号规范后面会有讲解
有了package.json文件,直接使用npm install命令,就会在当前目录中安装所需要的模块。
npm install
2-10 peerDependencies
有时,你的项目和所依赖的模块,都会同时依赖另一个模块,但是所依赖的版本不一样。比如,你的项目依赖A模块和B模块的1.0版,而A模块本身又依赖B模块的2.0版。
大多数情况下,这不构成问题,B模块的两个版本可以并存,同时运行。但是,有一种情况,会出现问题,就是这种依赖关系将暴露给用户。
最典型的场景就是插件,比如A模块是B模块的插件。用户安装的B模块是1.0版本,但是A插件只能和2.0版本的B模块一起使用。这时,用户要是将1.0版本的B的实例传给A,就会出现问题。因此,需要一种机制,在模板安装的时候提醒用户,如果A和B一起安装,那么B必须是2.0模块。
peerDependencies字段,就是用来供插件指定其所需要的主工具的版本。
{ "name": "chai-as-promised","peerDependencies": { "chai": "1.x" } }
上面代码指定,安装chai-as-promised模块时,主程序chai必须一起安装,而且chai的版本必须是1.x。如果你的项目指定的依赖是chai的2.0版本,就会报错。
注意,从npm 3.0版开始,peerDependencies不再会默认安装了。
2-11 bin
bin项用来指定各个内部命令对应的可执行文件的位置。
"bin": { "sometool": "./bin/sometool.js" }
上面代码指定,sometool 命令对应的可执行文件为 bin 子目录下的 sometool.js。Npm会寻找这个文件,在node_modules/.bin/目录下建立符号链接。在上面的例子中,sometool.js会建立符号链接npm_modules/.bin/sometool。由于node_modules/.bin/目录会在运行时加入系统的PATH变量,因此在运行npm时,就可以不带路径,直接通过命令来调用这些脚本。
因此,像下面这样的写法可以采用简写。
scripts: { start: './node_modules/sometool/sometool.js build' } // 简写为 scripts: { start: 'sometool build' }
所有node_modules/.bin/目录下的命令,都可以用npm run [命令]的格式运行。在命令行下,键入npm run,然后按tab键,就会显示所有可以使用的命令。
2-12 main
main字段指定了加载的入口文件,require('moduleName')就会加载这个文件。这个字段的默认值是模块根目录下面的index.js。
2-13 config
config字段用于添加命令行的环境变量。
{
"name" : "foo",
"config" : { "port" : "8080" },
"scripts" : { "start" : "node server.js" }
}
然后,在server.js脚本就可以引用config字段的值。
http .createServer(...) .listen(process.env.npm_package_config_port)
用户执行npm run start命令时,这个脚本就可以得到值。
$ npm run start
用户可以改变这个值。
$ npm config set foo:port 80
2-14 browser
browser指定该模板供浏览器使用的版本。browserify这样的浏览器打包工具,通过它就知道该打包那个文件。
"browser": { "tipso": "./node_modules/tipso/src/tipso.js" },
2-15 engines
engines字段指明了该模块运行的平台,比如 Node 的某个版本或者浏览器。
{ "engines" : { "node" : ">=0.10.3 <0.12" } }
该字段也可以指定适用的npm版本。
{ "engines" : { "npm" : "~1.0.20" } }
3.package-lock.json文件
参考链接:https://mp.weixin.qq.com/s/Na...
根据官方文档,这个package-lock.json 是在 npm install
时候生成一份文件,用以记录当前状态下实际安装的各个npm package的具体来源和版本号。
它有什么用呢?因为npm是一个用于管理package之间依赖关系的管理器,它允许开发者在pacakge.json中间标出自己项目对npm各库包的依赖。你可以选择以如下方式来标明自己所需要库包的版本
这里举个例子:
"dependencies": { "@types/node": "^8.0.33",},
这里面的 向上标号^是定义了向后(新)兼容依赖,指如果 types/node的版本是超过8.0.33,并在大版本号(8)上相同,就允许下载最新版本的 types/node库包,例如实际上可能运行npm install时候下载的具体版本是8.0.35。波浪号
大多数情况这种向新兼容依赖下载最新库包的时候都没有问题,可是因为npm是开源世界,各库包的版本语义可能并不相同,有的库包开发者并不遵守严格这一原则:相同大版本号的同一个库包,其接口符合兼容要求。这时候用户就很头疼了:在完全相同的一个nodejs的代码库,在不同时间或者不同npm下载源之下,下到的各依赖库包版本可能有所不同,因此其依赖库包行为特征也不同有时候甚至完全不兼容。
因此npm最新的版本就开始提供自动生成package-lock.json功能,为的是让开发者知道只要你保存了源文件,到一个新的机器上、或者新的下载源,只要按照这个package-lock.json所标示的具体版本下载依赖库包,就能确保所有库包与你上次安装的完全一样。
package.json文件只能锁定大版本,也就是版本号的第一位,并不能锁定后面的小版本,你每次npm install都是拉取的该大版本下的最新的版本,为了稳定性考虑我们几乎是不敢随意升级依赖包的,这将导致多出来很多工作量,测试/适配等,所以package-lock.json文件出来了,当你每次安装一个依赖的时候就锁定在你安装的这个版本。
在以前可能就是直接改package.json里面的版本,然后再npm install了,但是5版本后就不支持这样做了,因为版本已经锁定在package-lock.json里了,所以我们只能npm install xxx@x.x.x 这样去更新我们的依赖,然后package-lock.json也能随之更新。
通俗地讲就是:帮你锁住小版本,使之可以在任何环境下都能加载本地你install的当前版本。
4.npm 版本知识
指定版本:比如1.2.2,遵循“大版本.次要版本.小版本”的格式规定,安装时只安装指定版本。
(1)波浪号(tilde)+指定版本:比如~1.2.2,表示安装1.2.x的最新版本(不低于1.2.2),但是不安装1.3.x,也就是说安装时不改变大版本号和次要版本号。 (2)插入号(caret)+指定版本:比如ˆ1.2.2,表示安装1.x.x的最新版本(不低于1.2.2),但是不安装2.x.x,也就是说安装时不改变大版本号。需要注意的是,如果大版本号为0,则插入号的行为与波浪号相同,这是因为此时处于开发阶段,即使是次要版本号变动,也可能带来程序的不兼容。 (3)latest:安装最新版本。
大版本.次要版本.小版本”的格式规定还有一种通俗的解释:
大版本是指大的升级,很肯可能不兼容之前的版本 次要版本是针对当前版本的扩展 小版本是指修复当前版本bug