脚手架、构建工具、包管理工具

708 阅读6分钟

感谢b站up主__付金权的精彩分享!

感谢掘金博主 金色海洋 分享的一篇文章说清 webpack、vite、vue-cli、create-vue 的区别

感谢 jirengu.com 的精彩分享

脚手架

创建项目,选择性安装需要的插件,指定统一的风格,生成demo。

@vue/cli

原名 vue-cli 是 Vue 早期推出的一款脚手架,使用 Webpack 构建 Vue 项目,可以选择安装需要的各种插件,比如 Vuex、VueRouter等。

vue-cli 用于创建 vue2 的项目; @vue/cli 用于创建 vue3 的项目,当然也支持 vue2。

使用起来比较繁琐,首先要安装脚手架,然后使用 vue create hello-world 创建项目。

create-vue

create-vue 是 Vue3 的专用脚手架,使用 vite 创建 Vue3 的项目,也可以选择安装需要的各种插件,使用更简单。

yarn global add create-vite-app@1.18.0 
cva gulu-ui-1
cd gulu-ui-1
yarn   // 相当于 yarn install
yarn dev   

可选插件

标题内容
TypeScript
JSX Support
Vue RouterSingle Page Application development
Piniastate management
ESLintcode quality
Prettiercode formating
VitestUnit testing
Cypressboth Unit and End-to-End testing

构建工具

什么是构建工具

构建工具就是各种转换或编译工具的集合。

构建工具内容
转换babel 语法降级:将 ES 新语法转换兼容旧版浏览器
tsc工具:TS 代码转换为 JS 代码
Uglifyjs体积优化: 将代码压缩成体积小,性能更高的文件
vue / react-compiler:jsx 文件或 .vue文件 转换为 render 函数(浏览器能识别)
编译less / sass / postcss / component-style 对应的 loader编译工具

build 打包 就是将开发者写的浏览器不认识的代码,交给构建工具进行编译处理的过程,打包完成后给浏览器可以识别的文件。

构建工具做了什么

功能内容
模块化开发支持支持直接从node_modules里引入代码 + 多种模块化支持
处理代码兼容性babel语法降级,less、ts语法转换
提高项目性能压缩文件,代码分割
热更新构建工具自动监听文件变化,调用对应的集成工具重新打包,浏览器再重新运行
开发服务器解决跨域的问题

构建工具发展

标题打包脚本构建工具
史前 无Node.js之前PHP / Python / Java / Ruby / BashScriptmake
Node.js 问世
(为打包而生)
npm run dev 开发环境 dev 调用 JS 脚本
npm run build 生产环境 build 调用 JS 脚本
Grunt:以 文件 为操作对象,以 任务 为运行单元。
Gulp:操作放在内存中
Webpack全能选手:支持多场景的模块化,不限于浏览器端。
Vue Cli 是基于 Webpack 的 Vue 工具链
缺点是配置复杂,打包随着项目变大,越来越慢
Rollup打包性能比Webpack好缺点:功能不如Webpack全
Parcel优点是零配置缺点:功能不如Webpack全
Snowpack
Vite优点是远大于Webpack的开发速度
开发时,不打包,充分利用浏览器的module能力,按需加载
发布时,用Rollup打包
缺点是插件不够多
Turbopack

Webpack (2014年发布)

支持多场景的模块化,不限于浏览器端。 对于浏览器端的Webpack工作机制:提供importexportES6模块化的语法支持,把Nodejs模块化的代码转换为浏览器执行的代码。

loaderplugin区别

image.png
  • loader用于加载文件:任何文件都可以通过import导入进来,要有对应loader
module.exports = {
  module:{
    rules:[{
      test:/\.css$/i,
      use:["style-loader","css-loader"]
    }]
  } 
}
  • plugin用于扩展功能,插件参与打包过程(去除不必要代码)
const HtmlWebpackPlugin = require("html-webpack-plugin");
module.exports = {
  plugins:[new HtmlWebpackPlugin()]
}

常用功能

yarn add webpack@4.41.2 webpack-cli@3.3.10
yarn add webpack-dev-server@3.9.0
webpack-dev-server  // 本地预览
yarn init -y      // 初始化工程

