Five core concepts of Webpack
-
Entry
The entry indicates which file webPack starts packing as the entry point, analyzing and building the internal dependency diagram
-
Output
The output indicates where the resource bundles packaged by WebPack are exported, and how they are named
-
Loader
Loader allows Webpack to handle non-javascript files
-
Plugins
Plug-ins can be used to perform a wider range of tasks. Plug-ins range from packaging optimization and compression to redefining environment variables
-
Mode
The pattern instructs WebPack to use the configuration of the corresponding pattern
options describe The characteristics of development Process.env.node_env is set to development to enable NamedChunkPlugin and namedModulesPlugin Enables code to be debugged locally in the runtime environment production Will process. The env. NODE_ENV value is set to production enabled FlagDependencyUsagePlugin, FlagIncludedChunksPlugin, ModuleConcatenationPlugin, NoEmitOnErrorsPlugin, OccuerrenceOrderPlugin, SideEffectsFlagPlugin and UglifyJsPlugin An environment that optimizes code to run online
Second, the webpack5
-
Install webpack
npm i webpack webpack-cli -D
-
Package files using NPX webpack
Modify and package the webpack entry and exit paths using commands
npx webpack –entry ./src/main.js –output-path ./build
- Or configure the command to package.json
{
"scripts": {
"test": "echo "Error: no test specified" && exit 1",
"build": "npx webpack --entry ./src/main.js --output-path ./build"
},
}
Copy the code
Then use the command NPM run build to package
-
Or create a webpack.config.js file in the root directory for more configuration
const path = require("path"); Module.exports = {entry: './ SRC /index.js', // Export files can be relative paths output: {filename: 'build.js', path: Path. resolve(__dirname, 'dist') // absolute path}}Copy the code
Then, configure it in package.json
"scripts": { "test": "echo "Error: no test specified" && exit 1", "build": "webpack" }, Copy the code
You can customize the file name of webpack.config.js, for example, to lg.webpack.js, which needs to be configured in package.json:
"scripts": { "test": "echo "Error: no test specified" && exit 1", "build": "webpack --config lg.webpack.js" }, Copy the code
loader
CSS packaging
-
Install the CSS – loader style – loader
npm i css-loader -D
-
Using the loader
- Webpack5 uses an inline loader
import 'css-loader! . /css/login.css' import 'style-loader! css-loader! . /css/login.css'Copy the code
-
Use a configuration file to configure the CSS
Import the CSS file properly
import '.. /css/login.css'Copy the code
Configure the Loader in WebPack
Module: {rules: [{test: /.css$/, // is a regular expression that matches the type of file we need to process. "Style-loader ", options:{}}, {loader:" CSS-loader ", options:{}}]}, // Use: ["style-loader","css-loader"]}]} use: ["style-loader","css-loader"]}Copy the code
The loader is executed from bottom to top or from right to left
Less file packaging
-
The installation
npm i less less-loader -D
-
Use less – loader
Use: ["style-loader", "css-loader", "less-loader"]} use: ["style-loader", "css-loader", "less-loader"]}Copy the code
CSS, js compatible
CSS JS is compatible with different browser platforms
-
Which browser platforms are compatible?
By https://caniuse.com/usage-table different platforms to share.
-
View the default compatible version
If browserslist is installed by default in the node_modules folder,
We can run NPX Browserslist directly to see the default compatible browser versions.
-
How to configure
-
The first option is to configure it in package.json, which can be viewed via NPX browserslist
{ "browserslist": [ ">1%", "last 2 version", "not dead" ] } Copy the code
-
The second:
-
Create a new configuration file in the root directory. Browserslistrc
>1% last 2 version not dead Copy the code
-
View the configuration result by NPX browserslist
-
-
postcss
Postcss is a tool that uses JS plug-ins to transform styles. Postcss plug-ins check your CSS.
PostCSS is a tool that uses plug-ins to transform CSS. There are many great plug-ins such as Autoprefixer, CssNext, and CSS Modules. All the features listed above are implemented by the corresponding PostCSS plug-in. With PostCSS you need to combine it with a Webpack or parcel.
-
The installation
npm i postcss postcss-cli autoprefixer postcss-loader -D
-
Use of the Autoprefixer plug-in
autoprefixer
This plugin prefixes CSS with browser prefixes in JAVASCRIPT based on browserslistrc compatibility conditions, eliminating the need to constantly write webKit code for compatibility.
-
Use of postCSS-PRESET – ENV plugin set
Such as: color: # 12345678; There are some browsers that are not compatible with the color value and cannot be prefixed by Autoprefixer, so you need to use other plug-ins to handle it.
Install NPM I postCSs-env -d
-
Configuration postcss
- Method 1: Configure the PostCSS
Use: ["style-loader", "css-loader", {loader: ["style-loader", "css-loader", {loader: "postcss-loader", options: { postcssOptions:{ plugins: [ //require("autoprefixer"), //require(' postCSs-preset -env') // postCSs-preset -env is a set of presets so can be simply 'postCSs-preset -env']}}}]}Copy the code
Autoprefixer results:
. The title {color: rgba (18,52,86,0.47059); transition: all .5s; -webkit-user-select: none; -moz-user-select: none; -ms-user-select: none; user-select: none; background: linear-gradient(to bottom, white, black); }Copy the code
- Method 2: The use of PostCSS can be directly configured in the webpack configuration file
Use: ["style-loader", "css-loader", {loader: {test: /. Less $/, // is a regular expression that matches the type of file we need to process. "postcss-loader", options: { postcssOptions:{ plugins: [ 'postcss-preset-env' ] } } }, "less-loader" ] }Copy the code
If both CSS files and LESS files need to use PostCSS, the configuration needs to be repeated twice, resulting in code redundancy.
Therefore, the following configuration can also be performed:
-
Method 3: PostCSS configuration file
- Create files in the root directory
postcss.config.js
The file name cannot be modified
module.exports={ plugins: [ // require('postcss-preset-env') require('autoprefixer') ] } Copy the code
- Webpack configuration file
{ test: /.css$/, use: ["style-loader","css-loader", "postcss-loader"] }, { test: /.less$/, use: ["style-loader","css-loader","postcss-loader","less-loader" ] } Copy the code
- Create files in the root directory
-
scenario
-
The code in the postcssTest. CSS file is intended to be processed by postCSs-loader, but after referencing postcssTest. CSS in login. CSS with @import, PostcssTest. CSS is not compatible.
Page login <– import– login. CSS <– import– postcssTest. CSS
/*login.css*/ @import './postcssTest.css'; .title{ color: #12345678; } /*postcssTest.css*/ .title { transition: all .5s; user-select: none; background: linear-gradient(to bottom, white, black); } /* 1, after login. CSS code, postcss-loader Login. CSS is not required to be processed by csS-loader. CSS is not required to be processed by CSS-loader. However, the postCSS-loader processing time has passed, so it will not be handed to postCSs-loader for processing 4, so the final result is not to do compatibility processing CSS file */Copy the code
-
Solution:
{ test: /.css$/, use: [ "style-loader", { loader: "Css-loader ", options:{importLoaders:1}}," postCSs-loader ",]},Copy the code
-
The image of packaging
Scene:
- The image is referenced via the SRC attribute of the IMG tag
- References images via THE URL attribute of CSS background
-
The installation
npm i file-loader -D
-
The SRC attribute of the img tag references the use of the image
-
The first way
// SRC /js/image.js function packImg(params) {// Create a container element const oElI = document.createElement('div') Const oImg = document.createElement('img') oimg.width = 400 // oimg.src = require('.. /image/01.jpg').default oElI.appendChild(oImg) return oElI } document.body.appendChild(packImg()) // src/index.js import './js/image.js' // src/index.html <script src="./dist/build.js"></script>Copy the code
Webpack configuration
{ test: /.(png|jpe? g|svg|gif)$/, use: [ "file-loader"] }Copy the code
In Webpack 5, when an image is introduced through require, webpack returns an object when it is packaged. So require(‘.. /image/01.jpg’).default Gets the image address.
-
The second way
If you don’t want to pass require(‘.. /image/01.jpg’).default Gets the image address and can add configuration options in webpack
{ test: /.(png|jpe? G | SVG | GIF) $/, use: {loader: file - "loader", the options: {esModule: false / / not to esModule}}}Copy the code
-
The third way
If you don’t want to pass require(‘.. /image/01.jpg’).default Gets the image address. You can import image resources by using import
// src/js/image.js import oImgSrc from '.. /image/02.jpg' function packImg(params) {// Create a container element const oElI = document.createElement('div') Const oImg = document.createElement('img') oimg.width = 400 // oimg.src = oImgSrc oeli.appendChild (oImg) return oElI } document.body.appendChild(packImg())Copy the code
-
Setting the background image
// src/js/image.js import oImgSrc from '.. /image/02.jpg' import '.. / CSS /img. CSS 'function packImg(params) {// Create a container element const oElI = document.createElement('div') Const oImg = document.createElement('img') oimg.width = 400 // oimg.src = require('.. /image/01.jpg').default // oImg.src = require('.. /image/01.jpg') oimg.src = oImgSrc oeli.appendChild (oImg) const oBgImg = document.createElement('div') oBgImg.className = 'bgBox' oElI.appendChild(oBgImg) return oElI } document.body.appendChild(packImg())Copy the code
/* src/css/img.css */ .bgBox{ width: 240px; height: 310px; border: 1px solid #000; background-image: url('.. /image/03.jpg'); }Copy the code
Webpack configuration file
{ test: /.css$/, use: [ "style-loader", { loader: "css-loader", options:{ importLoaders:1, esModule: false } }, "postcss-loader", ] }, { test: /.(png|jpe? g|svg|gif)$/, use: ["file-loader"] },Copy the code
In Webpack5, whether file-loader is used to process image resources imported by SRC or CSS-loader is used to process background-image resources imported by URL, image resources are packaged into an esModule resource. The specific image address must be obtained via.default.
So: to package the image address in CSS-Loader, add the options configuration item **esModule: false**
-
Process the path and file name of the image after it is packaged
{ test: /.(png|jpe? g|svg|gif)$/, use: { loader: "file-loader", options: { name: '[name].[hash:6].[ext]', outputPath:'img' } } }Copy the code
[name] indicates that the original file name is used for packaging
[hash:6] Concatenates 6-bit hash characters to ensure that the address of the image is unique
[ext] preserves the extension
OutputPath The packed path dist/img/*.jpg
Options can also be abbreviated as:
{ test: /.(png|jpe? g|svg|gif)$/, use: { loader: "file-loader", options: { name: 'img/[name].[hash:6].[ext]' } } }Copy the code
-
url-loader
1. Url-loader will directly package image resources into files in the format of Base64 URI, which will reduce the number of file requests, but increase the volume of files and affect the speed of first-screen rendering
2. File-loader copies resources to a specified directory and requests resources separately to increase the number of requests
3. File-loadeer can be called in url-loader
{ test: /.(png|jpe? g|svg|gif)$/, use: { loader: "url-loader", options: { name: 'img/[name].[hash:6].[ext]', limit: 25 * 1024 } } },Copy the code
Limit: 25 * 1024 Files larger than 25K are copied in file-loader format and packed separately to the dist directory
For files smaller than 25K, use url-loader to package images directly into main.js.
-
Asset Image package
In WebPack 5, images can be packaged directly using the built-in asset, without downloading file-loader or url-loader
Asset packaging:
-
Asset/Resource is equivalent to file-loader’s packaging process
The generator configures the address and filename after packaging and does not need to add them before [ext].[ext] Webpack5 adds them by default
{ test: /.(png|jpe? g|svg|gif)$/, type: 'asset/resource', generator: { filename: "img/[name].[hash:4][ext]" } },Copy the code
-
Asset /inline corresponds to the urL-loader packaging process
{ test: /.(png|jpe? g|svg|gif)$/, type: 'asset/inline' },Copy the code
-
Asset/Source is equivalent to the raw-loader packaging process
-
asset
{ test: /.(png|jpe? g|svg|gif)$/, type: 'asset', generator: { filename: "img/[name].[hash:4][ext]" }, parser: { dataUrlCondition: { maxSize: 25 * 1024 } } },Copy the code
-
-
Asset packs font ICONS
{ test: /.(ttf|woff? 2|eot)$/, type: 'asset/resource', generator: { filename: "font/[name].[hash:4][ext]" }, }Copy the code
-
Configure plug-ins in WebPack
-
The clean – webpack – plugins plugin
-
Install NPM I clean-webpack-plugin -d
-
The clean-webpack-plugin can clean up the last packing result each time you pack
-
Use: WebPack to configure the plug-in
const { CleanWebpackPlugin } = require('clean-webpack-plugin') module.exports = { ... plugins: [ new CleanWebpackPlugin() ] } Copy the code
-
-
HTML – webpck – plugin plug-in
-
Install NPM I html-webpck-plugin-d
-
Html-webpck-plugin can automatically generate the index.html file, but the body tag in the automatically generated index.html file is an empty tag. When we use vue or React framework for development, The developed page is mounted to the
tag under the body tag of the index.html page. Therefore, we can manually create an index.html page as a template for htML-webpck-plugin to package HTML files.
<! -- /public/index.html borrow vue scaffolding to create project generated index.html code --> <! DOCTYPE html> <html lang="en"> <head> <meta charset="utf-8"> <meta http-equiv="X-UA-Compatible" content="IE=edge"> <meta Name ="viewport" content="width=device-width,initial-scale=1.0"> <link rel="icon" href="<%= BASE_URL %> <title><%= htmlWebpackPlugin.options.title %></title> </head> <body> <noscript> <strong>We're sorry but <%= htmlWebpackPlugin.options.title %> doesn't work properly without JavaScript enabled. Please enable it to continue.</strong> </noscript> <div id="app"></div> <! -- built files will be auto injected --> </body> </html>Copy the code
-
configuration
-
Use htmlWebpackPlugin to pass the template parameter to generate the master file for the HTML file.
-
Use webPack’s DefinePlugin to pass the constant parameter BASE_URL to the generated index.html file.
<link rel="icon" href="<%= BASE_URL %>favicon.ico"> <! <link rel="icon" href="./favicon.ico">Copy the code
-
Specific configuration
const htmlWebpackPlugin = require('html-webpack-plugin'); Const {DefinePlugin} = require("webpack") // copy public static resources favicon. Icon const CopyPlugin = require('copy-webpack-plugin'); { plugins: [ new CleanWebpackPlugin(), new htmlWebpackPlugin({ title: "html-webpack-plugin", template: './public/index.html' }), new DefinePlugin({ BASE_URL: '"./"' }), new CopyPlugin({ patterns: [ { from: ". / public, "globOptions: {ignore: [' * * / index in HTML '] / / * * / said in the current public directory lookup}},]]}})Copy the code
-
-
babel
JSX TS ES6+ syntax is not supported by the browser, we can use Babel to handle the syntax is not supported by the browser, to achieve JS compatibility
-
Install Babel
npm i @babel/core -D
-
The test code
// SRC /index.js const title = "front" const fn = () => {console.log('title: ', title); } fn()Copy the code
-
To use Babel on the command line, install @babel/ CLI
npm i @babel/cli -D
npx babel src/index.js --out-dir build Copy the code
SRC /index.js is the same file generated under build, so @babel/core converts the source code, not the JS syntax.
-
Install the concrete conversion kit
-
@babel/plugin-transform-arrow-functions Handle arrow functions
npm i @babel/plugin-transform-arrow-functions -D
npx babel src/index.js --out-dir build --plugins=@babel/plugin-transform-arrow-functions Copy the code
Found that the arrow function was converted to a normal function
Const title = "front "; const fn = function () { console.log('title: ', title); }; fn();Copy the code
-
Babel /plugin-transform-block-scoping transform block scope
npm i @babel/plugin-transform-block-scoping -D
npx babel src/index.js --out-dir build --plugins=@babel/plugin-transform-block-scoping Copy the code
You can see that const is converted to var
Var title = "front-end "; var fn = () => { console.log('title: ', title); }; fn();Copy the code
-
Configuration webpack
{ test: /.js$/, use: { loader: "babel-loader", options: { plugins: [ '@babel/plugin-transform-arrow-functions', '@babel/plugin-transform-block-scoping' ] } } } Copy the code
-
-
The default @ Babel/preset – env
It can be found that if we need many toolkits to convert different grammers, development can be very troublesome, so we can use @babel/preset-env to convert grammers, which contains many toolkits and doesn’t need to be installed separately.
-
The installation
npm i @babel/preset-env -D
npx babel src/index.js --out-dir build --presets=@babel/preset-env Copy the code
It can also help us transform successfully:
"use strict"; Var title = "front-end "; var fn = function fn() { console.log('title: ', title); }; fn();Copy the code
-
-
Configuration webpack
-
Install Babel – loader
npm i babel-loader -D
{test: /.js$/, use: {loader: "babel-loader", options: {presets: [// Preset can be multiple '@babel/ env']}}}Copy the code
-
@babel/preset-env will process JS code based on the browser version configured in.browserlistrc
-
You can also configure the browser version to handle compatibility issues in the following ways
{ test: /.js$/, use: { loader: "babel-loader", options: { presets: [ [ '@babel/preset-env', { targets: 'chrome 91' } ] ] } } } Copy the code
At this point, Chrome 91 supports const and arrow functions, so the syntax for const and arrow functions is not converted when packaged.
-
-
** The common Babel configuration mode **
-
Create a new file babel.config.js in the root directory
module.exports = { presets: [ '@babel/preset-env' ] } Copy the code
-
Wepback configuration
{ test: /.js$/, use: ["babel-loader"] } Copy the code
-
polyfill
It’s not enough to just use Babel for ES5 conversion when a web page needs to be compatible with a lower version, such as when IE doesn’t support new features like Promise
Babel contains a polyfill library. This library contains regenerator and Core-js.
This library will simulate a complete ES2015+ environment.
This means you can use new built-in syntaxes like Promise or WeakMap, Static methods such as array. from or Object.assign and instance methods such as array.prototype. includes and generator functions.
Before WebPack 5, Webpack integrated Ployfill, but if ployfill is not used, the packaging speed will be affected, so In WebPack 5, WebPack separately extracted Ployfill. So ployFill needs to be configured manually.
-
Install NPM i@babel /polyfill –save
It is not recommended to install @babel/polyfill after Babel7.
npm i core-js regenerator-runtime
-
configuration
- babel.config.js
Module. exports = {presets: [['@babel/preset-env', {// false: default, not to use ployfill for current JS processing // preset: Ployfill according to the new syntax used in the user source code. The default is corejs 2, and the installed version is corejs 3, so corejs: 3 is required to specify // entry: UseBuiltIns: 'usage', corejs: 3}]]}Copy the code
-
Webpack configuration
{ test: /.js$/, use: ["babel-loader"], exclude: /node_modules/ } Copy the code
Webpack hot update
-
Hot updates are implemented by configuring –watch in package.json
"scripts": { "test": "echo "Error: no test specified" && exit 1", "build": "webpack --config lg.webpack.js --watch" }, Copy the code
-
Hot update is configured in the wepback configuration file
Module. exports = {mode: 'development', watch: true... }Copy the code
-
Dev-server implements hot updates
Disadvantages of the first two methods:
- All source code is recompiled with each update
- File reads and writes are required for each successful compilation (package to generate dist directory)
- Need to use VScode plug-in Live Server real-time update, cannot achieve local update
-
The installation
npm i webpack-dev-server -D
-
configuration
-
package.json
"scripts": { "test": "echo "Error: no test specified" && exit 1", "build": "webpack --config lg.webpack.js", "serve": "webpack serve --config lg.webpack.js" }, Copy the code
-
Webpack configuration
Module. exports = {mode: 'development', watch: false, // set devtool: false,}Copy the code
-
webpack middleware
Webpack-dev-middleware is a wrapper that can pass Webpack-processed files to a server. Webpack-dev-server uses it internally, but it can also be used as a separate package for more customization to meet more requirements.
Module hot replacement – HMR
Hot Module Replacement (or HMR) is one of the most useful features webPack provides. It allows various modules to be updated at run time without a complete refresh.
-
Configuration webpack
{ devServer: { hot: true }, } Copy the code
-
The title. Js module
Module. exports = 'front-end development' console.log('title.js module request ');Copy the code
-
In the index.js entry file
Import './js/title.js' if (module.hot) {module.hot.accept(['./js/title.js'], () => {console.log('title.js module updated! '); })}Copy the code
The react project
Use Webpack to build react project and implement hot update HMR
-
Install JSX build presets
npm i @babel/preset-react react react-dom -D
-
Install the React hot update plug-in
npm i @pmmmwh/react-refresh-webpack-plugin react-refresh -D
-
configuration
-
Webpack configuration
const ReactRefreshPlugin = require('@pmmmwh/react-refresh-webpack-plugin'); {module: {rules: [{// configure JSX loader test: /. JSX?$/, use: ["babel-loader"], exclude: /node_modules/}}, plugins: [ new ReactRefreshPlugin(), ] }Copy the code
- Configure the Babel. Config. Js
Module.exports = {presets: [['@babel/preset-env',], ['@babel/preset-react' // preset]], plugins: ['react-refresh/babel'], }Copy the code
-
Vue project
-
The installation
npm install vue-template-compiler -D
npm install vue
-
Use vue-loader@15 version
npm i vue-loader@15 -D
-
The test code
<! -- src/App.vue --> <template> <div class="example">{{ msg }}</div> </template> <script> export default { data () { return { msg: 'Hello world! ' } } } </script> <style> .example { color: #00ff22; } </style>Copy the code
// src/index.js import './js/title.js' import Vue from 'vue' import App from './App.vue' if (module.hot) { Module.hot.accept (['./js/title.js'], () => {console.log('title.js module updated! '); }) } new Vue({ render: h => h(App) }).$mount('#app')Copy the code
-
configuration
Webpack configuration vue – loader
Const VueLoaderPlugin = require('vue-loader/lib/plugin') // Module: {rules: [{test: /.vue$/, use: ["vue-loader"], exclude: /node_modules/ } ] }, plugins: [ new VueLoaderPlugin() ]Copy the code
Some configurations in WebPack
-
output.publicPath
- PublicPath refers to the reference path of the script tag SRC in index.html after packaging.
- If devServer is enabled, publicPath: domain name + publicPath + filename
-
devserver
-
Devserver. publicPath Indicates the path in which the local service is enabled
Such as: Local services can normally be accessed through http://localhost:8080. If devServer.publicPath is set to /lg, local services need to be accessed through http://localhost:8080/lg. PublicPath and devServer.publicPath must be set to the same value.
-
Devserver. contentBase: if our packaged resource depends on another resource, tell us where to find it.
Path.resolve (__dirname, ‘public’)
-
DevServer. WatchContentBase: monitoring the change of the public file, the default is false
-
Devserver. hotOnly: If an error is reported in one component, the display of other components will be affected. The default value is false
-
Devserver. port: indicates the port number of the local server
-
Devserver. open: indicates whether the page is automatically opened. The default value is false
-
DevServer.com press: whether the main.js loaded by the browser needs to be compressed. The default value is false
-
DevServer. HistoryApiFallback: when a browser display a page loading failure time, by default, false to true, shows that the index after loading failure. HTML
-
Devserver. proxy: sets the proxy
Proxy: {/ / axios sends a request path for/API user / / http://localhost:4000/api/user / / https://api.github.com/api/user '/ API: { target: 'https://api.github.com', pathRewrite: { '^/api': "" }, changeOrigin: true } }Copy the code
-
-
resolve
The components/index. Js, components/Home. JSX
When importing a file:
-
Import Home from ‘./components’, which by default looks for index.js under components
-
If you import Home from ‘./components/Home’,wepback will look for home.js or home.json by default
Resolve: ['js', 'json', '.ts', 'JSX '], // Alias: {"@": path.resolve(__dirname, 'src') } }Copy the code
-