node&npm相关生态
nvm
node版本管理工具,有了nvm可以方便的在同一台设备上进行多个node版本之间的切换。
nrm
node安装源管理工具,可以帮助我们快速配置切换安装源。
包管理工具
npm
node package manager,即node包管理器。
它运行在node环境中,让开发者可以用简单的方式完成包的查找、安装、更新、卸载、上传等。其运行在node环境中根本原因是:浏览器环境无法提供下载、删除、读取本地文件的功能,而node属于服务器环境,没有浏览器的各种限制,理论上可以完全掌控运行node的计算机。
npm是包管理器的基石,可以认为前端所有的包管理器都是基于npm的。
yarn
-
yarn由Facebook、Google、Exponent、Tilde公司联合推出的新的JS包管理工具,为了弥补早起npm的一些缺陷而生;
-
yarn使用方法与npm相似,对比如下:
pnpm
官网:pnpm速度快,节省磁盘空间的软件包管理工具
pnpm的优势
快速:比其他包管理器快两倍;
高效:node_modules中的文件链接自特定内容寻址存储库;
支持monorepos:pnpm内置支持单仓多包;
严格:pnpm默认创建了一个非平铺的node_modules,因此代码无法访问任意包
pnpm做了什么?
所有文件存放在一个统一的位置:
- 当安装软件包时,其包含的所有文件都会硬链接到此位置,而不会占用额外的硬盘空间;这样可以在项目之间方便的共享相同版本的依赖包;
- 如果对同一依赖包使用了相同的版本,则硬盘上只有此依赖包的一份文件;如归使用了不同版本的依赖包,则只有版本之间不同的文件会被存储起来;
- pnpm创建的非扁平的node_modules防止了项目可以访问不属于当前项目所设定的依赖包(npm\yarn都可访问)
cnpm
淘宝npm镜像源,为了解决国内用户连接npm registry缓慢的问题,淘宝搭建的自己的registry
细剖npm配置文件—package.json
通过npm init(创建时挨着填写需要的信息)或者npm init -y(所有信息使用默认的)可以创建出package.json;
此配置文件主要包含:
- 项目的名称、版本号、项目描述等;
- 项目所依赖的其他库的信息和依赖库的版本号;
package.json详解
{
//项目名,必填
"name": "",
//项目版本号,必填
"version": "0.1.0",
//项目是否私有,如果是私有则npm不能发布
"private": true,
//scripts用于配置一些脚本命令,npm serve等价于npm serve,可以把run省略
"scripts": {
"serve": "vue-cli-service serve",
"build": "vue-cli-service build",
"lint": "vue-cli-service lint"
},
//dependencies中包含的是无论开发环境还是生产环境都需要依赖的包;
//执行npm install会根据dependencies自动安装需要的依赖包
"dependencies": {
"@fullcalendar/core": "^5.10.1",
"@fullcalendar/daygrid": "^5.10.1",
"@fullcalendar/vue": "^5.10.1",
"clipboard": "^2.0.8",
"core-js": "^3.6.5",
"default-passive-events": "^2.0.0",
"element-china-area-data": "^5.0.2",
"element-ui": "^2.15.6",
"js-base64": "^3.7.2",
"jsencrypt": "^3.2.1",
"qrcodejs2": "0.0.2",
"qs": "^6.10.2",
"sortable.js": "^0.3.0",
"sortablejs": "^1.14.0",
"uuid": "^8.3.2",
"vue": "^2.6.11",
"vue-router": "^3.5.3"
},
//devDependencies包含开发环境需要的依赖的包
//peerDependencies里面包含的是依赖包所依赖的另外的包(如element-plus这个包是依赖于vue3的)
//bundledDependencies\bundleDependencies打包依赖,最终发布包的时候需要用到的依赖,需要是在dependencies或devDependencies中声明过的
//optionalDependencies相比较dependencies和devDependencies有更高的优先级,在这个里面的依赖项即使安装失败也不会影响整个安装的过程
"devDependencies": {
"@vue/cli-plugin-babel": "~4.5.0",
"@vue/cli-plugin-eslint": "~4.5.0",
"@vue/cli-service": "~4.5.0",
"axios": "^0.24.0",
"babel-eslint": "^10.1.0",
"eslint": "^6.7.2",
"eslint-plugin-vue": "^6.2.2",
"js-cookie": "^3.0.1",
"nprogress": "^0.2.0",
"sass": "^1.43.4",
"sass-loader": "^7.1.0",
"script-ext-html-webpack-plugin": "^2.1.5",
"vue-template-compiler": "^2.6.11",
"vue-wxlogin": "^1.0.4",
"vuex": "^3.6.2"
},
"eslintConfig": {
"root": true,
"env": {
"node": true
},
"extends": [
"plugin:vue/essential",
"eslint:recommended"
],
"parserOptions": {
"parser": "babel-eslint"
},
"rules": {}
},
"browserslist": [
"> 1%",
"last 2 versions",
"not dead"
]
}
browserslist
browserlist的功能是在前端工具之间共享目标环境的浏览信息,根据提供的目标浏览器环境来职能添加css前缀、js的polyfill垫片来兼容旧版本浏览器,避免不必要的兼容代码以提高编译质量;
在前端项目中,我们会用到babel转换es6语法、eslint来保证代码质量和规范、AutoPrefixer和PosetCss来处理cssNext语法。所以在前端项目中一般会用到一下工具:
- AutoPrifixer
- Babel
- postcss-preset-env
- postcss-normalize
- eslist的eslint-plugin-compat
- styleLint的stylelint-no-unsupported-browser-features
这些工具会根据配置的目标浏览器环境来决定使用哪些策略处理你的源代码。
| 例子 | 说明 |
|---|---|
| > 1% | 全球超过1%人使用的浏览器 |
| > 5% in US | 指定国家使用率覆盖 |
| last 2 versions | 所有浏览器兼容到最后两个版本根据CanIUse.com追踪的版本 |
| Firefox ESR | 火狐最新版本 |
| Firefox > 20 | 指定浏览器的版本范围 |
| not ie <=8 | 方向排除部分版本 |
| Firefox 12.1 | 指定浏览器的兼容到指定版本 |
| unreleased versions | 所有浏览器的beta测试版本 |
| unreleased Chrome versions | 指定浏览器的测试版本 |
| since 2013 | 2013年之后发布的所有版本 |
注:
- 通畅使用npm全局安装的包都是一些工具包,如yarn、webpack等;
- axios、express、koa等库文件一般在dev依赖里面
npm install默认是在dependencies中;npm insall -dev`npm i -D`是在devDependencies中
npm下载原理
package-lock.json详解
从npm5.x开始,执行
npm install时会自动生成一个package-lock.json文件。
npm为了让开发者在安全的前提下使用最新的依赖包,在package.json中通常做了锁定大版本的操作,这样在每次npm install的时候都会拉取依赖包大版本下的最新的版本。这种机制最大的一个缺点就是当有依赖包有小版本更新时,可能会出现协同开发者的依赖包不一致的问题。
{
//项目名称
"name": "webpack",
//项目版本
"version": "1.0.0",
//lock文件的版本
"lockfileVersion": 2,
//使用requires跟踪模块的依赖关系
"requires": true,
"packages": {
"": {
"name": "webpack",
"version": "1.0.0",
"license": "ISC",
"dependencies": {
"axios": "^1.1.2"
}
},
"node_modules/axios": {
"version": "1.1.2",
"resolved": "https://registry.npmmirror.com/axios/-/axios-1.1.2.tgz",
"integrity": "sha512-bznQyETwElsXl2RK7HLLwb5GPpOLlycxHCtrpDR/4RqqBzjARaOTo3jz4IgtntWUYee7Ne4S8UHd92VCuzPaWA==",
//依赖包node_modules中依赖的包,与顶层的dependencies一样的结构
"dependencies": {
"follow-redirects": "^1.15.0",
"form-data": "^4.0.0",
"proxy-from-env": "^1.1.0"
}
},
"node_modules/combined-stream": {
"version": "1.0.8",
"resolved": "https://registry.npmmirror.com/combined-stream/-/combined-stream-1.0.8.tgz",
"integrity": "sha512-FQN4MRfuJeHf7cBbBMJFXhKSDq+2kAArBlmRBvcvFE5BB1HZKXtSFASDhdlz9zOYwxh8lDdnvmMOe/+5cdoEdg==",
"dependencies": {
"delayed-stream": "~1.0.0"
},
"engines": {
"node": ">= 0.8"
}
}
},
//项目依赖的包
"dependencies": {
"asynckit": {
"version": "0.4.0",
"resolved": "https://registry.npmmirror.com/asynckit/-/asynckit-0.4.0.tgz",
"integrity": "sha512-Oei9OH4tRh0YqU3GxhX79dM/mwVgvbZJaSNaRk+bshkj0S5cfHcgYakreBjrHwatXKbz+IoIdYLxrKim2MjW0Q=="
},
"axios": {
//实际安装的axios的版本
"version": "1.1.2",
//用来记录下载的地址,在registry中的位置
"resolved": "https://registry.npmmirror.com/axios/-/axios-1.1.2.tgz",
//用来从缓存中获取索引,再通过索引去获取压缩包文件
"integrity": "sha512-bznQyETwElsXl2RK7HLLwb5GPpOLlycxHCtrpDR/4RqqBzjARaOTo3jz4IgtntWUYee7Ne4S8UHd92VCuzPaWA==",
//依赖包所需要的所有依赖项,对应依赖包package.json里dependencies中的依赖项
"requires": {
"follow-redirects": "^1.15.0",
"form-data": "^4.0.0",
"proxy-from-env": "^1.1.0"
}
}
}