工程篇前传

一 前言

这是从头创建前端工程的系列文章的开篇,在构建现代的前端工程时:
(1)git 托管代码
(2)webpack 前端代码打包工具
(3)react/vue 等前端框架
(4) ESLint 前端代码风格校验工具
(5)TypeScript 前端代码结构和类型静态编译校验工具

本篇文章主要介绍下列相关概念:
(1)和git结合
(2)创建工程必备的package.json文件
(3)npm包相关知识

二 正文

1.使用git

如果你安装了git,将文件夹初始化=为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字段用于添加命令行的环境变量。

下面是一个package.json文件。

{
“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

三 后记

    原文作者:specialCoder
    原文地址: https://segmentfault.com/a/1190000014782802
    本文转自网络文章,转载此文章仅为分享知识,如有侵权,请联系博主进行删除。
点赞