介绍
vite 作为新一代开发、打包工具出现,速度比webpack快了10倍不止,于大型项目来说,是一个不可忽视的效率优化方式。
其速度优势的形成,主要基于两方面,
1:采用go语言开发的esbuild预加载工具。
2:新一代浏览器原生支持的esmodule模块管理接管打包工作,代替js。
其解决了资源加载时产生大量的http资源请求,以及简化了冗长的打包过程。
实践
构建项目
使用npm:npm init vite@latest
或者yarn:yarn create vite
以及pmpm:pnpm create vite
针对 vite+vue项目
# npm 6.x
npm init vite@latest my-vue-app --template vue
# npm 7+, 需要额外的双横线:
npm init vite@latest my-vue-app -- --template vue
# yarn
yarn create vite my-vue-app --template vue
# pnpm
pnpm create vite my-vue-app -- --template vue
主要目录结构
基本依赖
其中 @types/node 提供TS版本的node支持,在TS语言环境下使用如path、process等模块工具。
vite配置
因它使用 Rollup 打包代码,并且是预配置的,可输出用于生产环境的高度优化过的静态资源。
所以配置项相比较webpack会更加简洁!
注:在vite.config.js中无法使用process.env与import.meta.env.*
所以使用环境变量的方法需要用到 vite 全局方法 loadEnv(mode,变量名)
启动
vite内部已经集成了dotenv,所以我们可以轻易的配置、更换环境变量。
比如我们可以在根目录创建以下文件
其命名为 .env.* 的格式,文件后缀对应开发模式
我们可以在运行不同命令式时指定当前模式,比如
"scripts": {
"dev": "vite --mode dev", // 运行时
"build:prod": "vite build --mode prod", // 打包
},
使用 --mode * 命令来选用指定的全局配置文件
当我们运行了 npm run dev
此时可以使用vite提供的 import.meta.env.MODE 来查看当前的mode
console.log(import.meta.env.MODE) // 控制台输出 dev
注:vite提供 import.meta.env.* 来访问环境变量,其变量必须以 VITE_ 开头,否则不会暴露出去。
import.meta.env.PROD 与 import.meta.env.DEV 为vite提供的值,且他们应当始终相反
打包
// package.json
"scripts": {
......
"build": "vite build --mode dev", // 本地
"build:stag": "vite build --mode stag", // 预发布
"build:prod": "vite build --mode prod", // 生产
......
},
// vite.config.js
export default defineConfig({
......
// 访问线上资源的路径。可以是完整的如https://www.baidu.com/source/
// 也可以是不需要域名的路径,如下
base: "/neoclub/uta/",
......
});
值得注意的是,你使用js生成route配置,却在build后出现了无法读取module的错误,比如以下写法
const children = []
for (const menu of menus) {
const item = {
path: menu.path,
name: menu.path.replace("/", "_"),
component: () => import(`@/views${menu.path}.vue`), // 将无法正确引用模块
};
children.push(item)
}
export const router = createRouter({
history: createWebHashHistory(),
routes: [
{
path: "/home",
name: "_home",
component: () => import("@/views/home.vue"),
children
}
]
});
出现错误
解决方法
Vite 支持使用特殊的 import.meta.glob 函数从文件系统导入多个模块
匹配到的文件默认是懒加载的,通过动态导入实现,并会在构建时分离为独立的 chunk
+ const componentPath = import.meta.glob("../views/*.vue");
const children = []
for (const menu of menus) {
const item = {
path: menu.path,
name: menu.path.replace("/", "_"),
- component: () => import(`@/views${menu.path}.vue`), // 将无法正确引用模块
+ component: componentPath[`@/views${menu.path}.vue`], // 可以正确引入
};
children.push(item)
}
export const router = createRouter({
history: createWebHashHistory(),
routes: [
{
path: "/home",
name: "_home",
component: () => import("@/views/home.vue"),
children
}
]
});