Writing in the front

Are you still bothered by the various packaging configurations in Webpack?

Today we are going to talk about the various ways to inject environment variables in WebPack, or do you think it’s ok to inject environment variables via the command line?

If you have this idea, patience to look down I believe you will have a different harvest ~

After all, the so-called growth is the process of accumulation bit by bit! Let’s talk about the correct postures for using environment variables in Webpack 5.

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

  • Injection is used in business codewebpackEnvironment variables.
  • The official build process provides usewebpackEnvironment variables.
  • The traditional environment variable method is usedwebpackBuild process environment variables.

Business code uses environment variables

usewebpack.DefinePluginPlug-ins inject environment variables into business code

I believe many students have already applied this scenario, we need to inject some global variables through webpack during the packaging process to use in the business code.

For example, our business entry file has this code:

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

What we want is for business code to recognize the __WEBPACK__ENV variable and print the correct string value pacakges.

Think about what should we do?

For those of you who are familiar with WebPack, we can inject via definePlugins in WebPack:

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

After running the package command, the __WEBPACK__ENV variable in our business code will be replaced with the string ‘packages’ to achieve the same effect as the environment variable injection.

webpack.DefinePluginTriggered thinking

You’re probably already familiar with webpack.defineplugins, so let’s take a look at some of the following thoughts:

  1. 'packages'Is alreadystringType, why do we use itJSON.stringify()Process.
  2. At this timeThe environment variableIs it really the so-called environment variable?

Let’s start with these two questions:

definePluginThe so-called”The environment variable“Implementation method

The official Webpack documentation says so

(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').)

Webpack.defineplugins are essentially string replacements in the packaging process, such as __WEBPACK__ENV: json.stringify (‘packages’) we just defined.

During packaging, if __WEPBACK__ENV is used in our code, webpack replaces its value with the value defined in definePlugins, essentially matching string substitution, not traditional environment variable process injection.

Which brings us to our second question.

JSON.stringify()Working with environment variables

Let’s take a look at the first question. Let’s try configuring two different definePlugins to see the result:

// webpack.config.js
new webpack.DefinePlugin({
  __WEBPACK__ENV: JSON.stringify('packages'),
  TWO: '1 + 1'});Here we turn off devTools to list the packaged code
console.log('hello, Environment variable'.'packages')
Copy the code
// webpack.config.js
new webpack.DefinePlugin({
  __WEBPACK__ENV: 'packages'.TWO: '1 + 1'});Here we turn off devTools to list the packaged code
console.log('hello, Environment variable', packages)
Copy the code

The answer to the first question is clear when comparing these two pieces of code. For definePlugin, when we define the key:value global variable, it replaces the value directly with the text. So we usually use json.stringify (‘ Pacakges ‘) or ‘packages’.

We’ve pretty much cleared up the flow of DefinePlugin and the details that need extra attention, but at this point we define the so-called global variables to be used in the business code. But at this point, if we want to use environment variables for the packaged build process, we need a different way to inject.

Use environment variables during the build process

In general, when using WebPack, we need to use environment variables for dynamic packaging according to our own unique needs, such as dynamic reading of folders in the project to dynamically and interactive packaging of different bundles in the console.

The use of environment variables in the build process becomes very important at this point, which 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 in the project:

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

This line of code is equivalent to running Webpack, reading the webpack.config.js configuration file in the current directory and packing it, and injecting two environment variables, goal and Progress, with values of local and true, respectively.

This allows us to use the injected environment variable 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'),}}; };Copy the code

Module. exports exports a function containing env, not a traditional object.

In general,module.exportsPoints to a configuration object. In order to useenvVariables, you have to putmodule.exportsConvert to a function.

Let’s see 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'),}};Copy the code

Env.goal /production () {env.goal/production ();}

Module. exports is exported as a function of the configuration file, and the corresponding key is retrieved from the first argument of the function to the corresponding environment variable value.

So the question is, eh? What if I just want to get the corresponding environment variable in node’s process? What should I do? I just don’t want to write a function.

The traditional environment variable method is usedwebpackBuild 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 injected real traditional environment variables when running the webpack command instead of using –env? Let’s give it a try

Here we use a very useful environment variable plug-in called cross-env, which is very simple to use and can help us in different environments Linux/Windows… To inject runtime environment variables in the same way, 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"
Copy the code

We inject an environment variable with cross-env NAME_W=aaa.

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

module.exports = {
  entry: './src/a.js'};Copy the code

In our experiment, we found that the traditional way of injecting environment variables through the command line is also possible! So we get away from the fact that the export has to be a function and we can do whatever we want.

conclusion

Injection of environment variables can be a huge help in webPack builds and business code. When a system of front-end engineering code is required, environment variables play a crucial role in both the build process and the business code.

Now that we’ve covered everything we want to say, let’s make a brief summary:

When we need to use global variables in a similar way to environment variables when wrapping business code in Webpack, we can use webpack.definePlugin to define variables to be used in business code. (Note json.stringify () above, though).

Also, during the build process, we can use environment variables defined by –env through the –env parameter officially provided by WebPack and through the module.exports function in configuration files.

It is also possible to “escape” Webpack by injecting environment variables during the build process in a way we use everyday, using the environment variables defined on the command line and obtained via process.env.xxx.