Commit 1c1dbda0 authored by zhangfangli's avatar zhangfangli

浅谈vite

parent c90c966a
Pipeline #16178 canceled with stage
---
title: 浅谈vite
date: 2022/5/25 15:00:00
tags:
- vite
- package.json
author: 张芳利
---
<a name="Sxg5O"></a>
# 1. Vite 简介
<a name="GUv9u"></a>
## 1.1 Vite是什么?
Vite是一个由原生 ES Module 驱动的 Web 开发前端构建工具,它能显著改善前端开发体验;<br />要由两部分组成:
- 一个开发服务器,它基于 [原生 ES 模块](https://developer.mozilla.org/en-US/docs/Web/JavaScript/Guide/Modules) 提供了 [丰富的内建功能](https://vitejs.cn/guide/features.html),如速度快到惊人的 [模块热更新(HMR)](https://vitejs.cn/guide/features.html#hot-module-replacement)
- 一套构建指令,生产环境,它使用 [Rollup](https://rollupjs.org/) 打包你的代码,并且它是预配置的,可输出用于生产环境的高度优化过的静态资源。
<a name="V0wyB"></a>
## 1.2 Vite的特性
- 💡 **极速的服务启动:** 使用原生 ESM 文件,无需打包!
- ⚡️ **轻量快速的热重载:** 无论应用程序大小如何,都始终极快的模块热重载(HMR)
- 🛠️ **丰富的功能:** 对 TypeScript、JSX、CSS 等支持开箱即用。
- 📦 **优化的构建**:可选 “多页应用” 或 “库” 模式的预配置 Rollup 构建
- 🔩 **通用的插件**: 在开发和构建之间共享 Rollup-superset 插件接口。
- 🔑 **完全类型化的API**:灵活的 API 和完整 TypeScript 类型
<a name="Vv04S"></a>
# 2. Vite概念及设计思想
**打包:**使用工具抓取、处理并将我们的源码模块串联成可以在浏览器中运行的文件。
<a name="vmIab"></a>
## 2.1 和webpack 的区别
1. **打包和速度:**
webpack: 分析依赖=> 编译打包=> 交给本地服务器进行渲染。首先分析各个模块之间的依赖,然后进行打包,在启动webpack-dev-server,请求服务器时,直接显示打包结果。webpack打包之后存在的问题:随着模块的增多,会造成打出的 bundle 体积过大,进而会造成热更新速度明显拖慢。<br />![image.png](https://cdn.nlark.com/yuque/0/2022/png/22328960/1649906843938-e3f48703-d829-4552-8f60-94e9f6eda148.png#clientId=u66ceec79-db7d-4&crop=0&crop=0&crop=1&crop=1&from=paste&id=u271aea00&margin=%5Bobject%20Object%5D&name=image.png&originHeight=913&originWidth=1920&originalType=url&ratio=1&rotation=0&showTitle=false&size=144825&status=done&style=shadow&taskId=u69c1edc9-52b2-4ffe-bccf-ddae1305f22&title=)
vite: 启动服务器=> 请求模块时按需动态编译显示。是先启动开发服务器,请求某个模块时再对该模块进行实时编译,因为现代游览器本身支持ES-Module,所以会自动向依赖的Module发出请求。所以vite就将开发环境下的模块文件作为浏览器的执行文件,而不是像webpack进行打包后交给本地服务器。<br />![image.png](https://cdn.nlark.com/yuque/0/2022/png/22328960/1649906852732-e8b0df7d-cf10-4b82-b97c-755ae7cc32ec.png#clientId=u66ceec79-db7d-4&crop=0&crop=0&crop=1&crop=1&from=paste&id=u03b35c54&margin=%5Bobject%20Object%5D&name=image.png&originHeight=960&originWidth=1920&originalType=url&ratio=1&rotation=0&showTitle=false&size=155796&status=done&style=shadow&taskId=u4bf869fb-ed51-4bf9-8a67-0911a7031f8&title=)
2. **工具定位:**
webpack:是偏底层的东西,进行配置化,灵活度极高的工具,具有丰富的生态圈<br />vite: 是开箱即用,使用更简单的工具,但是目前是属于起步阶段
结论:
1. Vite主打特点就是轻快冷服务启动。冷服务的意思是,在开发预览中,它是不进行打包的。
1. 开发中可以实现热更新,也就是说在你开发的时候,只要一保存,结果就会更新。
1. 按需进行更新编译,不会刷新全部DOM节点。这功能会加快我们的开发流程度。
<a name="rEfXe"></a>
## 2.2 Esm 加载对比
1. esm 文件中,创建index.js , 引入main.js
![image.png](https://cdn.nlark.com/yuque/0/2022/png/22328960/1653447450005-2b833bbf-8fb2-468d-b5d8-2e4cb55834d7.png#clientId=ud79621cb-ae54-4&crop=0&crop=0&crop=1&crop=1&from=paste&height=351&id=u5f31b6be&margin=%5Bobject%20Object%5D&name=image.png&originHeight=351&originWidth=1151&originalType=binary&ratio=1&rotation=0&showTitle=false&size=36241&status=done&style=shadow&taskId=uabd2980f-3412-415a-89f5-2601c926139&title=&width=1151)
2. 安装 lodash的包
`yarn add lodash-es`
3. 引入loadsh,并利用她的fiter 功能
```jsx
console.log('测试esm');
import {filter} from 'loadsh'
const arr = [{name:'张小张',age:'22'},{name:"王小王",age:'18'}]
const newArr = filter(arr,item=>item.age>20)
console.log(newArr);
```
报错:<br />Uncaught TypeError: Failed to resolve module specifier "loadsh". Relative references must start with either "/", "./", or "../".<br />浏览器原生解析路径的问题,所以换一下引入方式<br />node_modules中找到lodash-es,找到她的package,json,查看找到 "main": "lodash.js"
```jsx
import { filter } from './node_modules/lodash-es/lodash.js'
```
4. 利用**Live Server** 插件,项目启动
![image.png](https://cdn.nlark.com/yuque/0/2022/png/22328960/1653449009035-6bb482eb-f7ed-4999-b01f-9f48e90598ac.png#clientId=ud79621cb-ae54-4&crop=0&crop=0&crop=1&crop=1&from=paste&height=359&id=u9dbcb02e&margin=%5Bobject%20Object%5D&name=image.png&originHeight=359&originWidth=395&originalType=binary&ratio=1&rotation=0&showTitle=false&size=18817&status=done&style=shadow&taskId=ub8e9c570-f0c9-4a5f-84f5-35e47bbaed1&title=&width=395)
5. 我们能看到打印出来的东西:
![image.png](https://cdn.nlark.com/yuque/0/2022/png/22328960/1653449056058-c7481993-8ec8-4a14-bcce-42ca5f029251.png#clientId=ud79621cb-ae54-4&crop=0&crop=0&crop=1&crop=1&from=paste&height=152&id=u7ef73e3e&margin=%5Bobject%20Object%5D&name=image.png&originHeight=152&originWidth=304&originalType=binary&ratio=1&rotation=0&showTitle=false&size=6955&status=done&style=shadow&taskId=u1eacf5f9-d6a1-4f7d-b2e5-f34ebfc6a31&title=&width=304)<br />以及请求的情况<br />![image.png](https://cdn.nlark.com/yuque/0/2022/png/22328960/1653449948119-5bef0b66-a27b-4ddd-a5a3-4e54b3e07cee.png#clientId=ud79621cb-ae54-4&crop=0&crop=0&crop=1&crop=1&from=paste&height=643&id=uf35290e3&margin=%5Bobject%20Object%5D&name=image.png&originHeight=643&originWidth=621&originalType=binary&ratio=1&rotation=0&showTitle=false&size=74073&status=done&style=shadow&taskId=u60c4ce1a-29d6-49da-917a-faf75213317&title=&width=621)<br />![image.png](https://cdn.nlark.com/yuque/0/2022/png/22328960/1653450060455-1649ff6b-03fc-4a63-93eb-3f4bd0329518.png#clientId=ud79621cb-ae54-4&crop=0&crop=0&crop=1&crop=1&from=paste&height=38&id=u65eefacd&margin=%5Bobject%20Object%5D&name=image.png&originHeight=38&originWidth=633&originalType=binary&ratio=1&rotation=0&showTitle=false&size=4527&status=done&style=shadow&taskId=ufc4deede-5ea2-4e1d-85e0-e3839921966&title=&width=633)<br />从上面看到只是用到了一个过滤但是其他的模块等也都进行了请求,浪费了时间
**vite是怎么做的呢?**
1. 创建一个vite-esm 文件
`yarn create vite`
2. 同样 安装lodash-es
2. main.js 中同样操作
```jsx
console.log('测试esm');
import { filter } from 'lodash-es'
const arr = [{name:'张小张',age:'22'},{name:"王小王",age:'18'}]
const newArr = filter(arr,item=>item.age>20)
console.log(newArr);
```
4. yarn dev 后,页面中看到
![image.png](https://cdn.nlark.com/yuque/0/2022/png/22328960/1653449853100-19c6cc19-f6d0-4eca-a1a0-787d8557adb9.png#clientId=ud79621cb-ae54-4&crop=0&crop=0&crop=1&crop=1&from=paste&height=151&id=u180269b3&margin=%5Bobject%20Object%5D&name=image.png&originHeight=151&originWidth=430&originalType=binary&ratio=1&rotation=0&showTitle=false&size=8151&status=done&style=shadow&taskId=uc65bec13-9284-4300-948b-1ce3cf5cb58&title=&width=430)<br />以及请求情况<br />![image.png](https://cdn.nlark.com/yuque/0/2022/png/22328960/1653449905941-940af26d-1daa-4e4a-9b0a-34ca48ce5130.png#clientId=ud79621cb-ae54-4&crop=0&crop=0&crop=1&crop=1&from=paste&height=260&id=u7ee1fd55&margin=%5Bobject%20Object%5D&name=image.png&originHeight=260&originWidth=563&originalType=binary&ratio=1&rotation=0&showTitle=false&size=24024&status=done&style=shadow&taskId=u8f373007-a4ca-4293-a3d6-d774a0c5210&title=&width=563)<br />![image.png](https://cdn.nlark.com/yuque/0/2022/png/22328960/1653450092822-a66700d0-75af-4539-8200-7cf559f57718.png#clientId=ud79621cb-ae54-4&crop=0&crop=0&crop=1&crop=1&from=paste&height=38&id=uc8232047&margin=%5Bobject%20Object%5D&name=image.png&originHeight=38&originWidth=615&originalType=binary&ratio=1&rotation=0&showTitle=false&size=4295&status=done&style=shadow&taskId=ue1c6145a-f58b-4a55-b62a-2be17c87de0&title=&width=615)<br />对比之下可以看到,页面清爽了很多,很多没有必要的请求也没有了。
<a name="vXvPP"></a>
# 3. vite 的使用
> Vite 需要 [Node.js](https://nodejs.org/en/) 版本 >= 12.0.0。
- **npm **
```jsx
npm init vite-app <project-name>
cd <project-name>
npm install
npm run dev
```
或者
```jsx
npm init @vitejs/app 项目名
npm init vite@latest
```
这个命令安装就是一步步自己选择一下是react还是vue,以及ts 等。如果选择vue,都是vue3.0的。
- **yarn**
```jsx
yarn create vite-app <project-name>
cd <project-name>
yarn
yarn dev
```
或者
```jsx
yarn create @vitejs/app 项目名
```
使用yarn有个问题 :文件名、目录名或卷标语法不正确<br />解决方法:[https://juejin.cn/post/6844904111570190349](https://juejin.cn/post/6844904111570190349)
vite中还会有一些模板可以选择,指定的所有相关项目模板都可以在[ https://github.com/vitejs/awesome-vite#templates]() 仓库中找到
> 一般都是默认创建的是vue3的项目,所以如果创建vue2,需要做一些修改之类的或者在模板库中查找使用
<a name="z548o"></a>
## 3.1 遇到的问题
控制台会显示 user --host to expose(使用 --host 暴露网络) <br />![image.png](https://cdn.nlark.com/yuque/0/2022/png/22328960/1649918916965-18facd57-edcd-4802-86ce-c93bb1eef370.png#clientId=u66ceec79-db7d-4&crop=0&crop=0&crop=1&crop=1&from=paste&height=141&id=ud7f8d36a&margin=%5Bobject%20Object%5D&name=image.png&originHeight=127&originWidth=399&originalType=binary&ratio=1&rotation=0&showTitle=false&size=6185&status=done&style=shadow&taskId=ua767c17e-be36-4279-930f-444bb45e8dc&title=&width=443.33334507765625)<br />解决方法:
1. 在根目录下的 vite.config.js 文件中添加以下内容
```jsx
import vue from '@vitejs/plugin-vue'
/**
* https://vitejs.dev/config/
* @type {import('vite').UserConfig}
*/
export default {
plugins: [vue()],
server: { // ← ← ← ← ← ←
host: '0.0.0.0' // ← 新增内容 ←
} // ← ← ← ← ← ←
}
```
2. 通过 Vite CLI 配置
执行 npx vite --host 0.0.0.0 命令后,就可以通过 http://10.56.116.128:3000/ 访问了。
3. 修改npm 脚本
修改 package.json 文件中 scripts 节点下的脚本,如下
```jsx
"scripts": {
"dev": "vite --host 0.0.0.0",
"build": "vite build",
"serve": "vite preview --host 0.0.0.0"
}
```
<a name="R0yEc"></a>
## 3.2 项目目录
```jsx
|-node_modules -- 项目依赖包的目录
|-public -- 项目公用文件
|--favicon.ico -- 网站地址栏前面的小图标
|-src -- 源文件目录,程序员主要工作的地方
|-assets -- 静态文件目录,图片图标,比如网站logo
|-components -- Vue3.x的自定义组件目录
|--App.vue -- 项目的根组件,单页应用都需要的
|--index.css -- 一般项目的通用CSS样式写在这里,main.js引入
|--main.js -- 项目入口文件,SPA单页应用都需要入口文件
|--.gitignore -- git的管理配置文件,设置那些目录或文件不管理
|-- index.html -- 项目的默认首页,Vue的组件需要挂载到这个文件上
|-- package-lock.json --项目包的锁定文件,用于防止包版本不一样导致的错误
|-- package.json -- 项目配置文件,包管理、项目名称、版本和命令
|--vite.config.js -- 配置文件
```
<a name="mLpTv"></a>
## 3.3 vite插件
Vite 旨在为常见的 web 开发工作提供开箱即用的支持。你可以使用插件进行扩展功能。<br />地址:[https://github.com/vitejs/awesome-vite#plugins](https://github.com/vitejs/awesome-vite#plugins)<br />例如:为传统浏览器提供支持
1. 下载
```jsx
npm i -D @vitejs/plugin-legacy
```
2. 需要将它添加到项目的 devDependencies 并在 vite.config.js 配置文件中的 plugins 数组中引入它
```jsx
// vite.config.js
import legacy from '@vitejs/plugin-legacy'
import { defineConfig } from 'vite'
export default defineConfig({
plugins: [
legacy({
targets: ['defaults', 'not IE 11']
})
]
})
```
<a name="YkAyf"></a>
## 3.4 vite.config.js
1. 是否自动在浏览器打开
`open: true`
2. 在生产中服务时的基本公共路径
`base: './',`
3. 与“根”相关的目录,构建输出将放在其中。如果目录存在,它将在构建之前被删除
`outDir: 'dist'`
4. 更改默认端口
`port:8080,`
5. 开启热更新
`hmr:true`
6. 配置别名路径
```jsx
resolve:{
alias:{
"@":resolve(__dirname,"src"),
"@c":resolve(__dirname,"src/components"),
}
},
```
7. 设置便捷图片路径引用
```jsx
resolve:{
alias:{
"/img":"src/assets/images/"
//这里不能通过path模块解析路径的写法
}
},
```
8. 把vite打包以后的js,css和img资源分别分门别类在js/css/img文件夹中
```jsx
build:{
assetsDir:"static",
rollupOptions:{ //自定义底层的 Rollup 打包配置,从 Rollup 配置文件导出的选项相同
input:{
index:resolve(__dirname,"index.html"),
project:resolve(__dirname,"project.html")
},
output:{
chunkFileNames:'static/js/[name]-[hash].js',
entryFileNames:"static/js/[name]-[hash].js",
assetFileNames:"static/[ext]/name-[hash].[ext]"
}
},
},
```
8. 跨域
```jsx
server: {
port: '3000',
open: false, //自动打开
base: "./ ", //生产环境路径
proxy: { // 本地开发环境通过代理实现跨域,生产环境使用 nginx 转发
// 正则表达式写法
'^/api': {
target: 'http://xxx.xxx.xxx.xxx:9999', // 后端服务实际地址
changeOrigin: true, //开启代理
rewrite: (path) => path.replace(/^\/api/, '')
}
}
},
```
<a name="agldq"></a>
## 3.5 给项目配置多个环境
1. 在项目根目录下分别新建.env.development,.env.test,.env.production文件
```jsx
//.env.devopment文件内容
NODE_ENV="development"
VITE_APP_BASEAPI="https://www.dev.com"
//.env.test文件内容
NODE_ENV="test"
VITE_APP_BASEAPI="https://www.test.com"
//.env.production文件内容
NODE_ENV="production"
VITE_APP_BASEAPI="https://www.production.com"
```
2. package.json
```jsx
"scripts": {
"dev": "vite --mode development",
"build": "vite build --mode production",
"test": "vite build --mode test",
"preview": "vite preview"
},
```
3. 项目中通过Import.meta.env.VITE_APP_BASEAPI来获取对应环境的值
```jsx
<template>
<div>
<Item></Item>
</div>
</template>
<script setup>
import { defineComponent, onMounted, ref } from 'vue'
import Item from "@c/item.vue"
console.log("env", import.meta.env.VITE_APP_BASEAPI)
console.log("可选链", obj?.gender || "male")
})
</script>
```
<a name="pgCX0"></a>
# 4. npm init vite@latest做了什么?
<a name="HsCxP"></a>
## 4.1 npm init
npm init :初始化一个简单的package.json文件,执行该命令后终端会依次询问 name, version, description 等字段<br />查询[文档](https://docs.npmjs.com/cli/v7/commands/npm-init)得知:<br />`**npm init <initializer>**`**:**can be used to set up a new or existing npm package.(可以用来建立一个新的或现有的NPM包)
<a name="oLGN9"></a>
## 4.2 npm init <initializer>
initializer in this case is an npm package named create-<initializer>, which will be installed by [npm-exec](https://docs.npmjs.com/cli/v7/commands/npm-exec), and then have its main bin executed -- presumably creating or updating package.json and running any other initialization-related operations.<br />(initializer 在这种情况下是一个名为 create-<initializer> 的 npm 包,这个包将由 [npm-exec](https://link.juejin.cn?target=https%3A%2F%2Fdocs.npmjs.com%2Fcli%2Fv7%2Fcommands%2Fnpm-exec)(也就是 **npx**) 来安装,然后执行 package.json 中 bin 属性对应的脚本,运行任何其他与初始化相关的操作。
init命令转化为对应的npm exec操作如下:
- npm init foo->npm exec create-foo
- npm init @usr/foo->npm exec @usr/create-foo
- npm init @usr->npm exec @usr/create
由上面得知:<br />npm init vite@latest => npx create-vite
<a name="ExHkk"></a>
## 4.3 查询create-vite
通过 [npmjs.com](https://link.juejin.cn/?target=http%3A%2F%2Fnpmjs.com) 查找 create-vite 或在 Vite 源代码中的 [packages](https://link.juejin.cn/?target=https%3A%2F%2Fgithub.com%2Fvitejs%2Fvite%2Ftree%2Fmain%2Fpackages) 文件夹(如下图)中可以看到有 [create-vite](https://link.juejin.cn/?target=https%3A%2F%2Fgithub.com%2Fvitejs%2Fvite%2Ftree%2Fmain%2Fpackages%2Fcreate-vite)<br />![image.png](https://cdn.nlark.com/yuque/0/2022/png/22328960/1652066071695-270ef119-cd3e-4759-99f1-ff72cb0ff793.png#clientId=u1fadd584-440f-4&crop=0&crop=0&crop=1&crop=1&from=paste&height=429&id=u91adb811&margin=%5Bobject%20Object%5D&name=image.png&originHeight=429&originWidth=871&originalType=binary&ratio=1&rotation=0&showTitle=false&size=42372&status=done&style=shadow&taskId=u7d18ef8c-0a6e-41a8-9cfa-94b1cfce5ab&title=&width=871)<br />![image.png](https://cdn.nlark.com/yuque/0/2022/png/22328960/1652066166077-54469a02-4af5-4cb1-8c3e-77f639caa777.png#clientId=u1fadd584-440f-4&crop=0&crop=0&crop=1&crop=1&from=paste&height=824&id=ue4178843&margin=%5Bobject%20Object%5D&name=image.png&originHeight=824&originWidth=783&originalType=binary&ratio=1&rotation=0&showTitle=false&size=70791&status=done&style=shadow&taskId=u9a62ff18-3905-428e-aa4b-94d3e5791fc&title=&width=783)<br />查看在 create-vite 文件夹下的 package.json 中发现 [bin 入口](https://link.juejin.cn/?target=https%3A%2F%2Fgithub.com%2Fvitejs%2Fvite%2Fblob%2Fmain%2Fpackages%2Fcreate-vite%2Fpackage.json%23L7)<br />![image.png](https://cdn.nlark.com/yuque/0/2022/png/22328960/1652066220280-96132ee8-2dfe-421c-8645-7505d6acbd8c.png#clientId=u1fadd584-440f-4&crop=0&crop=0&crop=1&crop=1&from=paste&height=861&id=uc98f3c46&margin=%5Bobject%20Object%5D&name=image.png&originHeight=861&originWidth=739&originalType=binary&ratio=1&rotation=0&showTitle=false&size=65541&status=done&style=shadow&taskId=u06c77076-ea95-4fce-ae35-99b3155a3a7&title=&width=739)
<a name="OVWEq"></a>
#
Markdown is supported
0% or
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment