使用环境变量与Vue.js

205

我一直在阅读官方文档,但无法找到有关环境变量的任何信息。 显然有一些社区项目支持环境变量,但这可能对我来说太过复杂了。 因此,我想知道是否有一些简单的开箱即用的东西可以在使用Vue CLI创建的项目中本地工作。

例如,我可以看到如果我执行以下操作,则正确的环境将被打印出来,这意味着已经设置好了?

mounted() {
  console.log(process.env.ROOT_API)
}

我对环境变量和Node还是有些陌生。

提醒一下,我正在使用Vue CLI 3.0 beta版本。


你正在使用哪个vue-cli模板?如果是Webpack,请参考http://vuejs-templates.github.io/webpack/env.html。 - Phil
另外,你的问题并不清楚。你有实际的问题吗? - Phil
1
如果你正在使用Webpack,process.env可以用来获取环境变量。 - Julian Paolo Dayag
我使用 vue create my-app 创建了我的项目,但根据您发布的文档,env 变量无法正常工作。@Phil - Edgar Quintero
6
你必须在变量前加上 'VUE_APP_'。参考链接:https://cli.vuejs.org/zh/guide/mode-and-env.html#example-staging-mode - Benjamin Poignant
14个回答

303

Vue.js 和 Webpack

如果您使用 Vue CLI 中的 Webpack 模板(默认配置),您可以创建并将环境变量添加到 .env 文件中。

这些变量将自动在项目中以 process.env.variableName 的形式访问。加载的变量也可供所有 vue-cli-service 命令、插件和依赖项使用。

您有几个选择,以下内容摘自环境变量和模式文档

.env                # loaded in all cases
.env.local          # loaded in all cases, ignored by git
.env.[mode]         # only loaded in specified mode
.env.[mode].local   # only loaded in specified mode, ignored by git

你的.env文件应该像这样:

VUE_APP_MY_ENV_VARIABLE=value
VUE_APP_ANOTHER_VARIABLE=value

如下评论所述:如果您使用的是Vue cli 3,则只会加载以VUE_APP_开头的变量。

如果当前正在运行,请不要忘记重新启动serve

使用Vite的Vue.js

Vite在特殊的import.meta.env对象上公开以VITE_开头的环境变量。

您的.env文件应该像这样:

VITE_API_ENDPOINT=value
VITE_API_KEY=value

这些变量可在Vue.js组件或JavaScript文件中通过import.meta.env.VITE_API_ENDPOINTimport.meta.env.VITE_API_KEY访问。

提示:如果你的开发服务器正在运行,请记得在.env文件中更改或添加变量时重新启动它。

欲了解更多信息,请参阅Vite文档中有关环境变量的章节


47
需要注意的是:只有以VUE_APP_开头的变量才会被webpack.DefinePlugin静态地嵌入到客户端捆绑包中。 - Edgar Quintero
41
只有以 VUE_APP_ 开头的变量才会被静态嵌入,这意味着如果你希望在客户端代码中访问环境变量,那么必须在 .env 文件中使用 VUE_APP_ 作为键的前缀。 - Yilmaz Guleryuz
36
如果服务正在运行,请不要忘记重新启动它。 - ali6p
5
需要注意的是:我们需要在所有的环境变量前面加上“VUE_APP_”,除了“NODE_ENV”和“BASE_URL”。 - palaѕн
1
正如其他答案所指出的那样,请确保将您的.env文件放置在项目的根目录下,作为package.json的同级文件(例如不要放在src文件夹中)。 - Partik
显示剩余10条评论

122

如果您使用的是Vue cli 3,则只有以VUE_APP_开头的变量才会被加载。

在根目录创建一个.env文件:

VUE_APP_ENV_VARIABLE=value

而且,如果它正在运行,则需要重新启动serve以便加载新的环境变量。

通过这种方式,您将能够在项目中(.js和.vue文件)使用process.env.VUE_APP_ENV_VARIABLE。

更新

根据@ali6p的说法,在Vue Cli 3中不需要安装dotenv依赖项。


1
如果你还没有安装dotenv,那么你需要先安装它,然后就可以像这样使用它。 - Pedro Silva
2
如果项目是使用Vue CLI 3创建的,则无需使用dotenv来获取环境变量。也许您想将此情况添加到您的答案中。 - ali6p
1
是的。在CLI 3之后。 - ali6p
它应该位于项目的根目录,就像package.json一样。 - Pedro Silva
重启服务器也有帮助。在哪里记录了添加 VUE_APP 部分的信息? - CodeConnoisseur
显示剩余4条评论

