preface
I have written about the core configuration concept and basic practice of Webpack before. Today, I mainly share the configuration and actual combat of Webpack for various situations
Webpack configuration concepts
Webpack basic practices
What do loaders and plugins do?
- Loader: file loader, because webpack is written with node, so can only identify JS files, and loader is used to identify and convert files
- Plugins: A plugin mechanism that broadcasts a series of events during Webpack execution. Plugins listen for these events and use the WebPack Api to process output files accordingly
Ok, start extension based on a basic practice demo from the previous chapter. If you want to start from 0, you can see the link to basic practice above.
The directory structure
webpack // Project directory
dist // Build build directory
bundle.js
index.html
main.js
utils.js
webpack.config.js
package.json
node_modules
main.css
Copy the code
webpack.config.js
const path = require('path');
module.exports = {
entry: './main.js'.// Import file
output: {
// Merge all dependent modules into a bundle.js file
filename: 'bundle[hash:6].js'.// Put the output files in the dist directory
// __dirname points to the current directory
path: path.resolve(__dirname, './dist'),},//mode:"production",
devServer: {// Local services
port:"1234".// Start port
progress:true./ / the progress bar
open:true // Automatically open the browser}};Copy the code
HTML plugin HTML – webpack – the plugin
For a single page SPA, we generate a dist directory every time we package. The dist directory usually contains bundled bundle.js and an entry file named index.html. Where did index.html come from?
Ok, it is actually generated by the HTML-webpack-plugin. The main principle is to create a new file based on a template file and automatically introduce bundle.js and other packaged CSS files
HTML – webpack – the plugin installation
cnpm install html-webpack-plugin -D
Copy the code
Webpack. Config. Js configuration
const path = require('path');
// Import the html-webpack-plugin
const HtmlWebpackPlugin = require("html-webpack-plugin");
module.exports = {
entry: './main.js'.output: {
filename: 'bundle[hash:6].js'.path: path.resolve(__dirname, './dist'),},devServer: {port:"1234".progress:true.open:true},plugins: [
// Use plug-in mode
new HtmlWebpackPlugin({
template: "./index.html".// Template HTML file
filename: "index.html".// New HTML file name after packaging
minify: { // Some optimizations
removeAttributeQuotes: true.// remove quotes
removeEmptyAttributes: true.// Remove the empty attribute
collapseWhitespace: true // remove whitespace
// There are many more}}})];Copy the code
This can be done with a plug-in that generates a new entry file in the dist directory every time it is packaged, and automatically introduces the packaged JS and CSS
Style to deal with
Actually in the work, we will write some styles, in addition to CSS, but also use some less,sass and other preprocessors, the browser itself is not recognized, in fact, is the credit of Webpack, use some loader can not recognize less or Sass conversion into CSS, Insert the style tag into the HTML, and there you go. See what it does.
Install style-loader CSS-loader less less-loader
cnpm install style-loader css-loader -D
cnpm install less less-loader -D
Copy the code
Webpack. Config. Js configuration
const path = require('path');
// Import the html-webpack-plugin
const HtmlWebpackPlugin = require("html-webpack-plugin");
module.exports = {
entry: './main.js'.output: {
filename: 'bundle[hash:6].js'.path: path.resolve(__dirname, './dist'),},devServer: {port:"1234".progress:true.open:true},module: { // Where the loader is mainly used
rules: [
// To configure the loader for packing CSS files, use defines the loader to be used, and pay attention to the sequence
// style-loader must be placed before CSS-loader because loader is executed from right to left
{
test: /\.css$/.// Matches files with a.css suffix
use: ['style-loader'.'css-loader']]}}plugins: [
// Use plug-in mode
new HtmlWebpackPlugin({
template: "./index.html".// Template HTML file
filename: "index.html".// New HTML file name after packaging
minify: { // Some optimizations
removeAttributeQuotes: true.// remove quotes
removeEmptyAttributes: true.// Remove the empty attribute
collapseWhitespace: true // remove whitespace
// There are many more}}})];Copy the code
Another configuration of rule can be written as an object, since several other configuration items are also supported
{
test: /\.(css|less)$/.// Matches files ending in.less or.css
use: [
{
loader: "style-loader".options: {
// Other related Settings}},'css-loader'.// Parse the @import path
'less-loader' // Resolve less to CSS]},Copy the code
Explain how CSS styling works in the configuration above
- The loader execution sequence is from right to left. Therefore, less-loader is executed to convert less to CSS
- It is then parsed by CSS-loader and passed by @import to style-loader
- Finally, style-loader will load the parsed CSS into the style tag and place it in the HTML head
- Ok browser can recognize and render it
In real development, it’s not always possible to embed the style tag in the head, so we can use the plugin mechanism to separate out the CSS, package it separately and import it through the link tag
Css out of mini – Css – extract – the plugin
Install the mini – CSS – extract – the plugin
npm install mini-css-extract-plugin -D
Copy the code
Webpack. Config. Js configuration
const path = require('path');
// Import the html-webpack-plugin
const HtmlWebpackPlugin = require("html-webpack-plugin");
/ / CSS
const MiniCssExtractPlugin = require("mini-css-extract-plugin");
module.exports = {
entry: './main.js'.output: {
filename: 'bundle[hash:6].js'.path: path.resolve(__dirname, './dist'),},devServer: {port:"1234".progress:true.open:true},module: { // Where the loader is mainly used
rules: [
// To configure the loader for packing CSS files, use defines the loader to be used, and pay attention to the sequence
// style-loader must be placed before CSS-loader because loader is executed from right to left
{
test: /\.css$/.// Matches files with a.css suffix
use: ['style-loader'.'css-loader']]}}plugins: [
// Use plug-in mode
new HtmlWebpackPlugin({
template: "./index.html".// Template HTML file
filename: "index.html".// New HTML file name after packaging
minify: { // Some optimizations
removeAttributeQuotes: true.// remove quotes
removeEmptyAttributes: true.// Remove the empty attribute
collapseWhitespace: true // remove whitespace
// There are many more}}),// Add a CSS extraction plug-in
new MiniCssExtractPlugin({
filename: "main.css".// CSS The extracted file name can be configured as a path, for example, CSS /main.css.
// There are many configuration items, please check the documentation, only listed here}})];Copy the code
Another way to use the MiniCssExtractPlugin, for example, to remove CSS or less, is to use the MiniCssExtractPlugin in the Loader configuration rule as follows:
After the CSS conversion is complete, use the MiniCssExtractPlugin to extract it from the page with the link tag
/ / CSS examples
{
test: /\.css$/,
use: [
MiniCssExtractPlugin.loader,
'css-loader'.// Parse the @import path]},/ / less sample
{
test: /\.less$/,
use: [
MiniCssExtractPlugin.loader,
'css-loader'.// Parse the @import path
'less-loader' // Resolve less to CSS]},Copy the code
extension
- You can use postCSs-loader to prefix CSS styles for browser compatibility
- The plugin optimize- CSS -assets-webpack-plugin is used to compress CSS, and uglip-js-plugin is used to compress JS
Convert ES6 to ES5
Bable is used here, mainly for converting JS syntax
The installation
// babel-loader Specifies the loader for Babel
// @babel/core Babel's core module
// @babel/preset-env converts ES6 to ES5
npm install babel-loader @babel/core @babel/preset-env -D
Copy the code
Webpack. Config. Js configuration
const path = require('path');
// Import the html-webpack-plugin
const HtmlWebpackPlugin = require("html-webpack-plugin");
/ / CSS
const MiniCssExtractPlugin = require("mini-css-extract-plugin");
module.exports = {
entry: './main.js'.output: {
filename: 'bundle[hash:6].js'.path: path.resolve(__dirname, './dist'),},devServer: {port:"1234".progress:true.open:true},module: { // Where the loader is mainly used
rules: [
// To configure the loader for packing CSS files, use defines the loader to be used, and pay attention to the sequence
// style-loader must be placed before CSS-loader because loader is executed from right to left
{
test: /\.css$/.// Matches files with a.css suffix
use: ['style-loader'.'css-loader']},// js => es6 convert es5
{
test:/\.js$/.// Matches files with the.js suffix
use:{ // This is written as an object
loader: 'babel-loader'.options: {
presets: ['@babel/preset-env'].// Convert es6 to ES5
plugins: [ // You can also configure plugins for a single loader, as described in the documentation
// Convert the class syntax to recognize some advanced syntax
["@babel/plugin-proposal-class-properties", { "loose" : true}]}}}]}plugins: [
// Use plug-in mode
new HtmlWebpackPlugin({
template: "./index.html".// Template HTML file
filename: "index.html".// New HTML file name after packaging
minify: { // Some optimizations
removeAttributeQuotes: true.// remove quotes
removeEmptyAttributes: true.// Remove the empty attribute
collapseWhitespace: true // remove whitespace
// There are many more}}),// Add a CSS extraction plug-in
new MiniCssExtractPlugin({
filename: "main.css".// CSS The extracted file name can be configured as a path, for example, CSS /main.css.
// There are many configuration items, please check the documentation, only listed here}})];Copy the code
The image processing
There are generally three ways to write images in development, and webPack has a corresponding way to handle these three cases
- Create an image in Js
File - loader or url - loader
- Introduce images to CSS
The default CSS loader converts to require
- The IMG tag is used in HTML
html-withimg-loader
The installation
// file-loader will generate img images in the package build directory
// url-loader
npm install babel-loader file-loader url-loader -D
npm install babel-loader html-withimg-loader -D
Copy the code
Webpack. Config. Js configuration
const path = require('path');
// Import the html-webpack-plugin
const HtmlWebpackPlugin = require("html-webpack-plugin");
/ / CSS
const MiniCssExtractPlugin = require("mini-css-extract-plugin");
module.exports = {
entry: './main.js'.output: {
filename: 'bundle[hash:6].js'.path: path.resolve(__dirname, './dist'),},devServer: {port:"1234".progress:true.open:true},module: { // Where the loader is mainly used
rules: [
// To configure the loader for packing CSS files, use defines the loader to be used, and pay attention to the sequence
// style-loader must be placed before CSS-loader because loader is executed from right to left
{
test: /\.css$/.// Matches files with a.css suffix
use: ['style-loader'.'css-loader']},// js => es6 convert es5
{
test:/\.js$/.// Matches files with the.js suffix
use:{ // This is written as an object
loader: 'babel-loader'.options: {
presets: ['@babel/preset-env'].// Convert es6 to ES5
plugins: [ // You can also configure plugins for a single loader, as described in the documentation
// Convert the class syntax to recognize some advanced syntax
["@babel/plugin-proposal-class-properties", { "loose" : true}]]}}},// Image loader processing
{
test: /\.(jpg|png|gif)$/.// Match files with JPG, PNG, GIF suffixes
use: {
loader: 'file-loader'.// For creating images with js
options: {esModule: false.// Compress the image path
outputPath: '/img/'.// Package and store in img folder, can be customized, the same as url-loader
publicPath: 'htpp://localhost' // Add the domain name before the path. You can also export the public configuration in outout}},Alternative file - / * url - loader loader {test: / \. (JPG | PNG | GIF) $/, / / match suffix JPG, PNG, GIF suffix file use: {loader: 'url-loader', // images do not need to be output, you can give a size limit, using base64 options: {limit:200*1024 // limit 200K use base64 format // other configuration reference document}}, */
{
test: /\.html$/, matches the file with the suffix HTMLuse: 'html-withimg-loader' // Path identification for the img tag SRC in HTML]}},plugins: [
// Use plug-in mode
new HtmlWebpackPlugin({
template: "./index.html".// Template HTML file
filename: "index.html".// New HTML file name after packaging
minify: { // Some optimizations
removeAttributeQuotes: true.// remove quotes
removeEmptyAttributes: true.// Remove the empty attribute
collapseWhitespace: true // remove whitespace
// There are many more}}),// Add a CSS extraction plug-in
new MiniCssExtractPlugin({
filename: "main.css".// CSS The extracted file name can be configured as a path, for example, CSS /main.css.
// There are many configuration items, please check the documentation, only listed here}})];Copy the code
To configure the source – the map
What is source-map? Source-map is the source map, because we package it, release it, and once there’s a problem, the code gets confused and compressed, and it’s hard to locate the problem code, and source-Map is there to solve it
module.exports = {
entry: { / * * / has been eliminated},
// Correspond to multiple exits
output: { / * * / has been eliminated}
/ / 1. Source code mapping, generate a separate sourcemap file, error when directly prompted error line
devtool: 'source-map'.// Large and complete Settings
/ / 2. Source map, does not produce a separate file, single will directly display the error column
// devtool: 'eval-source-map',
/ / 3. No columns are generated, but a separate mapping file is generated
// devtool: 'cheap-module-source-map', // can be retained after generation
/ / 4. No files are generated, and no columns are generated in the integrated repackaged files
// devtool: 'cheap-module-source-map', // can be retained after generation
}
Copy the code
Watch Real-time packaging
This feature is actually not very practical, so let me give you a brief introduction
Install the clean-Webpack-plugin and pack in real time each time, making sure the dist directory is up to date
cnpm install clean-webpack-plugin -D Clear the dist directory before packing
// Extend two plug-ins
cnpm install copy-webpack-plugin -D // Copy files from a directory to a specified directory
bannerPlugin // Copyright notice plugin, built-in in Webpack
Copy the code
module.exports = {
entry: { / * * / has been eliminated},
// Correspond to multiple exits
output: { / * * / has been eliminated}
/ / 1. Source code mapping, generate a separate sourcemap file, error when directly prompted error line
devtool: 'source-map'.// Large and complete Settings
// Enable monitoring, real-time packaging Settings
watch: true.watchOptions: {// Set monitoring options
poll: 1000.// Query 1000 times per second
aggregateTimeout: 500.// Start packing after CTRL + S
ignored: /node_modules/.// Ignore folders that do not need to be monitored
},
plugins: [new CleanWebpackPlugin(), // Delete dist directory before packing]}Copy the code
How does WebPack handle cross-domain
Cross domain should be a common problem in the front end, generally may be dealt with by the back end, then there is a corresponding solution in Webpack, proxy
export.modules{
entry: { / * * / has been eliminated},
// Correspond to multiple exits
output: { / * * / has been eliminated}
// webpack.config.js
devServer{
// Configure the proxy
proxy: {'/api': { // Intercepts requests containing/API in the url of the request interface
target: 'http://localhost:3000'.// Forwards the proxy to the domain name
pathRewrite: {'^/api':' '}, // Replace the beginning/API in the request path with empty
changeOrigin: true.// Target is a domain name.
secure: false.// Set a proxy that supports HTTPS}}}}Copy the code
PathRewrite is a configuration item to be aware of, because in real development, the back-end interface may not be so desirable, and it is not possible for every interface to have/API. The purpose of this configuration item is that our front-end will have/API on request, and then when the WebPack proxy proxy matches and replaces it.
Resolve Resolve third-party packages
This configuration is very interesting and is a magic tool for our development. It is directly related to the configuration of the path for importing files, images and other resources for different levels of components
export.modules{
entry: { / * * / has been eliminated},
// Correspond to multiple exits
output: { / * * / has been eliminated}
// Parse third-party packages
resolve: {// Parse the directory for the file search
modules:[path.resolve('node_modules')].Import A form "... /a"
extensions: ['.js'.'.css'.'.json'.'.vue'].// Delimit the extension, parsed in order
// Set alias, import 'bootstrap' when index.js is introduced
Improt X from "@components/ XXX "// Improt X from "@components/ XXX"
alias: {bootstrap:'bootstrap/dist/css/bootstrap.css'.'@Components': path.resolve(__dirname, 'src/components/'),},// Other reference documents}},Copy the code
Pack multiple pages [multiple entry, multiple exit]
In fact, packaging multiple pages, relatively easy to understand, is multiple entry, corresponding to multiple exit, here to do a simple example, easy to understand
// Multi-entry configuration
entry: {
home: './src/index.js'.other: './src/other.js'
},
// Correspond to multi-egress configuration
output: {
// Multiple exit Settings, [name] represents multiple entry variable names home,other, one by one packaging
filename: '[name].js'.// Name is a built-in variable that points to the entry entry configured with the corresponding key
// path: path.resolve(__dirname, 'dist'),
path: path.resolve(__dirname, 'dist'),
// publicPath: 'http://localhost'
},
// html-webpack-plugin generates multiple files for the configuration
plugins: [
new HtmlWebpackPlugin({
template: "./index.html".filename: "index.html".chunks: ['home'].// Multi-page package Settings, corresponding to entry js
}),
// Multi-page packaging, multiple new HtmlWebpackPlugin
new HtmlWebpackPlugin({
template: "./other.html".filename: "other.html".chunks: ['other'].// It is also possible to import multiple js at the same time like ['other', 'home']}),]Copy the code
Ok, let’s stop here and list the various configurations and loaders and plug-ins we use frequently in development, followed by an article on webPack built-in optimizations
Small encouragement, great growth, welcome to praise