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.jsnpm 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 - 编译后将配置文件保留为外部的主要内容,如果未能解决你的问题,请参考以下文章

vue-cli3.0读取外部化配置文件来修改公共路径

vue-cli3抽离配置文件

vue-cli3 vue.config.js配置

vue使用一些外部插件及样式的配置

安装@vue/cli之后,'vue' 不是内部或外部命令,也不是可运行的程序

Vue CLI多环境配置