web-dev-qa-db-fra.com

Vue.js avec différentes variables d'environnement

J'ai utilisé modèle Webpack officiel pour Vue.js. Il utilise une configuration distincte pour différents environnements . Ils proposent test, développement et production. Cependant, j'en ai besoin d'un autre car nous avons deux serveurs de production (un de production et un intermédiaire).

Quelle est la meilleure pratique pour avoir différentes configurations pour différents environnements de production? Je penserais à quelque chose comme npm run build --URL:http://some-url.com --PORT:80 ....

Tout conseil est le bienvenu!

21
kuceram

Cela ressemble plus à une question de webpack qu'à Vue.js, je veux partager notre configuration précédente pour gérer différents fichiers de construction et environnements. tout d'abord, nous conservons notre configuration dans un dossier séparé.

config/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'
    }
  }
}

config/dev.env.js

var merge = require('webpack-merge')
var prodEnv = require('./prod.env')

module.exports = merge(prodEnv, {
  NODE_ENV: '"development"',
  API_ROOT: '"/api"'
})

config/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
}

au cas où nous voulons travailler, nous changeons la racine de l'API ici.

et notre webpack.base.conf.js ressemble à ceci. build/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]')
        }
      }
    ]
  }
}

et enfin notre package.json ressemble à ceci

...
...
...
    "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"
     }
...
...
...

nous avons utilisé cette configuration pour regrouper notre application pour électron, web et webkit tout en utilisant des composants partagés.

mais encore plus tard, nous avons eu des problèmes d'écaillage. et nous avons commencé à utiliser lerna si vous avez besoin de quelque chose de plus modulateur. Je vous recommande de vérifier celui-ci.

Meilleures salutations.

18
Necmttn

Il existe un moyen simple. Dans config/prod.env.js ajoutez vos variables comme ceci:

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

Exécutez ensuite votre build comme ceci: MY_URL=http://example.org npm run build

Votre variable sera disponible dans main.js comme process.env.MY_URL

8
niutech

PROD: config/prod.env.js ajoutez votre VAR='"value"'

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

DEV: config/dev.env.js ajoutez votre 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"'
})

Votre variable sera disponible sous la forme process.env.API_URL ou process.env.VAR_NAME

0
erajuan