VueJS 和 Webpack:构建项目无法访问 ENV var

Posted

技术标签:

【中文标题】VueJS 和 Webpack:构建项目无法访问 ENV var【英文标题】:VueJS & Webpack: ENV var unaccessible from built project 【发布时间】:2018-10-28 17:34:54 【问题描述】:

我正在开发一个带有 vuejs 前端和 nodejs 后端的应用程序。我的前端向后端发出 API https 请求。我已经用 vue-cli 和 webpack 开始了我的项目。 我需要从 env 变量 (BACKEND_URL) 获取后端 API url。 由于我使用的是 webpack,因此我将此行添加到 config/prod.env.js :

module.exports = 
  NODE_ENV: '"production"',
 -> BACKEND_URL: JSON.stringify(process.env.BACKEND_URL)

它使用 webpack-dev-server 在开发模式下完美运行。我通过 docker-compose 文件传递​​了 env var:

environment:
            - BACKEND_URL=https://whatever:3000

但是当我运行构建时,我使用 nginx 来提供静态文件(但问题与使用 Visual Studio Code Live Server Extension 相同)。我以与以前相同的方式发送 BACKEND_URL env var。现在的问题是 process.env.BACKEND_URL 在应用程序中未定义(但在容器中定义)!所以我不能进行后端http调用:( 我正在努力寻找问题,请不要对回复无礼。谢谢

【问题讨论】:

我认为您需要将 env 变量保留在 .env 文件中。您可以拥有 url.env ,其中包含内容 BACKEND_URL=https://whatever:3000 ,然后在 docker-compose 中添加一行 env_file: -url.env 。看看是否有帮助。 docker-compose 的格式不太合适。你可能知道它是怎么回事。 感谢您的反馈。问题不存在:当我使用 docker exec /bin/bash 和 printenv 进入容器时,BACKEND_URL 就在那里。问题是webpack编译后的项目无法再读取env var。 【参考方案1】:

在构建期间它们没有被“翻译”,这就是发生在你身上的事情。在节点环境中,当您请求process.env 时,它将显示系统中所有可用的环境变量,这是真的。但是 Web 应用程序在执行时无权访问process.env。您需要一种在构建期间翻译它们的方法。

要实现这一点,您必须使用DefinePlugin。它在构建期间翻译任何东西,并在其他东西所在的位置写入一个神奇的字符串。

用你自己的例子:

module.exports = 
  NODE_ENV: '"production"',
  BACKEND_URL: JSON.stringify(process.env.BACKEND_URL)

如果你在构建期间这样做,如果没有 DefinePlugin,webpack 将不知道如何处理它,它将是一个简单的字符串。

如果你使用DefinePlugin:

new webpack.DefinePlugin(
  "process.env.BACKEND_URL": JSON.stringify(process.env.BACKEND_URL)
);

通过这样做,您允许 webpack 在构建期间翻译它。

【讨论】:

谢谢,您的回答帮助我了解发生了什么。实际上,我的语法与您建议的完全相同。据我了解,通过执行此 webpack 只会在构建期间获取 env var 值。因此,如果 BACKEND_URL 发生更改,我无法让前端知道,只能重新构建我的应用程序以将更改考虑在内。如果我的应用程序可以在我需要向后端发出的每个请求之前读取 env var,我会很高兴。 不,不可能,它们运行在不同的“环境”中,所以在 webpack 上它无法获取 process.env【参考方案2】:

试一试:https://www.brandonbarnett.io/blog/2018/05/accessing-environment-variables-from-a-webpack-bundle-in-a-docker-container/

如果我正确理解了您的问题,那么您正在使用 nginx 提供 webpack 包,并尝试从该包中访问环境变量。

不幸的是,它并不完全那样工作。您的 JS 文件无法访问环境,因为它是已交付给客户端的资源。我提出了一个解决方案,该解决方案还将这些环境变量与捆绑包一起提供在一个单独的 JS 文件中,该文件在容器启动时创建。

【讨论】:

【参考方案3】:

来自 VueJS 文档:https://cli.vuejs.org/guide/mode-and-env.html

在客户端代码中使用环境变量

只有以VUE_APP_ 开头的变量才会使用 webpack.DefinePlugin 静态嵌入到客户端包中。您可以在应用程序代码中访问它们:

console.log(process.env.VUE_APP_SECRET)

在构建过程中,process.env.VUE_APP_SECRET 将被替换为相应的值。在 VUE_APP_SECRET=secret 的情况下,将替换为“secret”。


因此,在您的情况下,以下内容应该可以解决问题。我曾经在我的项目中遇到过同样的问题,我从 vue/cli 和 vue create project ... 开始。

VUE_APP_BACKEND_URL=https://whatever:3000

【讨论】:

与问题完全无关 想解释一下这与问题“完全无关”吗? @Z 因为这个问题是经典的“我无法在运行时从静态 html 访问 env 变量”:***.com/questions/53010064/…

以上是关于VueJS 和 Webpack:构建项目无法访问 ENV var的主要内容,如果未能解决你的问题,请参考以下文章

webpack构建项目连接本机IP仍无法访问问题

VueJS + Webpack 开发服务器无法热重载 url 子路径

构建后无法导入和使用vuejs单文件组件

vuejs和webpack项目(VueComponent)初尝试——瀑布流组件

无法使用 vuejs2 和 webpack 嵌入自定义字体

我无法通过 symfony/webpack-encore 使用 Jest 和 Vuejs 运行测试