Closed czs0906 closed 3 years ago
肯定不是只有main 可用,但是我也确实遇到过,怀疑是 vite bug. @vite/client 文件晚于访问 env 就会出现这样情况。可以提供可复现的最小 demo 么.
这是我测试的demo vue-cli-vite-demo.zip
目前我们的策略是 dev 用 vite,build 还是走 Vue CLI 像这个问题可以先用 typeof 做本地兼容,保证在不改动历史逻辑的前提下先接入 vite 能力
类似👇
typeof process !== 'undefined' ? process.env.VUE_APP_ENV : 'development'
@czs0906
详细原因咱们可以一起定位一下,等有结论了可以在这个 issue 中讨论一波
我的 .env 文件全都不生效。。
@bowencool 这么一句没有上下文的抱怨无助于解决任何问题。我本人也在用这个插件,如果 .env 不生效,我干嘛自己不修复。肯定是又超出我认知的使用方式或其他问题引起的。
demo.zip 我就执行了 vue add vite
github 时代,为啥不弄个 repo ... 我下载看看你这个,但愿没有木马
demo.zip 我就执行了 vue add vite
你这个没有任何问题,vue-cli-plugin-vite 目前不支持设置 mode
,yarn vite
只会读取 .env
& .env.development
文件以及命令行里直接 VUE_APP_XXX=bbb yarn vite
的 env,你把你的 .env.dev
重命名为 .env.development
即可
详细原因咱们可以一起定位一下,等有结论了可以在这个 issue 中讨论一波
@czs0906 @screetBloom 你俩有啥新发现么 ?我这边之前看是 /@vite/client
是用来构建 runtime window.process
对象的,晚于业务代码的话,就会有问题,但是我这边项目没复现,可能是代码依赖关系不同导致的。
你这个没有任何问题,vue-cli-plugin-vite 目前不支持设置
mode
,yarn vite
只会读取.env
&.env.development
文件以及命令行里直接VUE_APP_XXX=bbb yarn vite
的 env,你把你的.env.dev
重命名为.env.development
即可
可以跟 @vue/cli 保持一样吗?因为.env.dev
里写的变量有点多,所以我们现在依赖 --mode=dev
、--mode=online
你这个没有任何问题,vue-cli-plugin-vite 目前不支持设置
mode
,yarn vite
只会读取.env
&.env.development
文件以及命令行里直接VUE_APP_XXX=bbb yarn vite
的 env,你把你的.env.dev
重命名为.env.development
即可可以跟 @vue/cli 保持一样吗?因为
.env.dev
里写的变量有点多,所以我们现在依赖--mode=dev
、--mode=online
支持,但暂时没时间。可以扩展改造下你们自己的 bin/vite,传入 —mode
详细原因咱们可以一起定位一下,等有结论了可以在这个 issue 中讨论一波
@czs0906 @screetBloom 你俩有啥新发现么 ?我这边之前看是
/@vite/client
是用来构建 runtimewindow.process
对象的,晚于业务代码的话,就会有问题,但是我这边项目没复现,可能是代码依赖关系不同导致的。
这个问题目前在我们的场景已经定位并解决,判断是 configureServer 的 res.end 阻塞了后续插件的加载 会尽快提供一个 fix 的pr修复此问题
@screetBloom hello,我这边项目也遇到了同样的问题,请问能给出大概的文件和代码行数在哪里吗?我似乎没看到跟 configureServer 相关的内容出现问题🤔。感谢🙏~
我这边对比了一下 vite 默认项目和通过这个插件生成的目标 index.html 之间的差别:
vite 生成的 index.html:
<!DOCTYPE html>
<html lang="en">
<head>
<script type="module" src="/@vite/client"></script>
<meta charset="UTF-8" />
<link rel="icon" href="/favicon.ico" />
<meta name="viewport" content="width=device-width, initial-scale=1.0" />
<title>Vite App</title>
</head>
<body>
<div id="app"></div>
<script type="module" src="/src/main.ts"></script>
</body>
</html>
vue-cli-plugin-vite 生成的 index.html:
<!DOCTYPE html>
<html lang="en">
<head>
<meta charset="utf-8">
<meta http-equiv="X-UA-Compatible" content="IE=edge">
<meta name="viewport" content="width=device-width,initial-scale=1.0">
<link rel="icon" href="/favicon.ico">
<title>Home Page</title>
</head>
<body>
<noscript>
<strong>We're sorry but Home Page doesn't work properly without JavaScript enabled. Please enable it to continue.</strong>
</noscript>
<div id="app"></div>
<!-- built files will be auto injected -->
<script type="module" src="/src/main"></script>
</body>
</html>
可以发现 vite 在 meta 标签前应该会默认插入一个 script 标签用来加载 /@vite/client
文件。而这个文件中包含了把 env 变量挂载到全局的代码。
这个 /@vite/client
文件除了在这里被引入以外,在构建 .vue 或者 .css 文件的时候,也会默认引入,这是两者都有的特性,如 App.vue 构建生成的 js 文件会有:
import { createHotContext as __vite__createHotContext } from "/@vite/client";import.meta.hot = __vite__createHotContext("/src/App.vue");var __defProp = Object.defineProperty;
var __getOwnPropDesc = Object.getOwnPropertyDescriptor;
var __decorateClass = (decorators, target, key, kind) => {
var result = kind > 1 ? void 0 : kind ? __getOwnPropDesc(target, key) : target;
for (var i = decorators.length - 1, decorator; i >= 0; i--)
if (decorator = decorators[i])
result = (kind ? decorator(target, key, result) : decorator(result)) || result;
if (kind && result)
__defProp(target, key, result);
return result;
};
因此所有在 App.vue 后面才访问的 env 环境变量,是都可以被访问成功的。 对应:
import Vue from 'vue'
import App from './App.vue'
if (process.env.VITE) {
console.log(process.env.VUE_APP_API_FOR_VITE)
} else {
console.log(process.env.VUE_APP_API_FOR_VUE_CLI)
}
new Vue({
render: (h) => h(App)
}).$mount('#app')
但如果在 App.vue 之前就被访问的 env 环境变量,在当前场景下,是无法访问成功的(因为 /@vite/client
还没有被加载)。
对应:
import Vue from 'vue'
import request from './request'
import App from './App.vue'
Vue.prototype.$request = request
new Vue({
render: (h) => h(App)
}).$mount('#app')
但在 vite 原生场景下,是可以访问成功的。(因为在全局 script 中加载了 /@vite/client
)
有解法么?大佬们,PR 欢迎
个人觉得原因应该是 vite-plugin-html-template 的中间件和 vite 本身的 indexHtml 中间件冲突了,导致一些默认的对于 html 的处理并没有应用过来。
比较简单粗暴的解决方案是直接在 vite-plugin-html-template 中加上 <script type="module" src="/@vite/client"></script>
。
更合理的解决方案可能是需要看 vite-plugin-html-template 可以怎么样应用 vite 中 indexHtml 默认的中间件,比较麻烦。。。
@ZenDay 感谢 @screetBloom 帮测试下你们的这样改可以么 ?
@ZenDay 感谢 @screetBloom 帮测试下你们的这样改可以么 ?
好的,收到,今天我也会一起看一波
v1.5.0 thanks all.
参考这个issue,用
vite
做了以下试验:.env.development
文件添加以下内容:src/main.js
文件,内容如下:if (process.env.VITE) { console.log(process.env.VUE_APP_API_FOR_VITE) } else { console.log(process.env.VUE_APP_API_FOR_VUE_CLI) }
new Vue({ render: (h) => h(App) }).$mount('#app')
src/main.js
文件,内容如下:Vue.prototype.$request = request
new Vue({ render: (h) => h(App) }).$mount('#app')