Vue CLI - 编译后将配置文件保留为外部
Posted
技术标签:
【中文标题】Vue CLI - 编译后将配置文件保留为外部【英文标题】:Vue CLI - Keep config file as external after compilation 【发布时间】:2019-05-29 00:11:19 【问题描述】:我正在使用 Vue CLI 开发一个应用程序。 此应用程序是一个 Web 界面,必须与板上的 Rest API 进行通信。
所以,因为板子会移动,板子的 IP 会随着时间的推移而变化,这取决于我在哪里。
这是我的项目当前树:
IP 配置包含在 Settings.js 文件中:
export const Settings =
// Server configuration
SERVER_IP: '127.0.0.1',
SERVER_PORT: '9000',
SERVER_PROTOCOL: 'http', // http or https
// Website configuration
DEBUG_MODE: true
;
在我的文件中,我使用以下语句导入此 IP:
import Settings from '../../Settings'
const ip = Settings.SERVER_IP;
// Do stuff
这很好用。但问题是:当 IP 发生变化时,我必须重新编译所有内容。因为Settings.js是和其他JS文件一起编译的。
所以,我想知道是否有办法让配置文件保留在 dist/ 目录中,并在执行期间由我的 JS 应用程序读取。所以我不必在每次我的应用服务器 IP 更改时重新编译所有内容。
你的帮助:)
【问题讨论】:
【参考方案1】:我对 Vue 的解决方案是基于solution for Angular。
您可以拥有与后端开发人员完全相同的环境变量。
但不同之处在于后端代码在服务器内部执行,而前端代码只不过是磁盘上的文件,您将其作为静态文件撤回,甚至没有机会在撤回之前运行和检查环境变量。
但是您的代码正在浏览器中执行。所以这是拥有环境的理想和唯一合适的地方。
但是,您必须事先准备好这个环境 - 根据您的后端环境。
计划如下:
-
您从编译中排除您的设置文件(见下文)。
您的设置文件会在您运行 Vue 应用程序之前“构建”环境。
从您的代码中,您可以使用该环境,并且您还可以在运行时更新该环境。
这是你的最终代码结构:
root_project_dir:
├─> cfg
│ └── settings.js
├─> public
│ ├── favicon.ico
│ └── index.html
├─> src
│ ├── App.vue
│ ├─> assets
│ │ └── logo.png
│ ├─> components
│ ├─> layouts
│ ├── main.js
│ ├─> plugins
│ ├─> router
│ ├─> store
│ └─> views
└── vue.config.js
创建设置文件cfg/settings.js:
/*
This file goes as an asset without any of compilation even after build process.
Thus, it can be replaced in a runtime by different file in another environment.
Example for Docker:
docker run -v ./local_cfg_dir:cfg image:tag
*/
(function(window)
window.__env = window.__env || ;
window.__env.api =
"url": "http://127.0.0.1:8000",
"timeout": 80000
;
window.__env.captcha =
"enabled": true,
"key": "Mee1ieth1IeR8aezeiwi0cai8quahy"
;
window.__env.rollbar =
"enabled": true,
"token": "zieriu1Saip5Soiquie6zoo7shae0o"
;
window.__env.debug = true;
)(this);
在 vue.config.js 的 npm run build 阶段为Webpack Copy plugin 提供复制cfg 文件的指令(您不能更改此名称):
module.exports =
chainWebpack: config =>
config.plugin("copy").tap(([pathConfigs]) =>
pathConfigs.unshift(
from: "cfg",
to: "cfg"
);
return [pathConfigs])
,
transpileDependencies: ["vuetify"]
;
检查生成的 webpack 配置并发现它已被应用(在输出的底部):
vue inspect
现在,当您构建项目时,您将在生成的目录中看到它:
dist
├─> cfg
│ └── settings.js
├─> css
│ ├── app.06b1fea6.css
│ └── chunk-1f2efba6.a298b841.css
├── favicon.ico
├─> img
│ └── logo.09e0e4e1.png
├── index.html
└─> js
├── app.8fc75c19.js
├── app.8fc75c19.js.map
└── chunk-vendors.1ab49693.js.map
因此,您可以在 public/index.html 中运行此设置,然后在同一窗口中运行应用程序:
<body>
<script src="/cfg/settings.js"></script>
<div id="app"></div>
<!-- built files will be auto injected -->
</body>
现在你的窗口中有它了:
您可以从代码中的任何位置访问此环境:
Vue.use(VueReCaptcha, siteKey: window.__env.captcha.key )
旁注:
如果您想“与 DevOps 兼容”,您需要在嵌套目录中进行设置(在我们的示例中为 cfg)。这将提供在 Kubernetes/Swarm 中进行挂载而不覆盖整个 dist 目录的能力。
【讨论】:
感谢您的指导。我没有让它正常工作,因为最后一步“从代码中的任何地方你可以到达这个环境”不起作用。我在 VSCode 中收到“属性 '__env' 在类型 'Window & typeof globalThis' 上不存在”的错误。我正在开发的应用程序是打字稿。 @kumaheiyama 但它真的存在吗?你能像上图一样在控制台中看到 window.__env 吗? 是的,我可以在控制台中看到 window.__env。难道这个解决方案不能很好地与打字稿配合使用吗?尽管使用了您的部分解决方案,但我找到了另一种解决方案。将在单独的答案中发布。 @kumaheiyama 如果您的 window.__env 存在并且包含来自 settings.js 的数据 - 解决方案 100% 有效。如果您的代码无法到达窗口的子对象 - 这是一个单独的问题,值得在 StackOveflow 上提出专门的问题。也许你需要先声明类型:(window as any).__env 很好的解释。关于 Vue 3 的注意事项 - Vue.use 不再可用;我使用了此处描述的提供/注入模式:***.com/a/63101214/1186321【参考方案2】:你可以在公共目录中创建一个config.json文件,然后在main js中你可以获取它并加载配置文件。现在你的 dist 是用这个 config.json 创建的。
fetch('/config.json').then(res => res.json()).then(config =>
.......
)
【讨论】:
非常简单实用,非常感谢!【参考方案3】:您是否事先知道完整的 IP 地址列表?如果是这样,您可以创建一个基于任何时间/位置逻辑返回正确 IP 的函数。
否则,您可以尝试将设置文件移动到公共文件夹,添加到您的 .gitignore 文件中,确保在您的 public/index.html 中引用它。它现在将位于已编译的 Vue 应用程序之外,并且可以从 Vue 内部作为全局设置变量进行访问。
所以你应该引用window.Settings
而不是import Settings from '../../Settings'
例如const ip = window.Settings.SERVER_IP;
这样您可以直接编辑设置,而无需每次都重新编译。
【讨论】:
以上是关于Vue CLI - 编译后将配置文件保留为外部的主要内容,如果未能解决你的问题,请参考以下文章