import {defineConfig} from 'vite'
import vue from '@vitejs/plugin-vue'
import vitePluginImp from 'vite-plugin-imp'
import path from 'path'
const isProduction = process.env.NODE_ENV === 'production'
// https://vitejs.dev/config/
export default defineConfig{
// 项目根目录
root: process.cwd),
// 在生产中服务时的基本公共路径
base: isProduction ? './' : '',
// 配置中指明将会把 serve 和 build 时的模式都覆盖掉,serve 时默认 'development',build 时默认 'production'
mode: 'development',
// 在开发时会被定义为全局变量,而在构建时则是静态替换
define: '',
// 静态资源服务的文件夹
publicDir: 'assets',
resolve: {
// 目录别名
alias: {
'@': path.resolve__dirname, '/src'),
},
},
// CSS 预处理器
css: {
preprocessorOptions: {
scss: {
// additionalData: `$injectedColor: orange;`
additionalData: "@import './src/assets/style/mixin.scss';"
}
,
less: {
javascriptEnabled: true
}
},
postcss: {
plugins: [
require'autoprefixer')
]
}
},
//
server: {
// 是否自动打开浏览器
open: true,
// 服务器主机名,如果允许外部访问,可设置为"0.0.0.0"
host: '0.0.0.0',
// 服务器端口号
port: 56438,
// 设为 true ,若端口已被占用则会直接退出,而不是尝试下一个可用端口
strictPort: false,
// 为开发服务器配置 CORS
cors: true,
// 设置为 true 强制使依赖预构建
force: true,
// 代理
proxy: {
'/api':
{
target: 'http://xxx.xxx.xx',
changeOrigin: true,
rewrite:
path) => path.replace/^/api/, '')
}
}
,
}
,
// build
build: {
// 压缩
minify: "esbuild",
assetsDir: "",
outDir: `./dist/${process.env.VITE_ENV}`,
// 进行压缩计算
brotliSize: false
},
ssr: false,
// 将要用到的插件数组
plugins:
[
vue),
vitePluginImp{
libList: [
{
libName: 'vant',
stylename) {
if /CompWithoutStyleFile/i.testname)) {
// This will not import any style file
return false
}
return `vant/es/${name}/style/index.js`
}
},
{
libName: 'element-plus',
style: name) => {
return `element-plus/lib/theme-chalk/${name}.css`
}
}
]
}),
require'autoprefixer')
]
})
Vite插件是什么
使用Vite插件可以扩展Vite能力,比如解析用户自定义的文件输入,在打包代码前转译代码,或者查找第三方模块。
Vite插件的形式
Vite插件扩展自Rollup插件接口,只是额外多了一些Vite特有选项。
Vite插件是一个拥有名称、创建钩子build hook)或生成钩子output generate hook)的对象。
如果需要配置插件,它的形式应该是一个接收插件选项,返回插件对象的函数。
范例:加载一个不存在的虚拟模块
创建vite-plugin-my-example.js
export default function myExample ) {
return {
name: 'my-example', // 名称用于警告和错误展示
resolveId source ) {
if source === 'virtual-module') {
return source; // 返回source表明命中,vite不再询问其他插件处理该id请求
}
return null; // 返回null表明是其他id要继续处理
},
load id ) {
if id === 'virtual-module') {
return 'export default "This is virtual!"'; // 返回"virtual-module"模块源码
}
return null; // 其他id继续处理
}
};
}
插件钩子
通用钩子
开发时,Vite dev server创建一个插件容器按照Rollup调用创建钩子的规则请求各个钩子函数。
下面钩子会在服务器启动时调用一次:
options 替换或操纵rollup选项
buildStart 开始创建
下面钩子每次有模块请求时都会被调用:
resolveId 创建自定义确认函数,常用语定位第三方依赖
load 创建自定义加载函数,可用于返回自定义的内容
transform 可用于转换已加载的模块内容
下面钩子会在服务器关闭时调用一次:
Vite特有钩子
config: 修改Vite配置
configResolved:Vite配置确认
configureServer:用于配置dev server
transformIndexHtml:用于转换宿主页
handleHotUpdate:自定义HMR更新时调用
范例:钩子调用顺序测试
export default function myExample ) {
// 返回的是插件对象
return {
name: 'hooks-order',
// 初始化hooks,只走一次
optionsopts) {
console.log'options', opts);
},
buildStart) {
console.log'buildStart');
},
// vite特有钩子
configconfig) {
console.log'config', config);
return {}
},
configResolvedresolvedCofnig) {
console.log'configResolved');
},
configureServerserver) {
console.log'configureServer');
// server.app.usereq, res, next) => {
// // custom handle request...
// })
},
transformIndexHtmlhtml) {
console.log'transformIndexHtml');
return html
// return html.replace
// /<title>.*?)</title>/,
// `<title>Title replaced!</title>`
// )
},
// 通用钩子
resolveId source ) {
if source === 'virtual-module') {
console.log'resolvedId', source);
return source;
}
return null;
},
load id ) {
if id === 'virtual-module') {
console.log'load');
return 'export default "This is virtual!"';
}
return null;
},
transformcode, id) {
if id === 'virtual-module') {
console.log'transform');
}
return code
},
};
}
钩子调用顺序
插件顺序
别名处理Alias
用户插件设置enforce: 'pre'
Vite核心插件
用户插件未设置enforce
Vite构建插件
用户插件设置enforce: 'post'
Vite构建后置插件minify, manifest, reporting)
插件编写实操
实现一个mock服务器vite-plugin-mock
实现思路是给开发服务器实例connect)配一个中间件,该中间件可以存储用户配置接口映射信息,并提前处理输入请求,如果请求的url和路由表匹配则接管,按用户配置的handler返回结果。
创建plugins/vite-plugin-mock.js
import path from 'path'
let mockRouteMap = {};
function matchRoutereq) {
let url = req.url;
let method = req.method.toLowerCase);
let routeList = mockRouteMap[method];
return routeList && routeList.finditem) => item.path === url);
}
function createRoutemockConfList) {
mockConfList.forEachmockConf) => {
let method = mockConf.type || 'get';
let path = mockConf.url;
let handler = mockConf.response;
let route = { path, method: method.toLowerCase), handler };
if !mockRouteMap[method]) {
mockRouteMap[method] = [];
}
console.log'create mock api: ', route.method, route.path);
mockRouteMap[method].pushroute);
});
}
function sendbody) {
let chunk = JSON.stringifybody);
// Content-Length
if chunk) {
chunk = Buffer.fromchunk, 'utf-8');
this.setHeader'Content-Length', chunk.length);
}
// content-type
this.setHeader'Content-Type', 'application/json');
// status
this.statusCode = 200;
// respond
this.endchunk, 'utf8');
}
export default function options = {}) {
options.entry = options.entry || './mock/index.js';
if !path.isAbsoluteoptions.entry)) {
options.entry = path.resolveprocess.cwd), options.entry);
}
return {
configureServer: function { app }) {
const mockObj = requireoptions.entry);
createRoutemockObj);
const middleware = req, res, next) => {
let route = matchRoutereq);
if route) {
console.log'mock request', route.method, route.path);
res.send = send;
route.handlerreq, res);
} else {
next);
}
};
app.usemiddleware);
},
};
}
export default function vitePlugin ) {
// 定义vite插件唯一id
const virtualFileId = '@my-virtual-plugin'
// 返回插件对象
return {
// 必须的,将会显示在 warning 和 error 中
name: 'vite-plugin',
// *以下钩子函数按照实际执行顺序排列*
/**
* config 可以在被解析之前修改 Vite 配置
* Vite独有钩子
* https://cn.vitejs.dev/guide/api-plugin.html#config
* @param config vite配置信息
* @param env 描述配置环境的变量
*/
config: config, env) => {}),
/**
* configResolved 解析 Vite 配置后调用,使用这个钩子读取和存储最终解析的配置
* Vite独有钩子
* https://cn.vitejs.dev/guide/api-plugin.html#configresolved
* @param config vite配置信息
*/
configResolved: config => {}),
/**
* options 替换或操作传递给rollup.rollup)的选项
* 通用钩子
* https://rollupjs.org/guide/en/
* @param options rollup配置信息
*/
options: options => {}),
/**
* configureServer 用于配置开发服务器
* Vite独有钩子
* https://cn.vitejs.dev/guide/api-plugin.html#configureserver
* @param server ViteDevServer配置信息
* https://cn.vitejs.dev/guide/api-javascript.html#vitedevserver
*/
configureServer: server => {}),
/**
* buildStart 在每个rollup.rollup)构建时被调用
* 通用钩子
* https://rollupjs.org/guide/en/
* @param options rollup配置信息
*/
buildStart: options => {}),
/**
* 此时 Vite dev server is running
*/
/**
* transformIndexHtml 转换 index.html 的专用钩子
* Vite独有钩子
* https://cn.vitejs.dev/guide/api-plugin.html#transformindexhtml
* @param html html字符串
* @param ctx 转换上下文; 在开发期间会额外暴露ViteDevServer实例; 在构建期间会额外暴露Rollup输出的包
*/
transformIndexHtml: html, ctx) => {}),
/**
* resolveId 用户自定义解析器
* 通用钩子 会在每个传入模块请求时被调用
* https://rollupjs.org/guide/en/
* @param source 源导入者 例子: import { foo } from '../bar.js', '../bar.js' 为source
* @param importer 导入者所在文件绝对路径
*/
resolveId: source, importer) => {}),
/**
* load 用户自定义加载器
* 通用钩子 会在每个传入模块请求时被调用
* https://rollupjs.org/guide/en/
* @param id 同resolveId source
*/
load: id => {}),
/**
* transform 可以用来转换单个模块
* 通用钩子 会在每个传入模块请求时被调用
* https://rollupjs.org/guide/en/
* @param code 模块代码
* @param id 同resolveId source
*/
transform: code, id) => {})
}
}