101
  1. 在根目录下(与 package.json 同级)创建两个文件.env.env.production
  2. 在这些文件中添加以 VUE_APP_ 为前缀的变量,例如: VUE_APP_WHATEVERYOUWANT
  3. serve 使用 .env 文件,而 build 使用 .env.production 文件
  4. 在您的组件(vue 或 js)中使用process.env.VUE_APP_WHATEVERYOUWANT来调用该值
  5. 如果当前正在运行,请不要忘记重新启动serve
  6. 清除浏览器缓存

确保您正在使用 vue-cli 版本 3 或以上

更多信息请参见:https://cli.vuejs.org/guide/mode-and-env.html


4
这应该是这个非常棘手问题唯一的答案。谢谢!指出根目录在哪里以及第5点和第6点的区别使它与其他答案不同。此外,您需要安装dotenv:npm install dotenv,我想。干得好。 - HWJ
1
总是忘记重启服务器! - christostsang
1
@Nguaial 我的意思是重新运行serve脚本 npm run serve ... 或者根据您的设置使用不同的cmd。 - ali6p
这是最好的答案,说实话。我甚至不需要像其他人建议的那样使用 .env.development,只需将 .env 作为我的开发配置文件即可。 - Narxx
谢谢。这个方法也适用于Vue 4。例如,我还有一个.env.test文件来为我们的测试机构建我的Vue应用程序。需要使用npm run build -- --mode test进行构建,然后它会使用正确的文件(我认为是.env + .env.test的组合)。此外:如果您想在模板中使用环境变量,当然需要将它们放入数据属性中,如data(){ return { ENV: process.env } },然后在模板中使用它们,例如This is my env: {{ ENV.VUE_APP_WHATEVERYOUWANT }}。或者还有其他更好的方法吗? - phil
显示剩余3条评论

46

在项目的根目录中创建您的环境文件:

  • .env
  • .env.someEnvironment1
  • .env.SomeEnvironment2

要加载这些配置,请通过mode指定环境,例如:

npm run serve --mode development //default mode
npm run serve --mode someEnvironment1

在您的env文件中,您只需声明配置为键值对,但如果您使用的是Vue 3,则必须VUE_APP_为前缀:

在您的.env文件中:

VUE_APP_TITLE=This will get overwritten if more specific available

.env.someEnvironment1:

VUE_APP_TITLE=My App (someEnvironment1)

然后您可以通过以下方式在任何组件中使用:

myComponent.vue:

<template>
  <div> 
    {{title}}
  </div>
</template>

<script>
export default {
  name: "MyComponent",
  data() {
    return {
      title: process.env.VUE_APP_TITLE
    };
  }
};
</script>

如果您没有指定mode,则运行应用程序将显示“This will get...”,但是如果您将someEnvironment1作为mode指定,那么您将从那里获取标题。

您可以通过在文件名后附加.local来创建在git上“隐藏”的配置文件:.env.someEnvironment1.local——当您有机密信息时非常有用。

阅读文档以获取更多信息。


这是唯一对我有效的答案。请使用完整的变量名...title: process.env.VUE_APP_API_URL - Nassim
一样的,这是我唯一能让它工作的方法。一旦我添加了文件,在我的项目目录根目录下运行npm run serve之后,我就能引用env变量了。 - R007
这很棒,需要记住的一件事是,“build”模式与webpack的NODE_ENV模式不同,因此您可以使用它来设置诸如staging之类的模式,甚至是您应用程序的不同“版本”或“部署”。https://medium.com/rangle-io/custom-build-modes-with-vue-cli-3-16ab208b4bc3 - sMyles

12

一个问题困扰着我,就是我在使用VueJS的webpack-simple安装时,并没有发现环境变量配置文件夹。因此,我无法编辑env.test、development和production.js配置文件。即使创建了它们也没有帮助。

其他答案对我来说不够详细,所以我只好"摸索"webpack.config.js。下面的解决方案效果很好。

要使环境变量起作用,webpack.config.js 应该在底部添加以下内容:

if (process.env.NODE_ENV === 'production') {
  module.exports.devtool = '#source-map'
  // http://vue-loader.vuejs.org/en/workflow/production.html
  module.exports.plugins = (module.exports.plugins || []).concat([
    new webpack.DefinePlugin({
      'process.env': {
        NODE_ENV: '"production"'
      }
    }),
    new webpack.optimize.UglifyJsPlugin({
      sourceMap: true,
      compress: {
        warnings: false
      }
    }),
    new webpack.LoaderOptionsPlugin({
      minimize: true
    })
  ])
}

