preface
Because front-end applications separated from the front end are not supported by the back end, it is ok to use a fixed development environment address for page debugging when developing front-end applications independently. If remote apis of different environments need to be debugged during local development, or applications need to be deployed to servers in different environments, If you don’t configure server addresses, environment-specific variables, and so on separately for these environments, you might need to change a lot of code each time you switch environments. There is little information available on the web about this section, so I’ll use the vue /Webpack project generated with vue-CLI init as an example to show you the idea of a simple multi-environment configuration THAT I’m currently using.
1. An ideal multi-environment configuration
In back-end development, parameters for different environments in a project are configured in different configuration files. When you need to package A Maven-based Java project, you usually just need to specify the Profile environment by adding -p to the end of the package command to package the corresponding environment. Similarly, if the front-end can do the same when using WebPack development or packaging, it will be much easier.
/* MVN clean package -p prodCopy the code
In the front end project, the debug and package command vue-cli init is already generated for us in package.json.
/* /package.json */
"scripts": {
"dev": "webpack-dev-server --inline --progress --config build/webpack.dev.conf.js"."start": "npm run dev"."lint": "eslint --ext .js,.vue src"."build": "node build/build.js"
}
Copy the code
It would be convenient to transform these commands into similar packaging commands in the back end, for example:
/* This is not the case */"scripts": {
"start:dev": "npm run dev -P dev"."build:test": "node build/build.js -P test"$NPM run start: $NPM run build: $NPM run build:test// Package, test environmentCopy the code
So the first thing you need to figure out is how to pass the parameters to the debug/packaged script.
Note:
What I want to mention in particular here is,vue-cli
Scaffolding helped us generate the entire project, and there was a counterpartwebpack.dev.conf.js
andwebpack.prod.conf.js
Two separatewebpack
Configuration file, but due to file naming (dev.conf.js/prod.conf.js
), it’s easy to mistake these two files for webPack configurations for different environments. But these two files are actually a configuration file for local debugging and a configuration file for packaged deployment. Debug/package both modes and environments (dev/test/pre/prod
Can be combined with each other. In theory, these twowebpack
I think it should be calledwebpack.debug.conf.js
andwebpack.build.conf.js
Would be more like it.
2. Parameterize the script
There are several ways to pass arguments to scripts in Node.js, such as using process.argv:
/* hello.js */
console.log('hello ', process.argv[2]); /* commandline */ $node./hello.js tidus //process.argv = ['node'.'./hello.js'.'tidus']
hello tidus
Copy the code
While process.argv is convenient, it’s not very configurable, so we use yargs, which is a component in Node.js that can be installed directly through NPM. ===> Poke me to view yargs API documentation
$ npm install yargs --dev --save
/* hello.js */
const argv = require('yargs').argv;
console.log('hello ', argv.env); /* command line */ $node./hello.js --envtest
hello test
Copy the code
Yargs makes it easy to get a command line argument with a given name, so let’s see how this argument can be used to implement multi-file configuration.
3. Introduce environment variables
First of all, there is a brief description of how to configure environment variables in Webpack’s official website, refer to Webpack Production for details. To put it simply, the DefinePlugin replaces all the specified strings that appear in our source code with our supplied objects/strings, and the configuration files for different environments are placed in the /config directory.
/ * / build/webpack. Dev. Conf. Js: * / plugins: [new webpack. DefinePlugin ({/ / all process in the source code. The env will be replaced by / /'.. /config/dev.env'This moduleexportThings that come out'process.env': require('.. /config/dev.env')
})
]
/* /config/dev.env.js */
'use strict'
const merge = require('webpack-merge')
const prodEnv = require('./prod.env')
module.exports = merge(prodEnv, {
NODE_ENV: '"development"'
})
Copy the code
Obviously we can use this plug-in directly to service our multiple environment variables. We can use the environment parameters passed into the script above to dynamically load configuration files for different environments to achieve the purpose of switching environments. Dynamically load code for different configuration environments:
/ * / build/webpack. Env. Conf. Js * / / / define the parameters configuration const argv = require ('yargs').argv; // Get the environment variable const env = argv.e; process.stdout.write('the env is '+ env +'\n'); // require specifies the environment configuration file const envConfigFile =".. /config/" + env + ".env.js";
process.stdout.write('the env config file is '+ envConfigFile +'\n'); // Leave the require configuration file intactexportModule. exports = require(envConfigFile);Copy the code
The next step is to dump the dynamically loaded environment files into the webpack configuration file. Since both webpack.dev.conf.js and webpack.prod.conf.js inherit from webpack.base.conf.js, So we directly rewrite the wepack.base.conf.js plug-in configuration, directly add the DefinePlugin configuration, and remove the original configuration file of the plug-in configuration:
/ * / build/webpack. Base. Conf., js * / / / introduction of the above webpack env. Conf module const envConfig = require ('./webpack.env.conf') module.exports = { ... // Configure DefinePlugin plugins: [ // http://vuejs.github.io/vue-loader/en/workflow/production.html new webpack.DefinePlugin({'process.env': envConfig
})
],
...
}
Copy the code
Then debug/package the command again with the default generated command, but with the environment parameters passed after the command:
/* /package.json */
"scripts": {
"start:dev": "webpack-dev-server --inline --progress --config build/webpack.dev.conf.js --e dev"."start:test": "webpack-dev-server --inline --progress --config build/webpack.dev.conf.js --e test"."start:pre": "webpack-dev-server --inline --progress --config build/webpack.dev.conf.js --e pre"."start:prod": "webpack-dev-server --inline --progress --config build/webpack.dev.conf.js --e prod"."build:dev": "node build/build.js --e dev"."build:test": "node build/build.js --e test"."build:pre": "node build/build.js --e pre"."build:prod": "node build/build.js --e prod",}Copy the code
Our environment configuration file could look something like this:
/* /config/test.env.js */
'use strict'
const merge = require('webpack-merge')
const prodEnv = require('./prod.env')
module.exports = merge(prodEnv, {
NODE_ENV: '"test"',
API_HOST: '"http://test.xx.com:8080"'
})
Copy the code
We can then use process.env.node_env in the source code to get the values of our configured environment variables, or even separate an API module:
/* /src/api/index.js */
const API_HOST = process.env.API_HOST;
export default {
api1: `${API_HOST}/path/to/api1`,
api2: `${API_HOST}/path/to/api2`
}
Copy the code
Finally, we can easily use these environment configurations in our Vue component:
/* /src/components/HelloWorld.vue */
import api from '@/api';
data () {
return {
msg: 'Welcome to Your Vue.js App',
env: process.env.NODE_ENV,
api1: api.api1,
api2: api.api2
}
}
Copy the code
4, summarize
Through the whole process, we added a webpack.env.conf.js module, slightly modified the three webpack configuration files generated by VUe-CLI, and added the configuration files of each environment in the config directory. The structure of the project looks like this: