Small knowledge, big challenge! This article is participating in the creation activity of “Essential Tips for Programmers”
This article has participated in the “Digitalstar Project” and won a creative gift package to challenge the creative incentive money.
The introduction
Webpack is the most commonly used project builder on the front end, but is often discouraged by its cumbersome configuration. This article will walk you through the basics of configuring WebPack step by step
What is the Webpack
Webpack is by far the most common front resources build tools, in Webpack view, front end all resource files (. CSS/js/JSX/img/PNG/sass…). Will be treated as modules. Depending on the structure of your project, Webpack packs ES6 and other extension languages that browsers can’t use directly, such as typescript, Sass, Vue, etc., with Loaders processing into a language that browsers can read so that it works correctly on the browser
Installation and use
- Create a folder and use
npm init -y
Initialize the NPM
mkdir webpack
cd webpack
npm init -y
Copy the code
- The installation
webpack
,webpack-cli
npm install webpack webpack-cli -D
Copy the code
- new
src
Folder, newindex.html
andindex.js
, modifyindex.js
// index.js
console.log('hello webpack! ')
Copy the code
- Enter on the console
npx webpack
npx webpack
Copy the code
You can see that the dist folder is generated in the root directory of the project, and there is main.js in it, indicating that webpack is successfully packaged!
Webpack basic configuration
Create the webpack configuration file webpack.config.js in the project root directory
Entrance to the entry
Entry specifies the entry file that WebPack builds, which determines the module from which WebPack starts generating the dependency graph
// webpack.config.js
module.exports = {
/ / the entry
entry: {
main: './src/index.js'}}Copy the code
Multiple entry configuration:
// webpack.config.js
module.exports = {
/ / the entry
entry: {
one: './src/one.js'.two: './src/two.js'}}/ / or
module.exports = {
/ / the entry
entry: {
main: [
'./src/one.js'.'./src/two.js']}}Copy the code
Export output
The Output field specifies where WebPack should output the file it builds, Path, and how to name filename
// webpack.config.js
const path = require('path')
module.exports = {
/ / the entry
entry: {
main: './src/index.js'
},
/ / export
output: {
path: path.resolve(__dirname, 'dist'), // ./dist
filename: 'main.js'}}Copy the code
Pattern mode
Provides the mode configuration option to tell WebPack to use the built-in optimizations for the corresponding mode.
- development
The value of process.env.node_env is set to development. Enable NamedChunksPlugin and NamedModulesPlugin.
module.exports = {
// ...
mode: 'development'
}
Copy the code
- production
The value of process.env.node_env is set to production. Enable FlagDependencyUsagePlugin FlagIncludedChunksPlugin…
module.exports = {
// ...
mode: 'production'
}
Copy the code
You can also specify the packaging mode when you run the packaging command
npx webpack --mode developmenet
Copy the code
Loader
Loaders is one of the core concepts of Webpack, because webPack can only handle JS files by default, so when you encounter other file types CSS/JPG/PNG /ts… For example, convert ES6 to ES5 that can be read by the browser, convert TypeScript to JavaScript, convert Sass to CSS. It is similar to the machines on a factory assembly line, which process and package raw materials step by step to produce a usable product
Loaders configuration has only a few simple items (* is mandatory) :
- Test: matches the regular expression of the corresponding file format (*)
- Use: Loader to use (*)
- Include /exclude: files to be processed or files not to be processed
Use file-loader to package JPG/PNG/GIF images
const path = require('path')
module.exports = {
mode: 'development'.entry: {
main: './src/index.js'
},
output: {
path: path.resolve(__dirname, 'dist'),
filename: 'main.js'
},
module: {
rules: [{test: /.(jpg|png|gif)$/,
use: {
loader: 'file-loader'.options: { // Provide additional configuration for loader (optional)
// placeholder []
name: '[name].[ext]'.// Use the original filename and suffix
// Can also be [name]_[hash].[ext] filename _ hash
outputPath: 'images/' // Output path}}}]}}Copy the code
Run NPX webpack and you can see the image in the dist directory
Use url-loader to package images
Url-loader converts the image format to Base64
const path = require('path')
module.exports = {
mode: 'development'.entry: {
main: './src/index.js'
},
output: {
path: path.resolve(__dirname, 'dist'),
filename: 'main.js'
},
module: {
rules: [{test: /.(jpg|png|gif)$/,
use: {
loader: 'url-loader'.options: {
name: '[name].[ext]'.// Use the original filename and suffix
outputPath: 'images/'.limit: 2048 // Limit files to 2048 bytes, i.e. 2KB
// If so, use file-loader}}}]}}Copy the code
If we want to change the image style to 300px width and height, we usually create an index. CSS file, write the style and import it in the index.js file
.avatar {
width: 300px;
height: 300px;
}
Copy the code
In the index.js file
import image from './psc.jpg'
import './index.css'
const img = new Image()
img.src = image
img.className += 'avatar'
const app = document.getElementById('app')
app.appendChild(img)
Copy the code
If you run NPX webpack, you can see the console error:
This is because WebPack cannot parse.css
File, at this point we need the corresponding Loader to handle this type of file CSS file
Use CSS-loader and style-loader to package styles
Install CSS-loader and style-loader
npm install css-loader style-loader -D
Copy the code
// webpack.config.js
{
test: /.css$/,
use: [
'style-loader'.'css-loader'.'postcss-loader'.'sass-loader']}Copy the code
Note that the plugin array is executed from bottom up/right to left
Use sass-Loader to process SCSS files
npm install sass sass-loader -D
Copy the code
body {
.avatar {
width: 300px;
height: 300px; }}Copy the code
Execution sequence: Sass -loader converts sASS files to CSS files, and then submits them to CSS-loader and style-loader
module.exports = {
// ...
{
test: /.scss$/,
use: [
'style-loader'.'css-loader'.'sass-loader']}}Copy the code
Prefixes the CSS3 properties with the browser
For some CSS3 properties, we want to prefix it with the corresponding browser (for example, -webkit-) to ensure that it works correctly across browsers. Postcss-loader automatically prefixes the browser for us
npm install postcss postcss-loader autoprefixer -D
Copy the code
// webpack.config.js
// ...
{
test: /.css$/,
use: [
'style-loader'.'css-loader'.'postcss-loader'.'sass-loader']}Copy the code
New postcss. Config. Js
// postcss.config.js
module.exports = {
plugins: [
require('autoprefixer') // Introduce the Autoprefixer plugin]}Copy the code
The plugin is internally prefixed by the browserslist property in package.json, so we need to configure package.json accordingly
// package.json
"browserslist": [
"1%" >.// Browsers compatible with 1% of the market are required
"last 2 versions" // Need to be compatible with both versions
]
Copy the code
Babel processing ES6
Install the loader
npm install -D babel-loader @babel/core @babel/preset-env
Copy the code
Note: There are three modules to install, don’t miss out =.=
const path = require('path')
const HtmlWebpackPlugin = require('html-webpack-plugin')
const { CleanWebpackPlugin } = require('clean-webpack-plugin')
module.exports = {
mode: 'development'.entry: {
main: './src/index.js'
},
output: {
filename: 'bundle.js'.path: path.resolve(__dirname, 'dist')},module: {
rules: [{test: /\.js$/,
exclude: /node_modules/,
use: {
loader: 'babel-loader'.options: {
presets: ['@babel/preset-env'}}}, {test: /.(jpg|png|gif)$/,
use: {
loader: 'url-loader'.options: {
name: '[name]_[hash].[ext]'.outputPath: 'images/'}}}]},plugins: [
new HtmlWebpackPlugin({
template: './src/index.html'
}),
new CleanWebpackPlugin()
]
}
Copy the code
Package the output main.js/bundle.js
As you can see, there is a problem here: Babel can only convert ES6 syntax, not new apis. Global objects such as Generator, Set, Maps, Proxy, Symbol, Promise, Async, and some methods defined on global objects such as Object.assign cannot be converted. For these, we can use Babel-polyfill
Babel handles the new ES6 API
Install (be careful to use –save, because the online environment is also needed) :
npm install @babel/polyfill --save
Copy the code
Introduce babel-polyfill in the index.js file
import '@babel-polyfill'
Copy the code
Packaged outputmain.js
As you can see, there is a lot more code in main.js. The size of the packed JS file is 405KB, while the size of the code before babel-polyfill was only 264 Bytes. Why are the sizes of the packed files so different?The reason is thatwebpack
thebabel-polyfill
The whole thing is packed in. whilebabel-polyfill
And certainly all of themA new API ES6
The gasket, the file must not be small.
We can add the useBuiltIns configuration to babel-Loader to tell babel-Polyfill to package only the ES6 code used to avoid unnecessary packaging and reduce the volume of packaging output.
// webpack.config.js
modules.exports = {
// ...
module: {
rules: [{test: /\.js$/,
use: {
loader: 'babel-loader'.options: {
presets: [['@babel/preset-env',
{
useBuiltIns: 'usage'}}}}}Copy the code
After entering the command, you can see that the size of the packaged output code is 192KB, which is significantly smaller
Plugin
Plugin is another core concept of WebPack, which can extend the functionality of WebPack when it reaches a certain stage. Two commonly used plugins are recommended
- html-webpack-plugin
The HTML-webpack-plugin automatically generates HTML files after packaging and injects the packed results into HTML.
The installation
npm install html-webpack-plugin -D
Copy the code
use
const path = require('path')
const HtmlWebpackPlugin = require('html-webpack-plugin')
module.exports = {
mode: 'development'.entry: {
main: './src/index.js'
},
output: {
path: path.resolve(__dirname, 'dist'),
filename: 'main.js'
},
module: {
rules: [{test: /.(jpg|png|gif)$/,
use: {
loader: 'file-loader'.options: { // Provide additional configuration for loader (optional)
// placeholder []
name: '[name].[ext]'.// Use the original filename and suffix
// Can also be [name]_[hash].[ext] filename _ hash
outputPath: 'images/' // Output path}}}]},plugins: [
new HtmlWebpackPlugin()
]
}
Copy the code
Receive Template Configuration
const path = require('path')
const HtmlWebpackPlugin = require('html-webpack-plugin')
module.exports = {
mode: 'development'.entry: {
main: './src/index.js'
},
output: {
path: path.resolve(__dirname, 'dist'),
filename: 'main.js'
},
module: {
rules: [{test: /.(jpg|png|gif)$/,
use: ['file-loader']}}]},plugins: [
new HtmlWebpackPlugin({
template: './src/index.html'}})]Copy the code
Here we let the process of importing the index.js file after packaging be injected into index.html automatically
- clean-webpack-plugin
Each time before the NPM run build we need to manually delete the dist folder. The clean-webpack-plugin can automatically delete the dist folder before exporting the packaged file
The installation
npm install clean-webpack-plugin -D
Copy the code
use
const path = require('path')
const HtmlWebpackPlugin = require('html-webpack-plugin')
const { CleanWebpackPlugin } = require('clean-webpack-plugin')
module.exports = {
mode: 'development'.entry: './src/index.js'.output: {
path: path.resolve(__dirname, 'dist'),
filename: 'bundle.js'
},
plugins: [
new HtmlWebpackPlugin({
template: './src/index.html'
}),
new CleanWebpackPlugin()
]
}
Copy the code
SourceMap
The browser actually executes the webpack-processed main.js or bundle.js file at runtime, and the problem is that if there is an error in the code, the browser in the console points to the packaged main.js file, which means that if we make an error at line 5 of the source code, You don’t know what line you’re pointing to in packaged code. That’s where SourceMap comes in. SourceMap is a technology that maps compiled, packaged, and compressed code back to the source code, pointing it exactly where the source code is
Configuration SourceMap
// Development environment
module.exports = {
mode: 'development'.devtool: 'cheap-module-source-map'.entry: './src/index.js'.output: {
path: path.resolve(__dirname, 'dist'),
filename: 'main.js'
},
plugins: [
new HtmlWebpackPlugin({
template: './src/index.html'
}),
new CleanWebpackPlugin()
]
}
Copy the code
WebpackDevServer
We need to re-run NPX Webpack every time we change the code to see the effect of the changes. Is there any way in WebPack that we can automatically package the changes after we save them? Webpack-dev-server can start a server locally and have the packaged output file run on the server, so that after we change the code save, webpack-dev-server will automatically package for us
The installation
npm install webpack-dev-server -D
Copy the code
Add the following command to package.json
// package.json
"scripts": {
"watch": "webpack --watch"."start": "webpack serve"
}
Copy the code
Run NPM run start to start the Webpack server at localhost:8080
Open: Automatically opens the browser
// webpack.config.js
devServer: {
contentBase: './dist'.// webpack-dev-server3
open: true
}
Copy the code
After running NPM run start, you can see that Webpack automatically opens the browser for us and visits localhost:8080
Use WebpackDevServer to implement request forwarding
HTTP requests are often used during development, and the proxy can forward the request to another URL when you request an interface
// webpack.config.js
module.exports = {
// ...
devServer: {
contentBase: './dist'.proxy: {
'/api': {
target: 'http://localhost:3000'}}}}Copy the code
axios.get('/api/users').then(res= > {
// ...
})
Copy the code
This time, if send the request to the/API/users, is the agent to request to http://localhost:3000/api/users.
The HMR module is hot replaced
There is no need to refresh the page, save and update. This means that content already rendered to the page does not disappear, but is automatically applied directly to the page based on the modified code
const path = require('path')
const HtmlWebpackPlugin = require('html-webpack-plugin')
const { CleanWebpackPlugin } = require('clean-webpack-plugin')
module.exports = {
mode: 'development'.entry: {
main: './src/index.js'
},
devserver: {
contentBase: './dist'.open: true.hot: true / / open HMR
},
output: {
filename: 'bundle.js'.path: path.resolve(__dirname, 'dist')},module: {
rules: [{test: /.(jpg|png|gif)$/,
use: {
loader: 'url-loader'.options: {
name: '[name]_[hash].[ext]'.outputPath: 'images/'}}}]},plugins: [
new HtmlWebpackPlugin({
template: './src/index.html'
}),
new CleanWebpackPlugin()
]
}
Copy the code
Note: HMR is turned on by default in Webpack4
conclusion
This article introduces the following basic configuration of Webpack, hoping to help the front end of the small white start Webpack, Webpack configuration process looks very complex, from the webpack official website can also see configuration items are also very much, but do not be scared by its cumbersome surface, mainly clear webpack logic, Step by step to configure the corresponding items, in fact, Webpack is also (zhen) this (de) like (nan)
Finally, if this article has been helpful to you, leave a like