Correct gestures for using environment variables in Webpack

  • 2021-11-24 00:43:47
  • OfStack

The catalogue is written at the front Business code uses environment variables Injecting environment variables into business code using the webpack. DefinePlugin plug-in
Thoughts on webpack. DefinePlugin
Implementation of what definePlugin calls "environment variables"
JSON. stringify () handles environment variables
Using environment variables in the build process The traditional environment variable method uses webpack to build process environment variables. Summarize

Write on the front

Are you still worried about various packaging configurations in Webpack?

Today, let's talk about various gestures of injecting environment variables in webpack, or do you think it is ok to inject environment variables through command line?

If you have this idea, watch patiently and I believe you will have different gains ~

After all, the so-called growth is the process of 1 point 1 drop accumulation! Let's talk about the correct gestures for using environment variables in Webpack 5.

The article explains the environment variables in Webpack process from three aspects:

The webpack environment variable is injected into the business code. The official build process uses webpack environment variables. The traditional environment variable method uses webpack to build process environment variables.

Business code uses environment variables

Injecting environment variables into business code using the webpack. DefinePlugin plug-in

I believe many students have already applied this scenario, so we need to inject some global variables through webpack to use in business code during packaging.
For example, our business entry file has such a code:


// src/main.js
console.log('hello, Environment variable', __WEPBACK__ENV)

What we hope is that when the variable __WEBPACK__ENV is encountered in the business code, the code will recognize the variable and output the correct string value pacakges.

Think 1 What should we do?

Students who are familiar with webpack have already thought of it. We can inject it through the plug-in definePlugins in webpack:


const wepback = require('webpack')
// webpack.config.js
...
new webpack.DefinePlugin({
  __WEBPACK__ENV: JSON.stringify('packages'),
  TWO: '1+1',
});

After we add this configuration to plugins of webpack, when we run the package command, if the variable __WEBPACK__ENV appears in our business code, it will help us replace it with the string 'packages', thus achieving the effect similar to environment variable injection.

Thoughts on webpack. DefinePlugin

Perhaps you are already familiar with the use of webpack. definePlugins plug-in. Don't worry, let's look down patiently. From this code, we have caused several thoughts under 1:

'packages' is already of string type, so why should we use JSON. stringify () for processing. Is the environment variable really the so-called environment variable at this time?

Let's discuss these two questions first:

Implementation of so-called "environment variables" in definePlugin

As stated in the official document of webpack,

(Note that because the plugin does a direct text replacement, the value given to it must include actual quotes inside of the string itself. Typically, this is done either with alternate quotes, such as '"production"', or by using JSON.stringify('production').)

In fact, he just said that webpack. definePlugins is essentially a string replacement during packaging, such as __WEBPACK__ENV: JSON. stringify ('packages').

In the packaging process, if __WEPBACK__ENV is used in our code, webpack will replace its value with the corresponding value defined in definePlugins, which is essentially matching string replacement, not the traditional environment variable process injection.

This answers our second question.

JSON. stringify () handles environment variables

Next, let's look at the first question, which is called true knowledge from practice. Let's try to compare and configure definePlugin twice to see the results:


// webpack.config.js
new webpack.DefinePlugin({
  __WEBPACK__ENV: JSON.stringify('packages'),
  TWO: '1+1',
});

//  Packaged code   We're closed down here devtools  List the code after packaging 
console.log('hello, Environment variable', 'packages')

// webpack.config.js
new webpack.DefinePlugin({
  __WEBPACK__ENV: 'packages',
  TWO: '1+1',
});

//  Packaged code   We're closed down here devtools  List the code after packaging 
console.log('hello, Environment variable', packages)

Careful comparison of these two codes shows that the answer to question 1 is actually very clear. When we use definePlugin as a plug-in to define key: value global variables, he will directly replace the text with value. So we usually use JSON. stringify ('pacakges') or "'packages'".

