【问题标题】:How to pass env variables to nuxt in production?如何在生产中将环境变量传递给 nuxt?
【发布时间】:2019-05-28 08:47:27
【问题描述】:

nuxt.config.js

modules: [
    '@nuxtjs/dotenv'
  ],

服务器/index.js

const express = require('express')
const consola = require('consola')
const { Nuxt, Builder } = require('nuxt')
const app = express()
const host = process.env.HOST || '0.0.0.0'
const port = 8080
app.set('port', port)
// Import and Set Nuxt.js options
let config = require('../nuxt.config.js')
config.dev = !(process.env.NODE_ENV === 'production')

const Storage = require('@google-cloud/storage')
const dotenv = require('dotenv')


async function getEnv() {
  if (config.dev) {
    dotenv.config({ path: '.env' })
    console.log('Environment local .env file loaded.')
    console.log(process.env.LOCALE)

    return
  }

  try {

    const bucketName = 'env-var'

    const dotEnvSourcePath = `.env`
    const dotEnvDestinationPath = `/tmp/${dotEnvSourcePath}`
    const storage = new Storage({})

    await storage
      .bucket(bucketName)
      .file(dotEnvSourcePath)

      .download({ destination: dotEnvDestinationPath })
    console.log(
      `gs://${bucketName}/${dotEnvSourcePath} downloaded to ${dotEnvDestinationPath}.`
    )


    dotenv.config({ path: dotEnvDestinationPath })


  } catch (err) {
    console.error('ERROR:', err)
  }
}

async function afterEnvProcess() {
  // Init Nuxt.js
  const nuxt = new Nuxt(config)

  // Build only in dev mode
  if (config.dev) {
    const builder = new Builder(nuxt)
    await builder.build()
  }

  // Give nuxt middleware to express
  app.use(nuxt.render)

  // Listen the server
  app.listen(port, host)
  consola.ready({
    message: `Server listening on http://${host}:${port}`,
    badge: true
  })
  const fs = require('fs')

  const dotEnvExists = fs.existsSync('.env')
}

getEnv()
  .then(r => afterEnvProcess())
  .catch(e => console.log(e))

在生产环境中运行应用程序时,我将process.env.<variable> 的值设为undefined。在开发中运行时,我得到了正确的值。似乎 env 变量没有被传递给 nuxt env 属性。

编辑 1: 当我使用 process.env 控制台记录环境变量时,我可以在谷歌云日志中看到正确的值。但同时这些控制台日志语句在浏览器控制台中显示未定义

【问题讨论】:

  • 考虑选择一个答案:)

标签: vue.js nuxt.js


【解决方案1】:

大多数人使用dotenv 包,但我不喜欢这个解决方案,因为它增加了管理与生产和开发不同的额外文件的需要,同时您可以自动化 webpack 以使用正确的值而无需额外的麻烦。

更简单的方法:

//package.json
  "scripts": {
    "dev": "NODE_ENV=dev nuxt"
  }
//nuxt.config.js
  env: {
    baseUrl:
      process.env.NODE_ENV === 'dev'
        ? 'http://localhost:3000'
        : 'https://my-domain.com'
  }

这将允许您通过调用process.env.baseUrl 来使用正确的值。请注意,您可以使用 console.log(process.env.baseUrl) 验证这一点,但不能使用 console.log(process.env),至少在 Chrome 中是这样。

【讨论】:

  • 请注意,您不需要在使用 dotenv 的其他环境中拥有 .env 文件,因为如果环境变量已经存在,它会获取它们。
  • 最佳解决方案。但请注意,您不需要 === 'dev'per 每个变量。使用它来节省空间:env: process.env.NODE_ENV === 'dev' ? { A: "1", B: "2" } : { A: "3", B: "4" },
【解决方案2】:

nuxt.config.env 明白了!

对于未来的 Google 员工,包括我自己,有一个恼人的问题,nuxt.config.js 没有很好地解释。

process.env.SOMETHING 在构建过程中被替换为 config.env.SOMETHING 值

在构建之前

    if (process.env.SOMETHING == 'testing123')

构建后

    if ('testing123' == 'testing123')

这也不适用于对象!只有文字。

// This won't work for you!
mounted() {
  console.log('process.env', process.env)
}

https://nuxtjs.org/api/configuration-env/

【讨论】:

    【解决方案3】:

    正如@Aldarund 之前所说:环境变量是在构建时设置的,而不是在运行时设置的。

    从 Nuxt.js 2.13+ 开始,您可以使用运行时配置和内置的 dotenv 支持。这提供了更好的安全性和更快的开发速度。

    要在运行时将环境变量用作 axios baseUrl,您可以使用:

    publicRuntimeConfig: {
        axios: {
          baseURL: process.env.BASE_URL
        }
      },
    

    有关运行时配置的更多信息:https://nuxtjs.org/blog/moving-from-nuxtjs-dotenv-to-runtime-config/

    关于 axios 运行时配置的更多信息:https://axios.nuxtjs.org/options

    【讨论】:

      【解决方案4】:

      在构建时捆绑的环境变量。所以你需要在为生产构建时设置它们

      它们将在运行时在您的 server/index.js 中可用,但是当 nuxt build dist 时,它将 process.env.* 替换为在构建时传递的值,所以当你开始时传递什么并不重要这个变量的服务器。

      【讨论】:

      • 当我执行 console.log 时,我可以在谷歌云日志中正确看到值,但在浏览器控制台中我看到未定义。这是否意味着它们可以在生产中使用?对不起,我是新手。如果您可以扩展答案,那将有所帮助。谢谢
      • 调用npm run generate时可以传入环境变量吗?试图弄清楚如何在 Windows 中执行此操作。
      • 比如我有:.env和.env.debug,那我该如何构建一个带有.env.debug的版本呢?
      • 同意这个评论,我可以看到很多答案,但总的来说,NuxtJS 还没有在生产运行时传递环境变量的功能,它的运行时配置意味着用于开发阶段和构建阶段,所以如果你必须附加到不同的 API 链接,你需要有不同的构建。
      【解决方案5】:

      UPD。这仅在通用模式下有效,因为 nuxtServerInit 不会在 SPA 模式下调用。

      您可以在没有任何环境变量的情况下构建 Nuxt 进行生产。然后将其存储在 nuxtServerInit 中。

      我为此使用 env-cmd。

      我有包含下一个内容的 .env-cmdrc 文件:

      {
        "production": {
          "API_URL": "https://api.example.com/",
          "IMG_URL": "https://img.example.com/",
          "ENV_PATH": "./.cmdrc.json"
        },
        "staging": {
          "API_URL": "https://stage.example.com/",
          "IMG_URL": "https://stage.img.shavuha.com/",
          "ENV_PATH": "./.cmdrc.json"
        },
        "development": {
          "API_URL": "https://stage.api.example.com/",
          "IMG_URL": "https://stage.img.example.com/",
          "ENV_PATH": "./.cmdrc.json"
        }
      }
      

      我在店里有这样的东西:

      export const state = () => ({
        api_url: '',
        img_url: ''
      })
      
      export const mutations = {
        SET_PROCESS_ENV: (state, payload) => {
          state.api_url = payload.api_url
          state.img_url = payload.img_url
        }
      }
      

      nuxtServerInit 操作:

        commit('settings/SET_PROCESS_ENV', {
          api_url: process.env.API_URL,
          img_url: process.env.IMG_URL
        })
      

      package.json:

      "dev": "env-cmd -e development -r .env-cmdrc nuxt",
      "build": "nuxt build",
      "start_stage": "env-cmd -e staging -r .env-cmdrc nuxt start",
      

      【讨论】:

      • 这看起来很有趣,值得一提的是,当使用 SPA 模式时它不会正常工作 - 根据文档 nuxtServerInit 操作仅从服务器端调用
      【解决方案6】:

      我创建了一个函数,即使在生产中也可以从 /server/index.js 更新模块设置。

      这仅适用于数组样式的模块配置语法。像这样

      ['@nuxtjs/google-gtag', { ... }]
      

      nuxt.config.js

      // Import and Set Nuxt.js options
      const config = require('../nuxt.config.js')
      config.dev = process.env.NODE_ENV !== 'production'
      
      function updateConfigModuleSettings(name, settings) {
        const i = config.modules.findIndex(m => Array.isArray(m) && m[0] === name)
        if (i > -1) {
          const oldSettings = config.modules[i][1]
          config.modules[i][1] = {
            ...oldSettings,
            ...settings
          }
        } else {
          throw new RangeError(`Nuxt module named '${name}' could not be found`)
        }
      }
      
      // call the function as many times as you like with your module settings overrides
      updateConfigModuleSettings('@nuxtjs/google-gtag', {
        id: process.env.GOOGLE_ANALYTICS_ID,
        debug: process.env.NODE_ENV === 'development', // enable to track in dev mode
      })
      
      async function start () {
        // this will take the overridden config
        const nuxt = new Nuxt(config)
      
        // ...
      }
      start()
      

      【讨论】:

        猜你喜欢
        • 1970-01-01
        • 2013-12-29
        • 2016-07-08
        • 1970-01-01
        • 1970-01-01
        • 1970-01-01
        • 1970-01-01
        • 1970-01-01
        • 2021-09-05
        相关资源
        最近更新 更多