需求描述
- 前段时间有这样的一个需求:
- 笔者有一个项目,在启动或者打包的时候
- 需要根据一些实际情况,去选择展示那个视图
- 就是我们在项目启动或者打包的时候,需要注入一个全局变量(保存在.env.development或.env.production文件中)通过命令行npm run dev的方式
- 一般来说,vue-router就可以实现这个需求
- 但是,某些情况下,这个需求不太适合用vue-router去实现
- 所以,笔者分享这篇文章,给到一个思路和示例
- 完整代码附上,在文末的github上
效果图
第一步,在启动项目的时候命令行传参,修改package.json
- 实际上,类似的功能效果笔者之前分享过一篇文章
- 《效能工具之node在项目中的应用(二)《以开发环境多后端服务切换问题为例》》
- 那个是使用的 inquirer 的npm包
- 相比较而言,本篇文章,不使用包
- 即用Vue和Vite自带功能的实现之
- 首先,我们去自定义脚本
"de": "node ./choose.js",
实现启动或者打包 - (这里删除了默认的
npm run dev
脚本即:"dev": "vite"
,),如下:
{
"name": "build",
"private": true,
"version": "0.0.0",
"type": "module",
"scripts": {
"de": "node ./choose.js",
"pr": "node ./choose.js"
},
"dependencies": { ... },
"devDependencies": { ... }
}
- 也就是说,当执行
npm run de
这个脚本的时候,会驱动node去执行choose.js
这个文件脚本js文件 - 当然了,这个文件在和package.json在同一目录下(根目录)
第二步 编写脚本choose.js文件
想要编写好一个choose.js文件,我们需要掌握以下的前置知识
前置知识child\_process
- 说到
child_process
模块,就不得不提process
模块 - 大家类比一下理解即可
- 前者是 Node.js 中的全局对象,这个对象提供了与当前 Node.js 进程进行交互的各种信息和控制能力。
- 后者是一个 Node.js 内置模块,该模块允许 Node.js 创建新的子进程,实现多进程编程
- 所以,我们可以使用child\_process来启动一个vite项目
即为:
- 假设此文件和vite项目在同一根目录,叫做c.js
- 那么,我们执行
node c.js
就可以把同级目录的vite项目跑起来了 - 相当于执行了,
npm run dev
- 因为前者也是驱动vite运行项目的(
"dev": "vite",
) - 默认
package.json
文件如下:
"scripts": {
"start": "npm run dev",
"dev": "vite",
"build:prod": "vite build",
"build:stage": "vite build --mode staging",
"preview": "vite preview",
}
我们直接改动手动地,通过node的child\_process模块驱动vite项目跑起来
// c.js
import { execSync } from 'child_process'
// 启动开发环境
execSync(`vite --host`, { stdio: 'inherit' });
// 启动生产环境
execSync(`vite build`, { stdio: 'inherit' });
execSync可以执行外部命令,如执行vite的命令
脚本choose.js文件
- 有了上述前置知识,我们就可以编写出以下脚本
- 拿到命令行输入的参数比如
- npm run de -- 1 或者 npm run de -- 2 或者 npm run de -- 3
- 根据传进来的 1 或者 2 或者 3
- 去选择对应的视图单位
- 注意,这里要把命令行传递进来参数,存一份到.env.development文件中(开发环境,生产环境.env.production)
- 我们直接写入到文件中,这样在任何一个.vue文件中都可以访问到这个命令行参数变量了
- 比如:fs.writeFileSync('./.env.development',
VITE_UNIT = ${params}
) - 注意,命令行传参的格式,否则Vite接受不到
npm run de -- xxx
,才能接收到这个xxx
参数(let params = process.argv.at(-1)
)npm run de -- xxx
,才能接收到这个xxx
参数(let params = process.argv.at(-1)
)npm run de -- xxx
,才能接收到这个xxx
参数(let params = process.argv.at(-1)
)
import process from 'process'
import { execSync } from 'child_process'
import fs from 'fs'
// 假设校验只有三个单元视图
const checkArr = ['1', '2', '3']
// 获取命令行参数
let params = process.argv.at(-1)
if (!checkArr.includes(params)) {
throw new Error('参数不对') // process.exit(1); // 遇到错误退出
}
if (process.env.npm_lifecycle_event == 'de') {
fs.writeFileSync('./.env.development', `VITE_UNIT = ${params}`)
execSync(`vite --host`, { stdio: 'inherit' });
} else if (process.env.npm_lifecycle_event == 'pr') {
fs.writeFileSync('./.env.production', `VITE_UNIT = ${params}`)
execSync(`vite build`, { stdio: 'inherit' });
}
.env.development和.env.production文件
- .env.development和.env.production都是环境变量文件
- 一个开发,一个生产
- 这里直接存放对应值就行了
- 如:VITE\_UNIT = 1
- 我们通过fs模块,直接往这个文件中写入内容:
fs.writeFileSync('./.env.development', 'VITE_UNIT = ${params}')
.env.development
和.env.production
有内容后,- 这样的话,就可以在任意的.vue文件中使用这个变量了
访问vite环境变量文件中的变量数据
直接:import.meta.env.VITE_UNIT
,如下:
<template>
<div>{{ unit }}</div>
</template>
<script setup>
let unit = import.meta.env.VITE_UNIT;
</script>
- 这里,笔者去把一些用到的html文件存放在
public文件夹
下unitView文件夹
下- 如下图
- 这样的话,就可以启动的时候,根据存放在
.env.development
文件中的变量VITE_UNIT
使用对应视图了 - 比如,当我启动项目的时候,执行命令是:
npm run de -- 2
- 代表着开发环境,我要查看视图2
- 这个时候,choose.js脚本会把传递的参数2写入到.env.development文件中,如下图:
- 最后,就可以通过
import.meta.env.VITE_UNIT
去动态使用了
<template>
<div>
<div v-html="htmlContent"></div>
</div>
</template>
<script setup>
import { ref, onMounted } from "vue";
// 获取传递进来的unit参数
let unit = import.meta.env.VITE_UNIT;
// 定义一个响应式变量来存储HTML内容
const htmlContent = ref("");
onMounted(async () => {
try {
// 使用fetch API读取publick文件架下unitView中的html视图文件
const response = await fetch(`/unitView/${unit}.html`);
if (response.ok) {
// 将响应内容转换为文本
const html = await response.text();
// 赋值响应式变量
htmlContent.value = html;
} else {
console.error("error");
}
} catch (error) {
console.error("Error fetching HTML file:", error);
}
});
</script>
这样的话,就可以实现相应效果了
补充:使用http-server本地访问打包好的dist文件夹
- 我们打包后的dist文件夹的入口文件,不能双击打开查看项目
- 关于Vite打包dist后的index.html双击无法访问参考文章
- vite 打包本地文件无法直接打开, file 类型 URL 引发跨域等问题探讨
- https://blog.csdn.net/qq_34727886/article/details/136163494
- 这个时候,我们可以使用
http-server
快速启动一个服务(不用部署在服务器上)
// 打开cmd,全局安装http-server
npm install -g http-server
// 进入指定打包的目录
cd dist
// cmd中输入启动服务
http-server
如下图:
这样的话,我们在本地,也能直接查看到打包好的dist文件夹的内容效果
完整代码
- 在笔者的github仓库:https://github.com/shuirongshuifu/build-choose
- 建议大家pull下项目,跑起来操作一下,更好理解
**粗体** _斜体_ [链接](http://example.com) `代码` - 列表 > 引用
。你还可以使用@
来通知其他用户。