We have almost cleared the DefinePlugin process and the details that require extra attention, but at this point we define what we call global variables to be used in business code. But at this point, if we want to use environment variables in the package build process, we need another way to inject them.

Using environment variables in the build process

Usually, in the process of using webpack, we need to use environment variables for dynamic packaging according to our own unique requirements, for example, some bundle corresponding to different user interactions are dynamically packaged by dynamically reading folders in projects.

At this point, it is very important to use environment variables during the build process. Using environment variables during the build process is simply to inject environment variables into non-business code, such as webpack. config. js configuration files.

Let's look at entering this line of code in the project:


npx webpack --env goal=local --env production --progress --config ./webpack.config.js

In this line of code, we run webpack to read the webpack. config. js configuration file in the current directory for packaging, and inject two environment variables, goal and progress, whose values are local and true respectively.

In this way, we can use the injected environment variables in the configuration file:


const path = require('path');

module.exports = (env) => {
  // Use env.<YOUR VARIABLE> here:
  console.log('Goal: ', env.goal); // 'local'
  console.log('Production: ', env.production); // true

  return {
    entry: './src/index.js',
    output: {
      filename: 'bundle.js',
      path: path.resolve(__dirname, 'dist'),
    },
  };
};

As you can see, here our module. exports derives a function containing env, not a traditional object.

Typically, module. exports points to a configuration object. To use the env variable, you must convert module. exports into a function.
Let's look at if we don't use functions:


const path = require('path');

// Use env.<YOUR VARIABLE> here:
console.log('Goal: ', process.env.goal); // undefined
console.log('Production: ', process.env.production); // undefined

module.exports = {
  entry: './src/index.js',
  output: {
    filename: 'bundle.js',
    path: path.resolve(__dirname, 'dist'),
  },
};

We can see that we read env. goal/production in the node process process and found that both are undefined.

That is to say, when we usually use--env to inject environment variables into the construction process of webpack on the command line, we need to export module. exports of the configuration file into the form of a function, so as to get the corresponding key in the first parameter of the function and get the corresponding environment variable value.

Then the problem comes again, eh? What if I just want to get the corresponding environment variable in process of node? What should I do? I just don't want to write a function.

Traditional environment variable methods use webpack to build process environment variables.

What should I do? In fact, the principle of webpack corresponding packaging is to execute our configuration file (nodejs configuration file) through shell command.

What if we run the command webpack by injecting really traditional environment variables instead of passing--env? Next, let's try 1 ~

Here we have a very easy-to-use environment variable plug-in cross-env, which is very simple to use and can help us inject runtime environment variables in the same way in linux/windows... in different environments. Next, let's use it in 1:

Don't forget to install npm install--save-dev cross-env.


// package.json
 "build": "cross-env NAME_W=aaa webpack --config ./webpack.config.js"

We injected an environment variable through cross-env NAME_W=aaa.


// webpack.config.js
console.log(process.env.NAME_W, 'env'); // 'aaa'

module.exports = {
  entry: './src/a.js',
};

Under our attempt, we found that it is also possible to inject environment variables through the traditional way of command line! In this way, we can escape the restriction that the export must be a function and "do whatever we want".

Summarize

In the webpack build and business code, the injection of environment variables is of great help to us. Environment variables play a critical role both in the build process and in the business code when you need a structured front-end engineering code.

Seeing that what we want to say here has already been said, let's make a simple summary:

When webpack packages business code, when we need to use some global variables in a similar way to environment variables, we can define some variables through webpack. DefinePlugin to use them in business code. (Note, however, JSON. stringify () mentioned above).

At the same time, during the construction process, we can use the environment variables defined by env through the official env parameter provided by webpack and the module. exports function in the configuration file.

At the same time, we can also "escape" the limitation of webpack by injecting environment variables in our daily use during the construction process, and directly use the environment variables defined on the command line and then obtain them through process. env. xxx.


Related articles: