Preface
As explained in the previous article - Take your webpack to the next level by understanding these concepts, we have a general understanding:
- Some of the concepts that arise in using
webpackprocess - Combined with the concepts of the packaging process, we analyzed the
webpackpackaging process, so that we can have a general understanding of the packaging process.
We all know that in the actual development process, we use webpack only to finally output css, img, js, html and other front-end resources that the browser can run.
So, in order to be more close to the actual situation, in this article, we will learn how to configure webpack with the purpose of how to output css, img, js, html and other front-end resources.
Learning Outline
This article explains the following basic configuration:
- Handling
css, lessfiles - Handling
img,font,audioand other front-end resource files. - Compiling
es6+syntax andAPI. - Processing
htmlfiles
The webpack documentation is pretty detailed, so I don't want to copy and paste it and write it all over again, so it's better to just read the documentation.
Learning can't be learned the hard way, there should be some methods and techniques. Therefore, I would like to summarize some methods in the process of explaining the configuration, so that we can better understand the configuration of webpack. In this way, some similar configurations, we can match them by looking at the documentation.
Remarks
The article has been uploaded to github:
- For the sake of reading convenience, the article only posted the relevant code, it is recommended to
forkit to see the complete code; or follow the article together with the side of the knock, so that the impression will be more profound! - It's not easy to create, if you think it's helpful, welcome to star🌟!
Handling css, less files
Let's start with the learn-03 case to see how webpack handles style files.
We install the appropriate loader to parse them:
-
less-loader: parseslessintocss. -
css-loader: parsescssinto valid modules recognized bywebpack. -
style-loader: parsescssand inserts it into<header />.
npm install less less-loader css-loader style-loader -D
Then configure it:
// webpack.config.js
module.exports = {
...,
module: {
rules: [
{
test: /.(css|less)$/,
use: [
'style-loader',
'css-loader',
'less-loader',
],
},
]
}
}
The parsing of loader is performed in reverse order (or right-to-left), so this configuration will be performed in the following order (less-loader → css-loader → style-loader):
- parses
lessintocss. - pass the result to
css-loader, which parses it into a valid module recognized bywebpack. - passes the result to
style-loader, which inserts the parsed styles into<header />) in the following order.
The less, css, and entry file code is:
// index.less
*{
margin: 0;
padding: 0;
}
h1{
color: red;
margin-top: 20px;
}
/* index.css */
h2{
color: green;
}
// index.js
import './assets/index.less';
import './assets/index.css';
Output:
We'll see that the style we wrote was processed successfully and inserted into the <head/>.
Summary
We previous post said:
- The resource files that we come in via
importorrequire, or each file in our project, can be viewed as an individual module - The role of the
Loaderis to convert these modules into valid modules thatwebpackrecognizes.
webpack humanely exposes the module configuration item, which is specifically designed to configure the relevant loader to parse the corresponding module. So if we want to parse some module used in our source code, we should:
- download the appropriate
loaderfirst -
Find the
moduleconfiguration directly and configure it according to theloaderusage.
So, we can try to configure our own .scss or .txt files according to the above summarized methods and ideas.
OK, we successfully got the styles (css) we need for our project, next we will see how to deal with images (img) and other front-end resource files.
Handling front-end resource files
There are a lot of front-end resource files, here, we roughly divide them into two categories first:
- Common class:
img,font,videoand so on. - Special category:
.csv,.xmland so on.
These resources are also modules as long as they are imported or required into our source code. Since they are modules, we need to install the appropriate loader to parse them, and then configure them in the module configuration.
Prior to wepack5, For resources of commonly used classes, we generally needed to install the following loader to parse them:
-
raw-loader: parses files into strings -
file-loader: parses files coming in fromimport/require()into a fully referencedurland sends the file to the output directory -
url-loader: can convert files tobase64.
We often use file-loader and url-loader. This is because common resources are often introduced into our projects as url, or converted to base64 in order to reduce http requests.
But after webpack5, webpack has built-in the functions of the above several loaders, so we can no longer need to install the above loaders; we can directly use webpack's own asset module.
The resource module built in after webpack5:
-
asset/source: equivalent toraw-loader. -
asset/resource: equivalent tofile-loader. -
asset/inline: equivalent to aurl-loader. -
asset: more flexible, has bothasset/resourceandasset/inline. If you set a file size limit, the file will be converted tobase64if it doesn't exceed the limit; if you don't set a size limit, it works the same asfile-loader.
This is why I love
webpack5so much, because we don't have to install so many messyloaders.
Let's use the case of learn-04 to see how we can use the resource module to parse our front-end resources.
Let's add the configuration from the previous chapter on parsing styles together and use the image resources in less and js respectively.
We have two images:
-
preview.gif: size349kb -
ecj-cli.png: size4kb.
// webpack.config.js
module.exports = {
...,
module: {
rules: [
{
test: /.(css|less)$/,
use: [
'style-loader',
'css-loader',
'less-loader',
],
},
{
test: /\.(png|svg|jpg|jpeg|gif)$/i,
type: 'asset',
parser: {
dataUrlCondition: {
maxSize: 1024 * 10 // // When the image size is < 10kb it will be converted to base64
}
},
generator: {
filename: '[name][ext]' // Set the name of the output file
}
}
]
}
}
Entry file:
// index.js
import './assets/index.less';
const img = new Image();
img.src = require('./assets/ecj-cli.png');
img.width = 500;
document.querySelector('#js_logo').append(img);
Style:
.bg_logo{
width: (1434/3px);
height: (1212/3px);
background-image: url('./preview.gif');
background-size: 100%;
}
Output results:
We'll see that the style and js both process the image successfully:
-
preview.gifis larger than10kb, so instead of being converted tobase64, a full reference path is returned (equivalent tofile-loader) -
ejc-cli.pngis smaller than10kbso it was converted tobase64(equivalent tourl-loader)
The gif above is a command line tool ejc-cli that I developed that is very useful in everyday projects. It can convert the
Exceldata collected by the docking staff intojsondata in a certain format which is needed by our code. It is very convenient for us to develop and maintain the data, and also to interface with other people.If you are interested, you can check out 👉🏻 learn about ejc-cli
Summary
Resources that are imported into our source code via import or require are also modules. So you need to download the appropriate loader and configure it in the module configuration.
For common resources (img, font, video, audio, etc.):
- Because they are commonly used,
webpack5has built-in functionality to handle them, so that we don't need to install an additionalloader, and we use theasset moduleto manage them directly. -
We generally use
asset/resource,asset/inline,assetmodules to manage common class resources. Because the resources of our common classes are often introduced in our projects, we need to parse them to introduce the fullurl, or convert them tobase64in order to reduce the number ofhttprequests.
For special classes of resources (.csv, .xml, etc.):
- We can understand that because they are not commonly used,
webpackdoes not have their functionality built in. - Therefore, we need to install the appropriate
loaderto parse them. For example, if we want to parse a.csvfile, we need to install thecsv-loaderto parse it.
We can try to configure ourselves to handle .video or font as summarized above.
OK, so far, we've got css, img. Let's see how we can get our js through webpack processing.
Compiling es6+
To this day, js is evolving rapidly, and every year some new syntax or new API appears in order to improve development efficiency and code quality.
For example, in terms of syntax appeared:
- Arrow functions:
()=> - class syntactic sugar:
class People {} - Deconstructed assignment:
const [x, y] = [1, 2]; - ...
On the API side again:
PromiseArray.prototype.includes()Object.keys()- ...
But these new additions are not supported on some lower browsers, so we need to use webpack to compile our es6+ into a version that these lower browsers can support.
Let's start with the learn-05 case and see how we configure webpack to compile es6+.
We install the relevant dependencies:
...
"devDependencies": {
"@babel/core": "^7.22.8",
"@babel/plugin-transform-runtime": "^7.22.7",
"@babel/preset-env": "^7.22.7",
"babel-loader": "^9.1.3",
"webpack": "^5.88.1",
"webpack-cli": "^5.1.4"
},
"dependencies": {
"core-js": "^3.31.1"
},
Entry files. Uses es6+ syntax such as class, Promise, ()=>{} and API:
// index.js
class People {
constructor(name) {
this.name = name;
}
sayHi() {
return Promise.resolve(this.name);
}
}
const Lee = new People('Lee');
Lee.sayHi().then(name => console.log(`Hi, I am ${name}.`));
Configure webpack:
// webpack.config.js
module.exports = {
...,
module: {
rules: [
{
test: /\.m?js$/,
exclude: /(node_modules|bower_components)/,
use: {
loader: 'babel-loader'
}
}
]
}
}
Configure Babel. Create a new babel.config.js file in the project root directory:
// babel.config.js
const presets = [
[
'@babel/preset-env',
{
useBuiltIns: 'usage',
corejs: {
version: require('core-js/package.json').version,
proposals: true
}
}
]
];
const plugins = [
'@babel/plugin-transform-runtime',
];
module.exports = {presets, plugins}
Set the target browser to be compatible with. Add the browserslist field to package.json:
"browserslist": [
"ie 11"
]
The result of running it in ie 11:
We will find:
- The
es6+we wrote runs successfully inie 11. -
Promise, thees6+API, has also been added toie 11.
It means that our compilation of es6+ was successful.
About Babel
In the configuration above, you will notice that if we want to compile es6+ with webpack, we also need to add the babel.config.js file to the root directory, which is a much more complicated and troublesome step than dealing with other modules. This is because compiling the core of es6+ requires Babel to work with it. Babel is a tool for compiling es6+.
Since this post is mainly about webpack, we'll just give a general mention of Babel here. Here are some common configurations for Babel.
- If the project we are developing is an application or a large project, we can configure it like this:
const presets = [
[
'@babel/preset-env',
{
modules: false,
useBuiltIns: 'entry', // or useBuiltIns: 'usage',
corejs: {
version: '3.27.2',
proposals: true
}
}
]
];
const plugins = [
'@babel/plugin-transform-runtime'
];
module.exports = {plugins, presets};
// index.js
// If use useBuiltIns: 'entry'
import 'core-js/stable'
- If we are trying to develop a third party library, we can configure it like this:
// Babel配置
const presets = [
[
'@babel/preset-env',
{
modules: false
}
]
];
const plugins = [
[
'@babel/plugin-transform-runtime',
{
corejs: {
version: 3,
proposals: true
}
}
]
];
module.exports = {plugins, presets};
Summary
- If
jsisimportedorrequiredinto our source code, then it is also a module. So we have to download the correspondingloader(babel-loader) and configure it in themoduleconfiguration. - In addition, we need to configure
babel-loaderand, most importantly,Babel(babel.config.js).
So, if we want to "compile es6+", we need to configure webapck, and most importantly we need to configure babel.config.js. If you don't want to just copy and paste the Babel configuration, you have to learn about Babel.
Remember what we use webpack for? To output css, img, js, html and other front-end resources that the browser can run.
OK, so far we have processed css, img, js through webpack. Let's take a look at how we can get our html through webpack processing.
Processing html files
In the above example, we want to see the effect in the browser, we need to:
- Create a new
htmlfile in the root directory. - In the new
htmlfile, we need to bring in the packaged resource files manually.
This process is too troublesome, is there a way, we just provide a html template file, and then through the webpack compilation, it automatically help us to pack the packaged files into the good. This way, we can run html directly after packaging and see the effect in the browser.
webpack is so user-friendly, of course there is.
Let's start by using the learn-06 example here to see how we can utilize webpack to achieve the results we described above.
Install the relevant plugins:
npm i html-webpack-plugin -D
This time, the webpack configuration is a little different:
We set the packaged js storage directory to be the js folder; and we add a hash value of 5 lengths to the packaged js name.
// webpack.config.js
const HtmlWebpackPlugin = require('html-webpack-plugin');
const path = require('path');
module.exports = {
entry: {
index: './src/index.js'
},
output: {
path: path.resolve(__dirname, './dist'),
filename: './js/[name]-[chunkhash:5].js',
clean: true
},
plugins: [
new HtmlWebpackPlugin({
filename: path.resolve(__dirname, './dist/[name].html'),
template: path.resolve(__dirname, './index.html'),
title: 'HtmlWebpackPlugin',
})
],
}
The structure of the packaged file is:
dist
├── index.html
└── js
└── index-efbfd.js
The packaged html is as follows:
We will find:
- Our
htmlandjsare packaged and exported to thedistfolder, which is very convenient for us to deploy (before we createdindex.htmlin the root directory, so there are onlyimgandjsfiles in thedistfolder after packaging). - The packaged
htmlwill automatically bring in our packagedjsfile for us.
Analyzing
As we can see from the above example, if we want webpack to process html files, we need to configure it in plugins provided by webpack. Some of you may wonder why html is a module and why it is configured in plugins and not in module. Let's analyze it.
All the files of our project can be considered as a module, but whether we configure them in module or plugins depends on what we want to use them for. Generally, if we use the module in our own source code, we need a Loader to parse it**.
When we explained how to deal with img and js above, our purpose was to parse these files in the source code:
-
img, which we need to convert tobase64 -
js, we need to compilees6+stuff intoes5and below
And, our files are introduced into our project by import or require(), so of course we need the appropriate Loader to convert these modules.
But when dealing with html files, our purpose is not to parse the html, we just want the packaged html to automatically reference our js and img, which is more like using the auto-introduction feature; moreover, we don't introduce our html into our project, so of course we don't need the appropriate Loader to parse it.
Remember from our previous post we explained that Loader is used to transform the modules, and Plugin is used to enhance the webpack package when compiling.
In this case, we are dealing with the html file, and our goal is to make the packaged html automatically reference our js and img. So we need to configure the plugins configuration item to enhance the webpack packaging and compilation functionality.
Similarly, suppose we want to parse an html file in our project (in our project, import html from '. /x.html'), then we have to install the appropriate loader (html-loader) and configure it in the module configuration item.
Summary
Whether to configure in the module or plugins configuration item depends on the purpose for which we are using these modules.
At this point, we have successfully configured webpack to get the css, img, js, and html we need for a project; this is also equivalent to learning the basic configuration of webpack.
You can use the methods summarized above to handle sass, font, video and other resources on your own to deepen your impression.
Learning Summary
From the above explanation of some configuration items, we can have the following summary:
- To parse
css, we need to install theloaderand configure it in themodule. - To parse
img,font,video, etc., we don't need to install theloader(webpackhas built-in functionality to parse them). We usually useasset/resource,asset/inline,assetinmoduleconfiguration to parse them. - To parse
js, we need to install the appropriateloader(babel-loader), configure it in themoduleconfiguration, and most importantly, learn aboutBabel. - To parse the
htmlfile, we need to configure thehtml-webpack-pluginplugin in thepluginsconfiguration field. - Whether we configure it in the
moduleorpluginsconfiguration depends on what we want to do with the modules.
With the above learning, let's organize and output a complete webpack base configuration to make it more impressive:
const HtmlWebpackPlugin = require('html-webpack-plugin');
const path = require('path');
module.exports = {
entry: {
index: './src/index.js'
},
output: {
path: path.resolve(__dirname, './dist'),
filename: './js/[name]-[chunkhash:5].js',
clean: true
},
module: {
rules: [
{
test: /.(css|less)$/,
use: [
'style-loader',
'css-loader',
'less-loader',
],
},
{
test: /\.(png|svg|jpg|jpeg|gif)$/i,
type: 'asset',
parser: {
dataUrlCondition: {
maxSize: 1024 * 10 // When the image size is < 10kb it will be converted to base64
}
},
generator: {
filename: '[name]-[hash:5][ext]' // Set the name of the output file
}
},
{
test: /\.m?js$/,
exclude: /(node_modules|bower_components)/,
use: {
loader: 'babel-loader'
}
}
]
},
plugins: [
new HtmlWebpackPlugin({
filename: path.resolve(__dirname, './dist/[name].html'),
template: path.resolve(__dirname, './src/index.html'),
title: 'Webpack Basic Configuration',
})
],
}
The full base configuration is at learn-07, and we recommend that you take a look at the full version, only webpack.config.js is posted here.
Finally
- I hope some of the methods summarized in this article for learning purposes will help you learn how to configure
webapckbetter. - Later articles will be in-depth configuration. In real projects, most of them are divided into development and production environments, so we will learn how to configure
webpackdifferently for different environments of development and production, which is closer to our real projects. - You can support me by following my github!
Regarding the content of the article, if you have similarities and differences, feel free to discuss them in the comments section!




Top comments (0)