π€ Use Case
You want to provide webpack with a different configuration based on the environment variable.
By directly adding the instruction pairs in the configuration file with a monolithic model, you risk a headhache π΅. There must be some way to make it simpler.
π Example Code
π¦ Packages
π‘ Solution
This is not π-science - it is about the order and the benefits deriving from it. I unpack the main configuration file by placing the instruction sets into appropriate files. Simply inform webpack of the environment variable (env) and it will know how to derive the appropriate orders.
Even from the developerβs point of view it becomes easier to follow the logical thread of the program, maybe even after a long time.
π€ Implementing the Solution
Initial State:
- package.json (
npm init -y
) - src/index.js (content not relevant)
- config
- [1] Add packages
- [2] Add npm scripts to
package.json
- [3] Building components
- [4] Assembling components
- 1 - Add packages
In the terminal invoke: npm i -D webpack webpack-cli webpack-dev-server
- 2 - Add npm scripts to package.json
Update package.json
adding the start and the build scripts. In the first case we use the development server specifying that env is development.
The alternative is the use of the bundler in production mode.
{
...
"scripts": {
"start": "webpack-dev-server --env development",
"build": "webpack --env production"
},
...
}
- 3 - Building components | π¦Ώ usePlugins
To pull up a wall first you have to make the bricks. This will be able to return a different array based on env as well as allowing easy and quick integration of plugins addition.
Create usePlugins.js
in config
. This file is structured like so:
- plugins imports
- exported function
- configuration panel π
- business logic β
// plugins imports
const HtmlWebpackPlugin = require('html-webpack-plugin');
const { CleanWebpackPlugin } = require('clean-webpack-plugin');
// exported function
exports.usePlugins = (e) => {
// configuration panel
const pluginsPanel = {
development: 'html',
production: 'html clean',
values: {
html: new HtmlWebpackPlugin({
title: 'Webpack Loading CSS',
}),
clean: new CleanWebpackPlugin(),
},
};
// business logic
let message = '[plugins]: ';
let error = '';
const plugins = pluginsPanel[e.toString()];
const arr = plugins.split(' ');
const outcome = arr
.map((plugin) => {
const p = pluginsPanel.values[plugin];
if (!p) {
error += plugin + ' ';
return;
}
message += plugin + ' '
return p;
})
.filter((plugin) => typeof plugin !== 'undefined');
console.info(message);
console.warn('[plugins|error]: ' + (error !== '' ? error : 'none'));
return outcome;
};
As you will appreciate in the end all the cumbersome import of plugins are in this secondary file, while webpack.config.js
will report only the essentials.
In the configuration panel are specified two different sets containing labels - all real plugin builders are crammed into a container (.values).
The exported function receives the env and according to it selects the right set.
Itβs up to the business logic to read the label, to understand if the relative plugin is present into the said container and if so place it in the final product.
Optionally it is best to sanitize the final result by filtering away the plugins not found and showing an error message
- 3 - Building components | β index
If you plan to expand this technique on later occasions it becomes useful to have to opportunity to get all these components with a single import.
In config
folder add an index.js
file.
const { usePlugins } = require('./usePlugins');
// const { anotherPlugin } = require('./another');
module.exports = {
usePlugins,
// anotherPlugin
};
The utility of this practice is more visible as the number of plugins grows.
- 4 - Assembling components π§
Itβs time to connect the wires in webpack.config.js
.
const path = require('path');
const helpers = require('./config'); //[1]
module.exports = (env) => ({ //[2]
entry: {
main: './src/index.js',
},
output: {
path: path.join(__dirname, 'dist'),
filename: '[name].js',
},
plugins: helpers.usePlugins(env),
});
- When you require the contents of a folder rather than a specific file contained in it, is selected by default the file named index.
- Rather than returning a configuration object directly, a function is exported - it can accept the env variable and use it to generate the appropriate outcome.
π Checking the Outcome
Try to assign different plugin combinations in the control panel and compare expectations with the message received at the console. Then try to make up some funny plugin label and add it - the server/build process will not crack and in the console is reported the culprit.
Check the example code for other use cases.
Top comments (0)