懒加载

对于某个JS文件很大,存在很多的模块,不想一开始就加载,当用户开启某个功能时,再去加载某个模块。

export default function lazy(){
    console.log('我是一个懒加载的模块')
}
const promise = import('./lazy')  
promise.then((module)=>{    // 成功执行的函数
  const fn = module.default
  fn()
},()=>{                     // 失败执行的函数
  console.log('模块加载错误')
})  

Rollup(2015年发布)

  • 面向ES Modules(最新的JS模块语法)而不是AMD/CommonJS(Webpack支持的旧标准),支持Tree-shaking
  • 不提供dev server,只做生产环境打包

Parcel(2017年发布)

优点:零配置,缺点:功能不如Webpack全

Snowpack(2019年发布)

Vite(并不只是打包)

  • 官方文档:Vitejs.dev
  • 继承Snowpack的核心思想:开发时,不打包,充分利用浏览器的module能力,按需加载
  • 发布时,用Rollup打包。
  • 搭建项目:Vite 需要Node.js版本 14.18+,16+

create-vite(vite脚手架)

create-vite和vite的关系是:

create-vite内置了vite,就像vue-cli会内置webpack

Vite周边

  • VitePress:用于建立文档类型的网站

  • Slidev:用Markdown做PPT的工具

  • Vitest:类似Jest的前端测试框架

Turbopack

Webpack的后继打包工具,由维护NextjsVercel公司开发。底层用Rust编写

打包过程在开发时期,不同于Vite的利用浏览器自身的模块化,不会对开发时对依赖打包.

包管理工具

为什么需要包管理

随着一个网站依赖的代码越来越多,下载资源要逛很多个站点,操作起来很麻烦,一个靠谱程序员因为实在受不了,自己就用 JS (运行在 Node.js 上)开发了一个工具把下载资源的这些代码集中到一起管理。

这个工具的全称为:Node Package Manager这些代码就称为:包(package),后来npm内置于Node.js中,即npm会随着node.js自动安装。

这个靠谱的程序员是:Isaac Z. Schlueter

包管理能做什么

npm可以管理本地项目的所需模块并自动维护依赖情况,也可以管理全局安装的 JS 工具;

如果一个项目中存在package.json文件,那么用户可以直接使用npm install命令自动安装和维护当前项目所需的所有模块。

常用工具

包管理内容备注
npm下载工具串行下载依赖
yarn
(facebook)
包管理工具并行下载依赖、支持从缓存安装、引入yarn.lock机制
pnpm包管理工具全局安装所有依赖,安装速度极快、磁盘空间利用效率高

node_modules 结构历史

标题内容
npm@3 之前版本
(第一阶段)
依赖树层级深,目录路径长
npm@3 版本
(第二阶段)
依赖结构不确定,扁平化算法复杂,耗时长
pnpm
(第三阶段)
硬链+软链 根目录中的包只是一个符号链接
// (第一阶段)npm@3 之前版本
node_modules
└─ foo
   ├─ index.js
   ├─ package.json
   └─ node_modules
      └─ bar
         ├─ index.js
         └─ package.json

// (第二阶段)npm@3 版本 扁平化处理
node_modules
├─ foo
|  ├─ index.js
|  └─ package.json
└─ bar
   ├─ index.js
   └─ package.json
   
//  (第三阶段)pnpm 版本   
node_modules
├─ .pnpm
|  ├─ foo@1.0.0/node_modules/foo
|  |  └─ index.js
|  └─ bar@2.0.0/node_modules/bar
├─ foo -> .pnpm/foo@1.0.0/node_modules/foo
└─ bar -> .pnpm/bar@2.0.0/node_modules/bar

第三阶段:pnpm

node_modules 根目录中的包只是一个符号链接。require('foo') 将执行 node_modules/.pnpm/foo@1.0.0/node_modules/foo/indexjs 中的文件(这里是硬链接),而不是 node_modules/foo/index.js 中的文件。

这种布局结构的一大好处是只有真正在依赖项中(package.json dependences)的包才能访问