如何从 Vue 应用程序外部化和使用环境变量:
- 创建于 VueCLI3
- 部署在 Docker 容器中
- 使用 NGINX
一些细节:
该项目构建一次并部署到测试和实时环境。因此,我想外部化一些随环境变化的变量(例如要调用的 URL、域、用户名等)。带有 VUE_APP_
前缀的 .env
文件变体的经典用法无助于解决此问题,因为它们的值在构建阶段注入(inject)到代码中:一旦成为变量,它们就不再是变量。已建成。
尝试了一下,我发现了一个blog post利用 dotenv
和一些额外的配置;但我无法将其与 this VueCLI 3 official guide 中的配置放在一起。不过解决方案并不需要采用类似的方法,我只是想找到一条出路。
可能不是有用的信息,但我计划在 Config Maps 中定义这些环境变量在 Kubernetes 配置中。
最佳答案
我想我已经成功克服了这个问题。我将决议留在这里。
在
.env.development
中定义特定于环境的环境变量(用于开发目的),并将它们也添加到 Pod configuration具有相应的值。在 Vue 项目源文件夹中的某个位置添加一个
configuration.js
文件。它将充当包装器,用于确定运行时是开发(本地)还是生产(容器)。就像显示的那样 here ,但不需要导入/配置dotenv
:export default class Configuration { static get EnvConfig () { return { envKey1: '$ENV_KEY_1', envKey2: '$ENV_KEY_2' } } static value (key) { // If the key does not exist in the EnvConfig object of the class, return null if (!this.EnvConfig.hasOwnProperty(key)) { console.error(`Configuration: There is no key named "${key}". Please add it in Configuration class.`) return } // Get the value const value = this.EnvConfig[key] // If the value is null, return if (!value) { console.error(`Configuration: Value for "${key}" is not defined`) return } if (!value.startsWith('$VUE_APP_')) { // value was already replaced, it seems we are in production (containerized). return value } // value was not replaced, it seems we are in development. const envName = value.substr(1) // Remove $ and get current value from process.env const envValue = process.env[envName] if (!envValue) { console.error(`Configuration: Environment variable "${envName}" is not defined`) return } return envValue } }
创建一个
entrypoint.sh
。经过一些修改,它看起来如下:#!/bin/bash function join_by { local IFS="$1"; shift; echo "$*"; } # Find vue env vars vars=$(env | grep VUE_APP_ | awk -F = '{print "$"$1}') vars=$(join_by ',' $vars) echo "Found variables $vars" for file in /app/js/app.*; do echo "Processing $file ..."; # Use the existing JS file as template cp $file $file.tmpl envsubst "$vars" < $file.tmpl > $file rm $file.tmpl done nginx -g 'daemon off;'
在您的
Dockerfile
中,添加一个CMD
,用于在期间运行上面的entrypoint.sh
脚本作为引导脚本容器创建。这样,每次启动容器时,它都会从 Pod 配置中获取环境变量,并将其注入(inject)到步骤 2 中所示的 Configuration 类中。# build stage FROM node:lts-alpine as build-stage # make the 'app' folder the current working directory WORKDIR /app # Copy package*.json and install dependencies in a separaate step to enable caching COPY package*.json ./ RUN npm install # copy project files and folders to the current working directory COPY ./ . # install dependencies and build app for production with minification RUN npm run build # Production stage FROM nginx as production-stage RUN mkdir /app # copy 'dist' content from the previous stage i.e. build COPY --from=build-stage /app/dist /app # copy nginx configuration COPY nginx.conf /etc/nginx/nginx.conf # Copy the bootstrapping script to inject environment-specific values and pass it as argument current to entrypoint COPY entrypoint.sh entrypoint.sh # Make the file executable RUN chmod +x ./entrypoint.sh CMD ["./entrypoint.sh"]
最后,使用我们的包装器配置类(如 Configuration.value('envKey1')
)代替 process.env
。瞧!
关于docker - VueCLI3 应用程序 (nginx/docker) 使用环境特定变量,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/57807248/