I've used official Webpack template for Vue.js. It uses separate configuration for different environments. They offer test, development and production. However, I need another one as we have two production servers (one production and one staging).
What is the best practice to have different configurations for different production environments? I would think of something like npm run build --URL:http://some-url.com --PORT:80 ...
.
Any advice is welcome!
Using Env Variables in Client-side CodeNODE_ENV - this will be one of "development" , "production" or "test" depending on the mode the app is running in. BASE_URL - this corresponds to the publicPath option in vue.config.js and is the base path your app is deployed at.
Using environment variables is a somewhat common practice during Development but it is actually not a healthy practice to use with Production. While there are several reasons for this, one of the main reasons is that using environment variables can cause unexpected persistence of variable values.
This is more like a webpack question rather then Vue.js, I wanna share our previous setup for handling different build files and environments. first of all, we keep our config in separated folder.
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 }
incase of where we wanna work we change API root in here.
and our webpack.base.conf.js look like this. 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]') } } ] } }
and finally our package.json is look like this
... ... ... "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" } ... ... ...
we used this setup for bundle our app for electron, web, and webkit while using shared components.
but still later on we had issue of scalling. and we started to use lerna if you need something more moduler. I recommend you to check that one out.
Best regards.
There is a simple way. In config/prod.env.js
append your variables like this:
module.exports = { NODE_ENV: '"production"', MY_URL: JSON.stringify(process.env.MY_URL || 'http://example.com') }
Then run your build like this: MY_URL=http://example.org npm run build
Your variable will be available in main.js
as process.env.MY_URL
If you love us? You can donate to us via Paypal or buy me a coffee so we can maintain and grow! Thank you!
Donate Us With