基于上述内容,在生产环境中,您将能够获取NODE_ENV变量。

mounted() {
  console.log(process.env.NODE_ENV)
}

现在可能有更好的方法来完成这个任务,但是如果你想在开发中使用环境变量,你可以按照以下步骤进行:

if (process.env.NODE_ENV === 'development') {

  module.exports.plugins = (module.exports.plugins || []).concat([
    new webpack.DefinePlugin({
      'process.env': {
        NODE_ENV: '"development"'
      }
    })
  ]);

} 

现在,如果你想要添加其他变量,那么就像这样简单:

if (process.env.NODE_ENV === 'development') {

  module.exports.plugins = (module.exports.plugins || []).concat([
    new webpack.DefinePlugin({
      'process.env': {
        NODE_ENV: '"development"',
        ENDPOINT: '"http://localhost:3000"',
        FOO: "'BAR'"
      }
    })
  ]);
}

我应该指出你似乎需要使用“''”双引号,但不清楚原因。

在开发过程中,我现在可以访问这些环境变量:

mounted() {
  console.log(process.env.ENDPOINT)
  console.log(process.env.FOO)
}

这里是完整的webpack.config.js文件,为了提供一些背景。

var path = require('path')
var webpack = require('webpack')

module.exports = {
  entry: './src/main.js',
  output: {
    path: path.resolve(__dirname, './dist'),
    publicPath: '/dist/',
    filename: 'build.js'
  },
  module: {
    rules: [
      {
        test: /\.css$/,
        use: [
          'vue-style-loader',
          'css-loader'
        ],
      },      {
        test: /\.vue$/,
        loader: 'vue-loader',
        options: {
          loaders: {
          }
          // other vue-loader options go here
        }
      },
      {
        test: /\.js$/,
        loader: 'babel-loader',
        exclude: /node_modules/
      },
      {
        test: /\.(png|jpg|gif|svg)$/,
        loader: 'file-loader',
        options: {
          name: '[name].[ext]?[hash]'
        }
      }
    ]
  },
  resolve: {
    alias: {
      'vue$': 'vue/dist/vue.esm.js'
    },
    extensions: ['*', '.js', '.vue', '.json']
  },
  devServer: {
    historyApiFallback: true,
    noInfo: true,
    overlay: true
  },
  performance: {
    hints: false
  },
  devtool: '#eval-source-map'
}

if (process.env.NODE_ENV === 'production') {
  module.exports.devtool = '#source-map'
  // http://vue-loader.vuejs.org/en/workflow/production.html
  module.exports.plugins = (module.exports.plugins || []).concat([
    new webpack.DefinePlugin({
      'process.env': {
        NODE_ENV: '"production"'
      }
    }),
    new webpack.optimize.UglifyJsPlugin({
      sourceMap: true,
      compress: {
        warnings: false
      }
    }),
    new webpack.LoaderOptionsPlugin({
      minimize: true
    })
  ])
}

if (process.env.NODE_ENV === 'development') {

  module.exports.plugins = (module.exports.plugins || []).concat([
    new webpack.DefinePlugin({
      'process.env': {
        NODE_ENV: '"development"',
        ENDPOINT: '"http://localhost:3000"',
        FOO: "'BAR'"
      }
    })
  ]);

}

我正在将未来的项目转向使用Vue CLI 3,但是在使用webpack-simple安装程序构建的应用程序中遇到了相同的问题。我在这里扩展了您的逻辑,并创建了一个“else”条件,在其中将process.env.NODE_ENV值传递给DefinePlugin参数。 - slowFooMovement
Aaron McKeehan,我按照你的建议对我的webpack.config进行了相同的添加。但是,我该如何在我的Vue组件中使用我为开发而编写的变量来进行请求开始呢? - Nodira
例如,我添加了以下代码: `if (process.env.NODE_ENV === 'development') { module.exports.plugins = (module.exports.plugins || []).concat([ new webpack.DefinePlugin({ 'process.env': { NODE_ENV: '"development"', DEBUG_MODE: true, ROOT_API: '"http://localhost:8080/"' } }) ]);} 在Setting.vue中,我想在我的post请求中添加ROOT_API变量:axios .post(ENVIRONMENT_VARIABLE_HERE??/api/users/me/change-password`){...}。请给我建议,我不是很擅长webpack的工作原理。 - Nodira
对我来说关键是在 .env 文件和 file.vue 文件中都加上 VUE_APP_ 前缀。 - fred
请注意,由于插件执行直接文本替换,因此传递给它的值必须包括字符串本身内部的实际引号。通常,这可以通过使用备用引号(例如'"production"')或使用JSON.stringify('production')来实现。https://webpack.js.org/plugins/define-plugin/#usage - Steven Almeroth

