One, foreword

  • In daily front-end development, there are at least two build environments
    • A set of development time use, build results for local development debugging, do not compress code, print debug information, including sourcemAP files, etc
    • A set of release time, build results are used online, i.e. code is compressed, no debug messages are printed at run time, static files do not include sourcemap, etc
  • Webpack 4.0 introduced the concept of mode
options describe
development willprocess.env.NODE_ENVThe value of the setdevelopment. To enable theNamedChunksPluginNamedModulesPlugin
production willprocess.env.NODE_ENVThe value of the setproduction. To enable theFlagDependencyUsagePlugin.FlagIncludedChunksPlugin.ModuleConcatenationPlugin.NoEmitOnErrorsPlugin.OccurrenceOrderPlugin.SideEffectsFlagPluginUglifyJsPlugin

2. Multiple ways to differentiate development/production environments

2.1 Using the CLI

2.1.1 writing a

"Scripts ": {// The default mode is development "dev1": "webpack-dev-server", // the default mode is production. "webpack", }Copy the code
  • The script above,canPass in any moduleprocess.env.NODE_ENVGets the current environment variable
  • You cannot get the current environment variable from the Node environment (in the WebPack configuration file)
// index.js 
function getEnv() {
   console.log(process.env.NODE_ENV);// development | production
}

// webpack.config.js
const path = require('path');
const webpack = require('webpack');

console.log('NODE_ENV',process.env.NODE_ENV);// undefined

module.exports =  {
  	entry:'./src/index.js'.output: {
            filename: 'js/[name].js'},... };Copy the code

2.1.2 writing 2

"scripts": {
   "dev2": "webpack --mode=development",
   "build2": "webpack --mode=production",
}
Copy the code
  • It’s the same thing as writing one

2.1.3 writing three

"scripts": {
   "dev3": "webpack-dev-server --env=development",
   "build3": "webpack --env=production",
}
Copy the code
  • The script above,Can’tPass in any moduleprocess.env.NODE_ENVGets the current environment variable
  • You can, however, get the current environment variable from a function in the Node environment (in the WebPack configuration file)
// index.js 
function getEnv() {
   console.log(process.env.NODE_ENV);// undefined
}

// webpack.config.js
const path = require('path');
const webpack = require('webpack');

console.log('NODE_ENV',process.env.NODE_ENV);// undefined

// Get the current environment variable from the function
module.exports = (env,argv) = > {
  console.log('env',env);// development | production
  return {
  	entry:'./src/index.js'.output: {
            filename: 'js/[name].js'},... }};Copy the code

2.2 use mode

// index.js 
function getEnv() {
   console.log(process.env.NODE_ENV);// development | production
}

// webpack.config.js
const path = require('path');
const webpack = require('webpack');

console.log('NODE_ENV',process.env.NODE_ENV);// undefined

module.exports =  {
  	mode:'development'.// development | production
  	entry:'./src/index.js'.output: {
            filename: 'js/[name].js'},... };Copy the code
  • The result is the same as that of method 2 in 2.1
  • One is set on the command line and one is set in the WebPack configuration file

2.3 use webpack DefinePlugin

  • The first thing you need to know about this plug-in is what it does: SettingsThe global variable(Not mounted towindowAll modules can read the value of this variable
// index.js function getEnv() { console.log(process.env.NODE_ENV); // development console.log(NODE_ENV); // production } // webpack.config.js const path = require('path'); const webpack = require('webpack'); // Console. log(' process.env.node_env ', process.env.node_env); // undefined console.log('NODE_ENV',NODE_ENV); // error!! module.exports = { mode:'development',// development | production entry:'./src/index.js', output: { filename: 'js/[name].js' }, plugins:[ new webpack.DefinePlugin({ 'process.env.NODE_ENV':JSON.stringify('development'), 'NODE_ENV':JSON.stringify('production'), }), ], ... };Copy the code
  • canPass in any moduleprocess.env.NODE_ENVGets the current environment variable
  • You cannot get the current environment variable from the Node environment (in the WebPack configuration file)

2.4 Using the cross-env plug-in

  • I always thought that this plugin could be used to set variables in any environment (browser, Node). After testing, it can only be setThe node environmentThe variable ofNODE_ENV

Against 2.4.1 writing a

"scripts": {
 	"dev1": "cross-env NODE_ENV='production' webpack-dev-server",
        "build1": "cross-env NODE_ENV='development' webpack",
}
Copy the code
  • The above script can be passed in any moduleprocess.env.NODE_ENVGets the current environment variable
  • You can get the current environment variable from the Node environment (in the WebPack configuration file)
  • However, there is a problem: the values obtained in the browser and Node environments are different
// !!!!!! // NPM run build1 // !!!!!! // index.js function getEnv() { console.log(process.env.NODE_ENV); // production } // webpack.config.js const path = require('path'); const webpack = require('webpack'); console.log('process.env.NODE_ENV',process.env.NODE_ENV); // development module.exports = { entry:'./src/index.js', output: { filename: 'js/[name].js' }, ... };Copy the code

Write two 2.4.2

"scripts": {
  "dev2": "cross-env NODE_ENV='development' --mode development",
  "build2": "cross-env NODE_ENV='production' --mode production",
}
Copy the code
  • The above script can be passed in any moduleprocess.env.NODE_ENVGets the current environment variable
  • You can get the current environment variable from the Node environment (in the WebPack configuration file)
  • So reading the value of the environment variable in the browser environment depends onmodeTo read the value of an environment variable in the Node environmentcross-env
// !!!!!! // NPM run build2 // !!!!!! // index.js function getEnv() { console.log(process.env.NODE_ENV); // production } // webpack.config.js const path = require('path'); const webpack = require('webpack'); console.log('process.env.NODE_ENV',process.env.NODE_ENV); // production module.exports = { entry:'./src/index.js', output: { filename: 'js/[name].js' }, ... };Copy the code

Three, misunderstanding

  • This problem is often seen in groups:cross-envwebpack.DefinePluginWhen used together, it cannot passprocess.env.xxxTo obtain the set environment variables, you need to pass thewebpack.DefinePluginSet insidekeyIn order to get.
  • The possible cause of this problem is that cross-env was set firstNODE_ENVDelta variable, and then deltaDefinePluginSet the environment variable again
"scripts": {
  "dev": "cross-env NODE_ENV='development' --mode development"
}
Copy the code
// index.js 
function getEnv() {
   console.log(process.env.NODE_ENV);// development
}

// webpack.config.js
const path = require('path');
const webpack = require('webpack');

console.log('process.env.NODE_ENV',process.env.NODE_ENV);// development

module.exports =  {
  	entry:'./src/index.js'.output: {
            filename: 'js/[name].js'
        },
  	plugins: [new webpack.DefinePlugin({
             	// Set environment variables
               	'process.env.NODE_ENV':JSON.stringify('development'),}),],... };Copy the code
  • You’ll notice that both the browser environment and the Node environment have access to the set variable, and you’ll assume that you can set other global variables as well.

  • The idea that cross-env and DefinePlugin are used together is strange in itself, as they are used in different ways

    • DefinePluginSet the “global variable” that can be read in the browser environment, directly throughkeyRead, which is not available in node
    • cross-envSets environment variables from the command lineNODE_ENV, so that the Node environment can read, passprocess.env.NODE_ENVread
    • If theDefinePluginIn the setting ofkeyprocess.env.NODE_ENV, will override webpack passmodeThe value of the environment variable set by the mode
"scripts": {
  "dev": "cross-env NODE_ENV='development' --mode development"
}
Copy the code
// index.js 
function getEnv() {
   console.log(process.env.NODE_ENV);/ / 666666
}

// webpack.config.js
const path = require('path');
const webpack = require('webpack');

console.log('process.env.NODE_ENV',process.env.NODE_ENV);// development

module.exports =  {
  	entry:'./src/index.js'.output: {
            filename: 'js/[name].js'
        },
  	plugins: [new webpack.DefinePlugin({
                // Note: because of the key of the same name, the value here overrides the default value !!!!!!
               	'process.env.NODE_ENV':JSON.stringify('666666'),}),],... };Copy the code

Four,

  • cross-envSpecifically used to set node environment variablesthe
  • webpack.DefinePluginUsed to set global variables in the browser environment(Will not mount towindowOn)
  • This article is only my personal understanding, if there is any mistake please inform, thank you very much

5. Recommended reading

Do you really understand the React lifecycle

React Hooks 【 nearly 1W words 】+ project combat

React SSR: + 2 projects

Implement a simple Webpack from 0 to 1