在使用 vite
开发过程中,我们遇到了一些问题,也提出了一些基于 vite
的解决方案。该文章围绕 vite
相关,介绍了相关的一些方案。
@tzxhy/vite-plugin-case-sensitive
vite 大小写敏感插件。Mac/Windows
下,文件路径是大小写不敏感的
,可能导致相同的代码,在 linux
平台上构建失败。引入该插件后,当引用的 path
不存在时,提示报错,如下:
安装
1
| yarn add @tzxhy/vite-plugin-case-sensitive
|
使用
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27
| import { defineConfig, } from 'vite';
import caseSensitivePlugin from '@tzxhy/vite-plugin-case-sensitive';
const ProjectPathDir = 'Your Project Path Dir'; const ProjectRootDir = 'Your Project Root Path Dir';
export default defineConfig((env) => { const plugins = []; if (env.mode !== 'production') { plugins.push(caseSensitivePlugin({ watch: [ path.join(ProjectPathDir, 'src'), path.join(ProjectRootDir, 'src'), ], })); } return { plugins, } })
|
@tzxhy/vite-generate-mock
根据 swagger.json
文档,创建 vite-plugin-mock
所用的 ts 文件。
安装
1
| yarn add @tzxhy/vite-generate-mock -D
|
使用
创建自定义文件,如:
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44 45 46 47 48 49 50 51 52 53 54 55 56 57 58 59 60 61 62 63 64 65 66 67 68 69 70 71 72 73 74 75 76 77 78 79 80 81 82 83 84
|
const path = require('path'); const fs = require('fs'); const generate = require('@tzxhy/vite-generate-mock').default; let customJsonConf = {}; try { customJsonConf = require('../mock/custom-mock-conf'); } catch(e) { console.log('如果需要自定义代理,创建 mock/custom-mock-conf.js 文件内容如:' + ` module.exports = { '/v1/mec/device/create_sensor': { url: '/api/mec/device/create_sensor_new', method: 'post', response: () => ({ errCode: 0, errMsg: 'success', errDetail: Random.string(), data: { rsuSerial: Random.string(), }, }), }, };`); }
const customInterfaceKeys = Object.keys(customJsonConf);
const mockCodes = generate({ fileHeader: '', apiPath: path.join(__dirname, '..', 'swagger', 'api.swagger.json'), apiPathRewrite(apiPath) { return apiPath.replace('/v1', '/api'); }, apiReplace(apiPath) { if (customInterfaceKeys.includes(apiPath)) { return this.returnObj(customJsonConf[apiPath]); } }, responseAdapter(apiPath, curveKeyName, curveLevel) { if (curveKeyName === 'totalPages') { return this.createNumberLiteral(100); } if (curveKeyName === 'count') { return this.createNumberLiteral(10000); } if (curveKeyName === 'id') { return this.createRandomNumber(1, 1000); } if (curveKeyName === 'alertingNum' || curveKeyName === 'totalAlerting' || curveKeyName === 'totalErrors' || curveKeyName === 'totalHistoryErrors' || curveKeyName === 'totalHistoryAlerting' ) { return this.createRandomNumber(1, 200); } if (curveKeyName === 'keepingTime') { return this.createRandomNumber(1000 * Math.floor(Math.random() * 1e3), 1e8); } if (curveKeyName === 'timestamp') { return this.createStringLiteral(new Date().valueOf() + '') } if (curveKeyName === 'errCode') { return this.createNumberLiteral(0); } if (curveKeyName === 'errMsg') { return this.createStringLiteral('success'); } } });
const mockDest = path.join(__dirname, '..', 'mock', 'api.ts'); fs.writeFileSync(mockDest, mockCodes); console.log('mock源文件已生成至: ' + mockDest);
|
配置 package.json
:
1 2 3 4 5 6 7
| { "scripts": { "start-with-mock": "yarn typings && yarn generate-mock && vite --open --mode mock", "generate-mock": "node scripts/generate-mock", "typings": "other things" } }
|
配置 vite.config.js
,如下:
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44 45 46 47
| import { defineConfig, } from 'vite';
import { viteMockServe, } from 'vite-plugin-mock';
export default defineConfig((env) => { const plugins = []; if (env.mode === 'mock') { console.log('use mock server...'); plugins.push( viteMockServe({ mockPath: 'mock', localEnabled: true, }), ); const mockGenerate = path.join(__dirname, 'scripts', 'generate-mock.js');
fs.watch(mockGenerate, () => { childProcess.exec('node ' + mockGenerate, (err, std) => { console.log(std); }); });
try { const customMock = path.join(__dirname, 'mock', 'custom-mock-conf.js'); fs.watch(customMock, () => { childProcess.exec('node ' + mockGenerate, (err, std) => { console.log(std); }); }); } catch (error) { console.log('watch custom mock error', '\n', error); } return { plugins, } })
|
然后开启 mock 开发
即可: yarn start-with-mock
。
@tzxhy/vite-plugin-shaking-css-module
vite 插件
。用于去除 vue3 css module 中未引用的样式 (css module tree shaking)。
例如:
style.less 文件(独立 SFC 样式文件):
1 2 3 4 5 6 7 8
| .test() { background-color: white; }
.app3 { .test; color: yellow; }
|
.vue 文件(SFC 单组件,包含内嵌 style 标签):
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31
| <template> <img :class="css.app" alt="Vue logo" src="./assets/logo.png" /> <span :class="css.app3">{{ count }}</span> </template> <script> // 略
import { ref, useCssModule, } from 'vue'; const css = useCssModule('css'); // 引用 app2 console.log('css: ', css.app2); </script> <style lang="less" module="css"> @import "./style.less"; // 引用上面的样式文件 // 被 template 引用 .app { font-family: Avenir, Helvetica, Arial, sans-serif; -webkit-font-smoothing: antialiased; -moz-osx-font-smoothing: grayscale; text-align: center; color: #2c3e50; margin-top: 60px; } // 被 script 引用 .app2 { margin-top: 60px; } </style>
|
main.ts 中可引用公共样式(不会被 tree shaking):
public.less 文件:
1 2 3 4 5 6 7
| #root { background-color: blue; } body { color: #666 }
|
则打包后,css 文件只会包含:.app, .app3,.app2 和非 SFC 样式。其余违背依赖的样式将被剔除,如:
1
| #root{background-color:#00f}body{color:#666}._app3_368a9{background-color:#fff;color:#ff0}._app_b4102{font-family:Avenir,Helvetica,Arial,sans-serif;-webkit-font-smoothing:antialiased;-moz-osx-font-smoothing:grayscale;text-align:center;color:#2c3e50;margin-top:60px}._app2_87af3{margin-top:60px}
|
安装
1
| yarn add @tzxhy/vite-plugin-shaking-css-module -D
|
引入方式
在 vite.config.js
中声明插件:
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20
| import pureCss from '@tzxhy/vite-plugin-shaking-css-module'; import vue from '@vitejs/plugin-vue';
export default defineConfig((env) => { const pureCssPlugin = pureCss(); const plugins = [vue(), pureCssPlugin]; return { css: { modules: { generateScopedName: pureCssPlugin.generateScopedName, }, }, plugins, }; });
|
其他
当前仅能分析出 template 和 script 中直接使用 CssModulesName.moduleName (或者 CssModulesName [‘moduleName]) 的形式获取依赖;对于动态求值类型,无法计算。当出现这种情况时,可以在 script 中增加引用,如:
1 2 3 4 5 6 7 8 9 10 11 12 13 14
| <template> <div :class="'dynamicModule' + no" /> </template> <script> // 略 import { ref, useCssModule, } from 'vue'; const css = useCssModule('css'); const no = ref(1); // 1 或者 2
// 依赖检测注入 (css.dynamicModule1, css.dynamicModule2); </script>
|