5
这是我编辑 vue.config.js 的方法,让我能够将NODE_ENV暴露给前端(我使用Vue-CLI):

vue.config.js

const webpack = require('webpack');

// options: https://github.com/vuejs/vue-cli/blob/dev/docs/config.md
module.exports = {
    // default baseUrl of '/' won't resolve properly when app js is being served from non-root location
    baseUrl: './',
    outputDir: 'dist',
    configureWebpack: {
        plugins: [
            new webpack.DefinePlugin({
                // allow access to process.env from within the vue app
                'process.env': {
                    NODE_ENV: JSON.stringify(process.env.NODE_ENV)
                }
            })
        ]
    }
};

1
这正是我长期以来一直在寻找的东西。它简单易懂,可以在启动时从命令行向变量中传递值,并且稍后可以在应用程序中使用,无需额外的库和困难。非常感谢!如要与我相同:
  1. CUSTOM_VAR:JSON.stringify(process.env.CUSTOM_VAR)||"默认值"
  2. 在运行时设置变量值:set CUSTOM_VAR=value && npm run serve
  3. 在应用程序中使用变量:console.log(process.env.CUSTOM_VAR)
- Alex Shink

3
在vue-cli的第三个版本中:
有三个选项可以使用.env文件: 你可以使用.env 或者:
- .env.test - .env.development - .env.production
你可以通过在/node_modules/@vue/cli-service/lib/util/resolveClientEnv.js:prefixRE中使用前缀正则表达式 /^/ 而不是 /^VUE_APP_/ 来使用自定义.env变量。
当然,这并不推荐,因为在开发不同模式(如测试、开发和生产)的.env文件时,每次运行'npm install..'都会被覆盖。

2
除了之前的回答,如果您想在sass中访问VUE_APP_*环境变量(无论是vue组件的sass部分还是scss文件),则可以将以下内容添加到您的vue.config.js中(如果没有,则可能需要创建一个): "最初的回答"
let sav = "";
for (let e in process.env) {
    if (/VUE_APP_/i.test(e)) {
        sav += `$${e}: "${process.env[e]}";`;
    }
}

module.exports = {
    css: {
        loaderOptions: {
            sass: {
                data: sav,
            },
        },
    },
}

在处理之前,似乎将字符串“sav”添加到每个sass文件中,这对于变量来说是可以的。您还可以在此阶段导入mixin,以使它们可用于每个vue组件的sass部分。

然后,您可以在vue文件的sass部分中使用这些变量:

<style lang="scss">
.MyDiv {
    margin: 1em 0 0 0;
    background-image: url($VUE_APP_CDN+"/MyImg.png");
}
</style>

or in a .scss file:

.MyDiv {
    margin: 1em 0 0 0;
    background-image: url($VUE_APP_CDN+"/MyImg.png");
}

来自https://www.matt-helps.com/post/expose-env-variables-vue-cli-sass/

Original Answer翻译成“最初的回答”:


这对于Vue组件中的scss文件可以正常工作。但是我正在使用Vuetify和其variables.scss文件(https://vuetifyjs.com/en/customization/sass-variables/),但它却无法工作。我得到了SassError:未定义变量。有什么想法吗? - dari0h
请注意,这完全取决于您使用的加载器版本。例如,在v8中,您需要使用prependData而不是data - sMyles
如果你遇到问题,请确保使用 scss 而不是 sass(或者两者都添加)@dari0h - sMyles

1
如果你正在使用 Laravel、Vue 和 Webpack,你可以尝试在 .env 变量上添加前缀 MIX_

i.e.:

MIX_SPACESHIP="U.S.S. Enterprise"

然后通过以下方式将其引入到Vue组件中:

process.env.MIX_SPACESHIP

1
重要提示(在Vue 4中,很可能在Vue 3+中也是如此!):我设置了VUE_APP_VAR,但无法通过控制台记录进程和打开env对象来查看它。但我可以通过记录或引用process.env.VUE_APP_VAR来查看它。我不确定原因是什么,但请注意您必须直接访问变量!

2
在我的情况下,我遇到了相同的问题,原因是我将.env文件放置在/src文件夹中而不是项目根目录中! - Christian Casutt

网页内容由stack overflow 提供, 点击上面的
可以查看英文原文,
原文链接