【问题标题】:Vue.js build with different environment variablesVue.js 使用不同的环境变量构建
【发布时间】:2017-11-02 18:18:54
【问题描述】:

我在 Vue.js 中使用了 official Webpack template。它对不同的environments 使用单独的配置。他们提供测试、开发和生产。但是,我需要另外一台,因为我们有两台生产服务器(一台生产服务器和一台暂存服务器)。

为不同的生产环境设置不同的配置的最佳做法是什么?我会想到像npm run build --URL:http://some-url.com --PORT:80 ... 这样的东西。

欢迎任何建议!

【问题讨论】:

    标签: webpack vue.js


    【解决方案1】:

    这更像是一个 webpack 问题,而不是 Vue.js, 我想分享我们之前处理不同构建文件和环境的设置。 首先,我们将配置保存在单独的文件夹中。

    配置/index.js

    // see http://vuejs-templates.github.io/webpack for documentation.
    var path = require('path')
    
    const CDN = 'https://cdnURL.com/'
    
    module.exports = {
      build: {
        env: require('./prod.env'),
        assetsRoot: path.resolve(__dirname, '../dist'),
        assetsSubDirectory: 'static',
        assetsPublicPath: CDN,
        productionSourceMap: true,
        // Gzip off by default as many popular static hosts such as
        // Surge or Netlify already gzip all static assets for you.
        // Before setting to `true`, make sure to:
        // npm install --save-dev compression-webpack-plugin
        productionGzip: false,
        productionGzipExtensions: ['js', 'css'],
        productionBundleAnalyze: process.env.ANALYZE ? true : false
      },
      dev: {
        env: require('./dev.env'),
        port: 8080,
        assetsSubDirectory: 'static',
        assetsPublicPath: '/',
        proxyTable: {
          '/api': {
            target: process.env.npm_package_config_proxy,
            logLevel: 'debug',
            changeOrigin: true,
            onProxyRes(proxyRes, req, res) {
              // http-proxy-middleware
              proxyRes.headers['Content-Type'] = proxyRes.headers['content-type']
              delete proxyRes.headers['content-type']
            }
          }
        },
        // CSS Sourcemaps off by default because relative paths are "buggy"
        // with this option, according to the CSS-Loader README
        // (https://github.com/webpack/css-loader#sourcemaps)
        // In our experience, they generally work as expected,
        // just be aware of this issue when enabling this option.
        cssSourceMap: false
      },
      projects: {
        main: {
          entry: './packages/home/index.js',
          devPath: 'main.html',
          target: 'web',
          buildPath: path.resolve(__dirname, '../dist/index.html'),
          testPath: '../packages/home/__test__/index.js'
        },
        desktop: {
          entry: './packages/desktop/index.js',
          devPath: 'desktop.html',
          target: 'electron-renderer',
          buildPath: path.resolve(__dirname, '../../static/desktop.html'),
          assetsRoot: path.resolve(__dirname, '../../'),
          assetsSubDirectory: 'static',
          assetsPublicPath: '../',
          testPath: '../packages/desktop/__test__/index.js'
        },
        login: {
          entry: './packages/login/index.js',
          devPath: 'login.html',
          target: 'web',
          buildPath: path.resolve(__dirname, '../dist/login.html'),
          testPath: '../packages/login/__test__/index.js'
        },
        setting: {
          entry: './packages/setting/index.js',
          devPath: 'setting.html',
          target: 'web',
          buildPath: path.resolve(__dirname, '../dist/setting.html'),
          testPath: '../packages/setting/__test__/index.js'
        },
        playground: {
          entry: './packages/playground/index.js',
          target: 'web'
        }
      }
    }
    

    配置/dev.env.js

    var merge = require('webpack-merge')
    var prodEnv = require('./prod.env')
    
    module.exports = merge(prodEnv, {
      NODE_ENV: '"development"',
      API_ROOT: '"/api"'
    })
    

    配置/prod.env

    module.exports = {
      NODE_ENV: '"production"',
      API_ROOT: '"http://test.example.co/api"'  //staging server
      // API_ROOT: '"http://127.0.0.1:8787/api"'  //mock-up server
    }
    

    如果我们想在哪里工作,我们会在此处更改 API 根目录。

    我们的 webpack.base.conf.js 看起来像这样。 构建/webpack.base.conf.js

    var path = require('path')
    var config = require('../config')
    var utils = require('./utils')
    var projectRoot = path.resolve(__dirname, '../')
    
    const isProduction = process.env.NODE_ENV === 'production'
    
    module.exports = {
      entry: utils.entrys(),
      output: {
        path: config.build.assetsRoot,
        publicPath: isProduction ? config.build.assetsPublicPath : config.dev.assetsPublicPath,
        filename: '[name].js'
      },
      resolve: {
        extensions: ['.js', '.vue', '.json'],
        alias: {
          'src': path.resolve(__dirname, '../src'),
          'assets': path.resolve(__dirname, '../src/assets'),
          'components': path.resolve(__dirname, '../src/components')
        },
        unsafeCache: true
      },
      target: config.projects[process.env.npm_package_config_dev].target,
      module: {
        rules: [
          {
            test: /\.vue$/,
            loader: 'vue-loader',
            options: {
              postcss: [
                require('postcss-cssnext')(),
                require('lost')()
              ],
              cssModules: {
                localIdentName: isProduction ? '[path][name]---[local]---[hash:base64:5]' : '[path][name]--[local]',
                camelCase: true
              },
              loaders: Object.assign({}, utils.cssLoaders()),
              preLoaders: {
                html: 'inline-svg-loader'
              }
            }
          },
          {
            test: /\.js$/,
            loader: 'babel-loader',
            include: projectRoot,
            exclude: /node_modules/,
            query: {
              cacheDirectory: true
            }
          },
          {
            test: /\.json$/,
            loader: 'json-loader'
          },
          {
            test: /\.html$/,
            loader: 'vue-html-loader'
          },
          {
            test: /\.(png|jpe?g|gif)(\?.*)?$/,
            loader: 'url-loader',
            query: {
              limit: 10000,
              name: utils.assetsPath('img/[name].[hash:7].[ext]')
            }
          },
          {
            test: /\.(woff2?|eot|ttf|otf)(\?.*)?$/,
            loader: 'url-loader',
            query: {
              limit: 10000,
              name: utils.assetsPath('fonts/[name].[hash:7].[ext]')
            }
          }
        ]
      }
    }
    

    最后我们的 package.json 是这样的

    ...
    ...
    ...
        "scripts": {
          "dev": "webpack-dashboard -- node build/dev-server.js",
          "dev:login": "npm config set mesh:dev login && npm run dev",
          "dev:setting": "npm config set mesh:dev setting && npm run dev",
          "dev:main": "npm config set mesh:dev main && npm run dev",
          "dev:desktop": "npm config set mesh:dev desktop && node build/dev-server.js",
          "dev:playground": " npm config set mesh:dev playground && cross-env PORT=9000 npm run dev"
         }
    ...
    ...
    ...
    

    在使用共享组件时,我们使用此设置将我们的应用程序捆绑到电子、Web 和 webkit 中。

    但后来我们遇到了剥落问题。如果您需要更多模块,我们开始使用lerna。我建议您检查一下。

    最好的问候。

    【讨论】:

      【解决方案2】:

      有一个简单的方法。在config/prod.env.js 中附加您的变量,如下所示:

      module.exports = {
        NODE_ENV: '"production"',
        MY_URL: JSON.stringify(process.env.MY_URL || 'http://example.com')
      }
      

      然后像这样运行你的构建:MY_URL=http://example.org npm run build

      您的变量将在main.js 中作为process.env.MY_URL 提供

      【讨论】:

      • Running MY_URL=example.org npm run build in windows 返回MY_URL is not recognized... ...有什么办法解决这个问题?
      • @imin 在 Windows 上,你必须先set MY_URL=http://example.org,然后运行npm run build
      • 太棒了!这正是我想要的。谢谢哥们:)
      【解决方案3】:

      产品:config/prod.env.js 附加您的VAR='"value"'

      'use strict'
      module.exports = {
        NODE_ENV: '"production"',
        API_URL: '"https://production URL"'
      }
      

      DEV:config/dev.env.js 附加您的VAR='"value"'

      'use strict'
      const merge = require('webpack-merge')
      const prodEnv = require('./prod.env')
      
      module.exports = merge(prodEnv, {
        NODE_ENV: '"development"',
        API_URL: '"http://localhost"'
      })
      

      您的变量将以process.env.API_URLprocess.env.VAR_NAME 的形式提供

      【讨论】:

        【解决方案4】:

        变量 process.env.NODE_ENV 总是有两个值: 开发 - 生产。

        通过这个变量,您可以确定使用哪个 url。

        例如:

        const API_URL = {
          development: "http://localhost/api/",
          productrion: "https://api.example.com/api/",
        };
        const baseURL = API_URL[process.env.NODE_ENV];
        

        【讨论】:

          猜你喜欢
          • 2019-05-24
          • 1970-01-01
          • 1970-01-01
          • 2021-11-03
          • 1970-01-01
          • 1970-01-01
          • 2020-01-24
          • 2023-01-30
          • 2019-02-25
          相关资源
          最近更新 更多