《三十一》开发模式构建工具 Vite
基于 Vite4。
在实际开发中,编写的代码往往是不能被浏览器直接识别的,例如 ES6+、React、Vue、TypeScript 等,必须通过构建工具来对代码进行转换、编译,例如 Webpack、Rolluop、Vite 等。
Vite:下一代前端开发与构建工具,能够显著地提升前端开发体验。
Vite 的构成:
Vite 主要由两部分构成:
- 一个开发服务器:基于原生的 ESModule 提供了丰富的內建功能,HMR 的速度非常快。
- 一套构建指令:基于 Rollup 打包代码,可以打包输出优化过的静态资源。
可以对已有项目单独安装并使用 Vite;也可以直接使用
npm init vite
命令来创建一个基于 Vite 的项目。
Vite 启动本地服务为什么快速?
-
Vite 利用浏览器已经原生支持 ESModule,遇到 import 就发送一个 HTTP 请求去按需加载加载文件,而不需要加载整个项目。
-
Vite 会启动一个 Connect 服务器拦截这些请求,使用 ESBuild 构建工具动态生成转换后的 ESModule 代码返回给浏览器,而不需要提前解析依赖、打包构建后再启动开发服务器。
Vite2 之前是使用 koa 来搭建服务器;Vite2 及之后是使用 Connect 来搭建服务器。
Webpack 是先解析依赖、打包构建再启动开发服务器,因此启动时间更长。// src/utils/index.ts export const dateFormat = (date: string) => { return `日期为:${date}` }
-
在首次启动 Vite 时,Vite 会预构建项目的第三方依赖。
这么做的目的是:
- CommonJS 和 UMD 兼容性: 在开发阶段中,Vite 的开发服务器将所有代码视为原生 ES 模块。因此,Vite 必须先将以 CommonJS 或 UMD 形式提供的依赖项转换为 ES 模块。
- 性能: Vite 将那些具有许多内部模块的 ESM 依赖项转换为单个模块。有些包将它们的 ES 模块构建为许多单独的文件,彼此导入,例如,
lodash-es
有超过 600 个内置模块,当执行import { debounce } from 'lodash-es'
时,浏览器会同时发出 600 多个 HTTP 请求,即使服务器能够轻松处理它们,但大量请求会导致浏览器端的网络拥塞,使页面加载变得明显缓慢,通过将lodash-es
预构建成单个模块,现在我们只需要一个HTTP请求。
ESBuild 构建工具:
Vite 使用 ESBuild 作为默认的构建工具。 ESBuild 主要用于将现代 JavaScript、TypeScript、CSS 等浏览器不理解的或需要转换的代码,转换成浏览器能够理解的、向后兼容的代码。
Vite 和 Webpack 是一类工具,ESBuild 和 Babal 是一类工具。
ESBuild 的特点:
- 超快的构建速度,并且不需要缓存。
- 支持 ESModule 和 CommonJS 的模块化。
- 支持 ES6 的 TreeShaking。
- 支持 Go、JavaScript 的 API。
- 支持 TypeScript、JSX 等语法编译。
- 支持 SourceMap。
- 支持代码压缩。
- 支持扩展其他插件。
为什么 ESBuild 构建速度超快?
- ESBuild 是使用 Go 语言编写的,可以直接转换成机器代码,而无需经过字节码。
- ESBuild 可以充分利用 CPU 的多内核,尽可能让它们饱和运行。
ESBuild 会单独开一个进程,在这个进程中会尽可能地多开线程,多个线程是可以跑在多个 CPU 内核中,因此就可以并行执行。
- ESBuild 的所有内容都是从零开始编写的,没有使用第三方库,所以从一开始就考虑了各种性能问题。
Vite 的构建指令:
使用 Vite 开启本地服务:
-
新建
vite-demo
文件夹,并且运行npm init -y
命令初始化项目。 -
安装 Vite:
npm install vite -D
。 -
新建
src/index.js
文件,并编写代码。console.log('index')
-
新建
index.html
文件,并编写代码。<!DOCTYPE html> <html lang="en"> <head> <meta charset="UTF-8"> <meta name="viewport" content="width=device-width, initial-scale=1.0"> <title>Document</title> </head> <body> <script src="./src/index.js" type="module"></script> </body> </html>
-
安装 Vite:
npm install vite -D
。 -
运行
npx vite
命令,Vite 会将当前根目录下的index.html
文件作为入口文件,开启一个本地服务器,并且支持热替换。Vite 开启本地服务会比 Webpack 快很多。
使用 Vite 打包代码:
- 运行
npx vite build
命令打包上面的代码,会发现,打包输出到了 dist 文件夹下。
使用 Vite 预览打包后的代码:
如果想要预览打包后的代码的效果,可以运行 npx vite preview
命令,将会开启一个本地服务并运行打包后的文件。
必须先运行
npx vite build
命令打包代码,才可以使用npx vite preview
命令进行预览。
使用 Vite 处理各种类型的文件:
使用 Vite 处理 CSS 样式:
Vite 原生支持 CSS、CSS 预处理,还有 PostCSS 的转换,不需要额外做什么配置。
CSS:
- 新建
src/css/index.css
文件,并编写代码。body { background-color: red; }
- 在
src/index.js
文件中将其引入。import './css/index.css' console.log('index')
- 运行
npx vite
命令,会发现使用 Vite 进行的话,不需要针对 CSS 文件做什么配置,直接编译成功了,Vite 会创建一个<style></style>
标签将 CSS 内联到 HTML 文件中。
Less:
- 安装 Less:
npm install less -D
。 - 新建
src/css/index.less
文件,并编写代码。@bg: blue; body { background-color: @bg; }
- 在
src/index.js
文件中将其引入。import './css/index.less' console.log('index')
- 运行
npx vite
命令,会发现使用 Vite 进行的话,不需要针对 Less 文件做什么配置,直接编译成功了。
PostCSS:
- 安装 PostCSS 和 PostCSS 的预设:
npm install postcss postcss-preset-env -D
。 - 新建
postcss.config.js
文件,并编写配置信息。module.exports = { plugins: [ require('postcss-preset-env') ] }
- 新建
src/css/index.css
文件,并编写代码。body { user-select: none; }
- 在
src/index.js
文件中将其引入。import './css/index.css' console.log('index')
- 运行
npx vite
命令,会发现使用 Vite 进行的话,不需要针对 PostCSS 做什么配置,PostCSS 就已经生效了。
使用 Vite 处理 TypeScript 代码:
Vite 原生支持 TypeScript,不需要额外做什么配置。
- 新建
src/utils.ts
文件,并编写代码。export const dateFormat = (date: string) => { return `日期为:${date}` }
- 在
src/index.js
中将其引入。import {dateFormat} from './utils/index.ts' console.log(dateFormat('1999-10-10'))
- 运行
npx vite
命令,会发现编译成功了。
使用 Vite 处理图片:
Vite 原生支持对图片的处理,不需要额外做什么配置。
- 在
src/images/
文件夹下放入一张图片。 - 在
src/index.js
文件中将其引入。import likeImg from './images/like.jpg' const img = document.createElement('img') img.src = likeImg document.body.appendChild(img)
- 运行
npx vite
命令,会发现编译成功了。
使用 Vite 处理 Vue 文件:
Vite 对 Vue 提供了第一优先级的之处:通过 @vitejs/plugin-vue
插件实现 Vue3 单文件组件的支持;通过 @vitejs/plugin-vue-jsx
插件实现对 Vue3 JSX 的支持;通过 vite-plugin-vue2
插件实现对 Vue2 的支持。
- 安装 Vue2:
npm install vue@2
。 - 新建
src/js/App.vue
文件并编写代码。// src/js/App.vue <template> <div>{{title}}</div> </template> <script> export default { data() { return { title: 'Hello Vue' } } } </script> <style scoped></style>
- 新建
src/index.js
文件,并编写代码。// src/index.js import Vue from 'vue' import App from './js/App.vue' new Vue({ render: h => h(App) }).$mount('#app')
- 新建
index.html
文件,并编写代码。<!DOCTYPE html> <html lang="en"> <head> <meta charset="UTF-8"> <meta name="viewport" content="width=device-width, initial-scale=1.0"> <title>Document</title> </head> <body> <div id="app"></div> <script src="./src/index.js" type="module"></script> </body> </html>
- 运行
npx vite
命令进行打包,会发现报错了,Vite 无法转换 Vue 文件。
- 安装
vite-plugin-vue2
插件用来处理 Vue 文件:npm install vite-plugin-vue2 -D
。 - 新建
vue.config.js
文件,并编写配置。import {createVuePlugin} from 'vite-plugin-vue2' export default { plugins: [ createVuePlugin(), ] }
- 运行
npx vite
命令进行打包,会发现打包成功了。
使用 Vite 处理 React 文件:
Vite 原生支持 JSX 语法,不需要额外做什么配置。但是文件必须以 .jsx
为后缀,否则 Vite 不知道需要处理的是 JSX 语法。
- 安装 React 和 ReactDOM:
npm install react react-dom
。 - 新建
src/index.jsx
文件,并编写代码。// src/index.jsx import React from 'react' import ReactDOM from 'react-dom' class App extends React.Component { state = { title: 'Hello World', } render() { return ( <div>{this.state.title}</div> ) } } ReactDOM.render(<App/>, document.getElementById('app'))
- 新建
index.html
文件,并编写代码。<!DOCTYPE html> <html lang="en"> <head> <meta charset="UTF-8"> <meta name="viewport" content="width=device-width, initial-scale=1.0"> <title>Document</title> </head> <body> <div id="app"></div> <script src="./src/index.jsx" type="module"></script> </body> </html>
- 运行
npx vite
命令,会发现打包成功了。