Various correct postures for using environment variables in Webpack

Various correct postures for using environment variables in Webpack

Write in front

Are you still worried about various packaging configurations in Webpack?

Today we are going to talk about various ways to inject environment variables in webpack. Or do you think that injecting environment variables through the command line is not enough?

If you have this idea, I believe you will gain something different if you read on patiently.

After all, growth is a process of accumulation bit by bit! Let’s talk about the correct ways to use environment variables in Webpack 5.

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

  • Inject webpack environment variables into business code.
  • The official build process uses webpack environment variables.
  • The traditional environment variable method uses webpack build process environment variables.

Business code uses environment variables

Use the webpack.DefinePlugin plugin to inject environment variables into business code

I believe that many students have already applied this scenario. We need to inject some global variables through webpack during the packaging process and use them in the business code.
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 business code encounters the variable __WEBPACK__ENV, the code will recognize this variable and output the correct string value pacakges.

Think about what we should do?

Students who are familiar with webpack have actually thought of it. We can inject it through the definePlugins plug-in 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 the webpack plugins, when we run the packaging command, if the variable __WEBPACK__ENV appears in our business code, it will help us replace it with the string 'packages', thus achieving an effect similar to environment variable injection.

Thinking triggered by webpack.DefinePlugin

Maybe you are already familiar with the use of the webpack.definePlugins plugin. Don't worry, let's take a look at it patiently. This code leads us to the following thoughts:

  1. 'packages' is already of string type, why do we need to use JSON.stringify() to process it?
  2. Are the environment variables at this time really the so-called environment variables?

Let’s first discuss these two issues:

definePlugin so-called "environment variables" implementation

The official webpack documentation says this

(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 is just saying that webpack.definePlugins is essentially a string replacement in the packaging process, such as the __WEBPACK__ENV:JSON.stringify('packages') we just defined.

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

This also answers our second question.

JSON.stringify() handles environment variables

Next, let’s take a look at the first question. As the saying goes, practice makes perfect. Let's try to compare the two different definePlugin configurations to see the results:

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

// Packaged code Here we close devtools to list the packaged code console.log('hello, Environment variable', 'packages')
// webpack.config.js
new webpack.DefinePlugin({
  __WEBPACK__ENV: 'packages',
  TWO: '1+1',
});

// Packaged code Here we close devtools to list the packaged code console.log('hello, Environment variable', packages)

Comparing the two codes carefully, the answer to the first question is very clear. When we use definePlugin to define key:value global variables, it will directly replace the text with value. So we usually use JSON.stringify('pacakges') or "'packages'".

We have almost explained the process of DefinePlugin and the details that require extra attention, but at this point we define the so-called global variables for use in business code. But at this time, if we want to use environment variables in the packaging and building process, we need another way to inject them.

Using environment variables during the build process

Usually when using webpack, we need to use environment variables for dynamic packaging according to our unique needs. For example, we can dynamically read folders in the project and dynamically interact with users in the console to package different bundles.

At this time, it is very important to use environment variables in the build process. The so-called use of environment variables in the build process simply means injecting environment variables into non-business code, such as the webpack.config.js configuration file.

Let's look at entering this line of code into our project:

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

At this point, this line of code is equivalent to running webpack to read the webpack.config.js configuration file in the current directory for packaging, and injecting two environment variables goal and progress, whose values ​​are local and true respectively.

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'),
    },
  };
};

Careful ones may have discovered that our module.exports here exports a function containing env, rather than a traditional object.

Typically, module.exports points to a configuration object. To use env variables, you have to convert module.exports into a function.
Let's see what happens if we don't use a function:

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 when we read env.goal/production in the node process, we find that both are undefined.

That is to say, when we usually use --env to inject environment variables into the webpack build process in the command line, we need to export the module.exports of the configuration file in 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.

So here comes the question again, eh? What if I just want to get the corresponding environment variables in the node process? What should I do, I just don't want to write a function.

The traditional environment variable method uses webpack build process environment variables.

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

What if we inject true traditional environment variables instead of --env when running the webpack command? Next, let’s try it~

Here we use a very useful 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 different environments such as Linux/Windows... Next, let's use it:

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 via cross-env NAME_W=aaa.

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

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

After our attempts, we found that it is actually possible to inject environment variables through the traditional command line method! This way we escape the restriction that the export must be a function and can do whatever we want.

Summarize

In webpack construction and business code, the injection of environment variables is of great help to us. When a certain system of front-end engineering code is required, environment variables play a vital role both in the build process and in the business code.

Seeing that we have already covered what we want to say here, let's make a brief summary:

When webpack packages business code, if we need to use some global variables in a similar way to environment variables, we can use webpack.DefinePlugin to define some variables for use in business code. (But note the JSON.stringify() mentioned above).

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

At the same time, you can also "escape" the limitations of webpack by injecting environment variables in the way we use in our daily life during the build process, directly use the environment variables defined in the command line and then get them through process.env.xxx.

This is the end of this article about using environment variables in Webpack. For more information about using environment variables in Webpack, please search for previous articles on 123WORDPRESS.COM or continue to browse the following related articles. I hope you will support 123WORDPRESS.COM in the future!

You may also be interested in:
  • Detailed explanation of some misunderstandings in setting environment variables for Webpack

<<:  MySQL data duplicate checking and deduplication implementation statements

>>:  Use of Linux file command

Recommend

Zabbix monitoring docker application configuration

The application of containers is becoming more an...

Sample code for a large drop-down menu implemented in pure CSS

This is a large drop-down menu implemented purely...

Robots.txt detailed introduction

Basic introduction to robots.txt Robots.txt is a p...

A simple way to implement all functions of shopping cart in Vue

The main functions are as follows: Add product in...

How to detect Ubuntu version using command line

Method 1: Use the lsb_release utility The lsb_rel...

A brief analysis of MySQL's WriteSet parallel replication

【Historical Background】 I have been working as a ...

Vue implements tree table through element tree control

Table of contents Implementation effect diagram I...

HTML 5 Reset Stylesheet

This CSS reset is modified based on Eric Meyers...

Solution to the problem of adaptive height and width of css display table

Definition and Usage The display property specifi...

Use Visual Studio Code to connect to the MySql database and query

Visual Studio Code is a powerful text editor prod...

Differences between FLOW CHART and UI FLOW

Many concepts in UI design may seem similar in wo...

Import CSS files using judgment conditions

Solution 1: Use conditional import in HTML docume...

Solution to ONLY_FULL_GROUP_BY error in Mysql5.7 and above

Recently, during the development process, the MyS...