Vite 模板语法
场景
当一套代码,需要发布到两个环境(
A环境
和B环境
)中时,A环境
下需要系统管理页面,B环境
下不需要系统管理页面。这时,我们可以通过后端返回的菜单控制。但是如果
A环境
和B环境
的登录页面也不一样呢?这时,我们就可能需要模板语法来控制。需要自定义一个
vite
插件,在打包前,读取环境变量,然后使用 blueimp-tmpl 的模板语法对代码进行判断并替换。
项目地址
实践
安装依赖
blueimp-tmpl 模板语法
1
npm install blueimp-tmpl
cross-env 跨环境执行命令
1
npm install cross-env -D
获取环境变量
在
package.json
文件中添加scripts
脚本1
2
3
4
5
6
7
8"scripts": {
"dev": "npm run dev:A",
"dev:A": "cross-env platform=A vite",
"dev:B": "cross-env platform=B vite",
"build": "npm run build:A",
"build:A": "npx rimraf dist && cross-env platform=A vite build",
"build:B": "npx rimraf dist && cross-env platform=B vite build",
},platform=A
和platform=B
是自定义变量。只要是xxx=xxx
这种格式的变量,都可以通过process.env.xxx
拿到。在
vite.config.ts
文件中获取环境变量1
2
3
4
5
6
7
8
9
10
11
12import { defineConfig } from 'vite';
import react from '@vitejs/plugin-react';
// https://vite.dev/config/
export default () => {
const platform = process.env.platform; // 获取环境变量
console.log('platform', platform);
return defineConfig({
plugins: [react()],
});
};执行
npm run dev:A
或者npm run dev:B
,可以在 启动窗口(终端) 中看到打印的platform
变量值
使用 Vite
插件
在项目根目录下创建
vite-plugin-blueimp-tmpl.ts
文件,添加下面内容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// @ts-ignore
import tmpl from 'blueimp-tmpl';
import { Plugin } from 'vite';
interface Options {
/** 匹配内容 */
match?: RegExp;
/** 匹配文件 */
test?: RegExp;
/** 模板数据 */
data: Record<string, any>;
}
/**
* 模板插件
* - 匹配文件中的 //tmpl 内容
* - 使用 blueimp-tmpl 进行模板编译 {% ... %} 中的表达式
* - 通过 o.xxx 访问 data 对象中的数据
* @example //tmpl {% o.name %}
* @example
* //tmpl {% if(o.platform == 'A') { %}
* xxx
* //tmpl {% } %}
*/
const vitePluginBlueimpTmpl = (props: Options): Plugin => {
const { match = /\/\/tmpl/g, test = /src.+\.ts(x)?/, data = {} } = props;
return {
name: 'vite-plugin-blueimp-tmpl', // 插件名称
enforce: 'pre', // 在 Vite 核心插件之前调用该插件, 打包之前运行
transform: (code: string, id: string) => {
// id 是文件路径, code 是文件内容
if (test.test(id) && code.match(match)) {
// 会将 //tmpl 替换为空
const str = code.replace(match, '');
/**
* 使用 blueimp-tmpl 进行模板编译,
* - https://www.npmjs.com/package/blueimp-tmpl#api
* - 解析 {% ... %} 中的表达式, 并将 data 对象中的数据传入模板中
*/
const tmplstr = tmpl(str)(data);
console.log(id); // 打印出被处理的文件路径
console.log(tmplstr); // 打印出处理后的文件内容
return tmplstr;
}
},
};
};
export default vitePluginBlueimpTmpl;在
vite.config.ts
文件中添加插件,并传入platform
环境变量。(需要将vitePluginBlueimpTmpl
放在插件最前面,方便拿到未编译的代码)1
2
3
4
5
6
7
8
9
10
11
12
13import { defineConfig } from 'vite';
import react from '@vitejs/plugin-react';
import vitePluginBlueimpTmpl from './vite-plugin-blueimp-tmpl';
// https://vite.dev/config/
export default () => {
const platform = process.env.platform; // 获取环境变量
console.log('platform', platform);
return defineConfig({
plugins: [vitePluginBlueimpTmpl({ data: { platform } }), react()],
});
};
使用模板语法
在
src/App.tsx
文件中添加下面内容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
28import { useEffect } from 'react';
import './App.css';
function App() {
useEffect(() => {
//tmpl {% if(o.platform == 'A') { %}
console.log('A环境');
//tmpl {% } %}
//tmpl {% if(o.platform == 'B') { %}
console.log('B环境');
//tmpl {% } %}
}, []);
return (
<>
{/* //tmpl {% if(o.platform == 'A') { %} */}
<div>我是A环境</div>
{/* //tmpl {% } %} */}
{/* //tmpl {% if(o.platform == 'B') { %} */}
<div>我是B环境</div>
{/* //tmpl {% } %} */}
</>
);
}
export default App;此时启动项目,
访问页面之后
,在启动窗口(终端)
中可以看到编译后的代码(必须访问页面后终端才会打印!!!,因为vite
是按需编译的)
部署
- 最后在
CICD
流水线上只需要添加npm run build:A
或者npm run build:B
命令,就可以实现环境切换了
本博客所有文章除特别声明外,均采用 CC BY-NC-SA 4.0 许可协议。转载请注明来源 小四先生的云!
评论