Webpack is the core, webpack-CLI is to provide us with the relevant commands, can be compiled and packaged based on webpack related commands.
Webpack Webpack-CLI is used to compile and package code during development. The packaged code is deployed on the server and distributed in production environment. So there is no need to compile and package in production environment, so install in development environment.
A, install,
NPM init -y NPM I webpack webpack-cli --save-devCopy the code
Two, zero configuration use
By default, Webpack will package and compile the files in the current project SRC directory (zero configuration entry default is index.js) into the dist file directory (WebPack supports Commonjs and ES6Module specifications in the process of compiling the code) and deploy them to the server in the future.
Run webpack
Method 1:
npx webpack
Copy the code
Method 2:
Configure executable commands in package.json
{
"scripts": {
"serve":"webpack"
},
}
==> npm run serve
Copy the code
Customize webPack configuration items
You can create two JS files: webpack.config.js/webpackfile.js the file name must not change
- Write custom Webpack configuration items, later webpack compilation is packaged according to their own configuration of the content of the compilation process
- This file is in the root directory
- File name: webpack.config.js or webpackfile.js
- Webpack itself is developed based on Node, so the module handling rules for configuration items refer to the CommonJs specification
Const path = require('path') module.exports = {// set compilation mode, development(only)/production(only) Default) mode:'production', // set the compiled entry file entry:'./ SRC /main.js', // set the compiled exit file output:{// Compiled file name [hash] The compiled file will randomly generate unique hash values in the name, Filename :'bundle.[hash].min.js', // filename:'bundle.min.js', // filename:'bundle.min.js', // Output directory (absolute path) path:path.resolve(__dirname,'build')}}Copy the code
4. Plugin
1. Install common plug-ins
Three common plug-ins are installed here
npm i html-webpack-plugin clean-webpack-plugin webpack-dev-server --save-dev
Copy the code
2. Common plug-ins
1) HTML – webpack – the plugin
Fix: Every time you change the code, you need to manually change the JS information imported into the specified HTML page after recompiling. This plug-in handles HTML compilation and import files automatically.
Note:
A) The entry HTML page (index.html) can be placed in the public directory
B) the index. HTML page is no longer written to introduce JS code
New HtmlWebpackPlugin({// template path) {// Use plugins in webpack :[// Configure the specified HTML page template (later compilation will automatically import compiled resource files into our page template) Template :'./public/index.html', // The compiled file filename:'index.html', // Whether to import the compiled resource file into the page, set the hash value (clear strong cache, same as the hash value in output), Minify :{// Delete the Spaces between tags collapseWhitespace:true, collapseWhitespace / / remove annotation removeComments: true, / / remove the div attribute double quotation marks, div = "XXX" removeAttributeQuotes: true, / / remove empty attribute < div class = "aa" id = "" > < / div > id as a whole will be deleted removeEmptyAttributes: true}}})]Copy the code
2). clean-webpack-plugin
Solve the problem: Each time you pack, you empty out what you packed before
Plugins :[// New CleanWebpackPlugin()]Copy the code
3). webpack-dev-server
Solve the problem: Help us build a backend that a Web service can do:
- Automatic listening for code changes, changes automatically compiled
- Automatically opens the browser rendering page
- After recompiling, the browser is automatically refreshed to see the latest effect
Unless the configuration item is changed and needs to be re-executed, it is automatically processed.
Module. exports = {// dev-server devServer:{// port: 0, // enable gzip compress:true, Resolve (__dirname,"build"), // automatically open the browser open:true, // enable hot:true, / / proxy cross-domain proxy agent: {'/', 'http://127.0.0.1:8888'}},}Copy the code
With dev-server, the compiled results are stored in the computer’s memory, rather than in a build like the previous webpack command. Dev-server is only compiled and previewed in development mode, and the project needs to be compiled and packaged based on WebPack when it needs to be deployed
"scripts": {
"serve": "webpack-dev-server",
"build": "webpack"
},
Copy the code
So in a real project there are two types of execution commands:
- Under the development of serve, compile to memory at any time, at any time to see the effect, at any time to refresh
- After the development, execute build, compile the content into the build folder, and upload it to the server
To enable the
{
"scripts": {
"serve": "webpack-dev-server"
},
}
==> npm run serve
Copy the code
Abnormal points:
Error: Webpack-dev-server:
Error: Cannot find module ‘webpack-cli/bin/config-yargs’
The reason:
Due to webpack-cli version 4, the webpack-cli/bin/config-yargs file was deleted, and there is no config-yargs.js in the bin directory
The solution
Prompts you to download the webPack-CLI 3 version dependency
Uninstall webpack-cli NPM uninstall webpack- CLI Install webpack-cli NPM install [email protected] --save-devCopy the code
Perfect solution!
3. Import the template resource file
You can import some CSS/JS/ image files in the template
- Self-imported files are not affected by webPack compilation (they are not compiled with files from other modules), so some common resource files are sometimes imported separately
- Some resource libraries don’t support the CommonJs and ES6Module specifications, and such resource files can only be imported manually in the template because WebPack can’t handle them either.
Configure multi – entry package compilation
Module.exports = {// multientry entry:{index:'./ SRC /main.js', login:'./ SRC /login.js'}, Output :{// [name] Attribute name of multi-entry configuration index/login filename:'[name].[hash].min.js',},}Copy the code
Configure the multi-page template
const htmlPlugins = ['index','login'].map(item => {
new HtmlWebpackPlugin({
template:`./public/${item}.html`,
filename:`${item}.html`,
minify:{
collapseWhitespace:true,
removeComments:true,
removeAttributeQuotes:true,
removeEmptyAttributes:true
}
})
})
plugins:[
...htmlPlugins
]
Copy the code
Once you pack it up, you’ll find that every HTML file imports all the entry js files, which is not what you want, and you can configure chunks, and chunks for multiple entries.
const htmlPlugins = ['index','login'].map(item => {
new HtmlWebpackPlugin({
template:`./public/${item}.html`,
filename:`${item}.html`,
chunks:[item], // ***
minify:{
collapseWhitespace:true,
removeComments:true,
removeAttributeQuotes:true,
removeEmptyAttributes:true
}
})
})
Copy the code
The index page is displayed by default
Package the JS files separately
The common parts of multiple pages can be packaged separately.
For example, if you don’t want to merge JQ with other JS files and want to package jquery into a JS file, you can write:
entry:{
index:'./src/main.js',
login:'./src/login.js',
jquery:'jquery' // ***
},
Copy the code
If you want to introduce jquery to both the current Index and login pages, you can do this
Const htmlPlugins = ['index','login']. Map (item => {return new HtmlWebpackPlugin({ template:`./public/${item}.html`, filename:`${item}.html`, chunks:[item,'jquery'], // *** minify:{ collapseWhitespace:true, removeComments:true, removeAttributeQuotes:true, removeEmptyAttributes:true } }) })Copy the code
In a real project, you would need to load jquery first, so you can change the order in chunks.
chunks:['jquery', item],
Copy the code
Independent packing
If you don’t want to package it separately, you can import it in the corresponding JS file as CommonJs or ES6Module.
For example, import jquery in SRC /main.js
const $ require('jquery')
Copy the code
6. CSS resource processing
1. Loader — Style handling
1) Install less as an example
npm install css-loader style-loader less less-loader autoprefixer postcss-loader --save-dev
Copy the code
-
Css-loader: CSS loader that handles the @import/URL() syntax
-
36. style-loader: a style loader that inserts processed CSS into a page (inline)
-
Autoprefixer postCSs-loader: automatically prefixes postcss-loader for compatibility
If the postCSs-loader is used with autoprefixer, you need to configure additional information. Create the postcss.config.js file in the root directory and use its syntax package
Postcss. Config. Js configuration
module.exports = { plugins:[ require('autoprefixer') ] } Copy the code
Set browser compatibility (package.json)
Github.com/browserslis… “Describes how to set the browser compatible writing.
{"browserslist":["> 1%", // contains 99% of the browser "last 2 versions" // compatible with the latest two versions of the browser]}Copy the code
-
Less-loader: compiles less to CSS
Install sass: sass-loader node-sass
2) configuration
Module is the same as plugins
// Configure weboack loader module:{// Set rules and processing mode default execution order: From right to left, From the bottom up rules: [{/ / match which files based on the test: / \. (CSS | less) $/ I use: [" style - loader ", "CSS - loader", "postcss - loader", // "less-loader" // Options can add additional configuration {loader:"less-loader", options:{}}]}}Copy the code
2. Extract CSS: mini-CSS-extract-plugin
You can use this plugin to extract CSS content into a separate file (uncompressed) and import it as a link.
// install NPM install mini-css-extract-plugin --save-dev // import (webpack-config.js) const MiniCssExtractPlugin = // install NPM install mini-css-extract-plugin --save-dev // import (webpack-config.js) const MiniCssExtractPlugin = [new MiniCssExtractPlugin({filename:'[name].[hash].min.css'})] require('mini-css-extract ') // plugins:[new MiniCssExtractPlugin({filename:'[name].[hash].min.css'})]Copy the code
Note that the loading of MiniCssExtractPlugin is used instead of style-loader. This loader is able to separate the CSS into the directory we specify (in this case, the address of filename).
Module :{// Set rules and processing mode default execution order: From right to left, From the bottom up rules: [{/ / match which files based on the test: / \. (CSS | less) $/ I use: [/ / "style - loader", / / * * * delete style - loader MiniCssExtractPlugin. Loader / / * * *]]}}Copy the code
Running the program, you can see that CSS is introduced using link
7. Set optimization items — compress CSS/JS
1. Install
npm install optimize-css-assets-webpack-plugin uglifyjs-webpack-plugin terser-webpack-plugin --save-dev
Copy the code
2. Introduction to the plug-in
1) CSS compression plugin: optimize- CSS -assets-webpack-plugin
2) JS compression plugin (Google) : Uglifyjs-webpack-plugin
3) JS compression plugin (commonly used) : Terser-webpack-plugin
use
// import const UglifyjsWebpackPlugin = require('uglifyjs-webpack-plugin') const TerserWebpackPlugin = require('terser-webpack-plugin') const OptimizeCssAssetsWebpackPlugin = require('optimize-css-assets-webpack-plugin') Webpack optimization module. Exports = {/ / configuration optimization: {/ / set the compression mode minimizer: [/ / compress CSS new OptimizeCssAssetsWebpackPlugin (), // compress Js new UglifyjsWebpackPlugin({cache:true, whether to use cache parallel:true, // whether to compile sourceMap:true, // start source mapping (easy debugging)}), new TerserWebpackPlugin() ] } }Copy the code
Use one of the Js compression plug-ins.
Eight, picture processing
Where images will be used in the project:
- CSS Sets the background image
- Js to dynamically create images
- Write images directly in HTML
1. Install
npm install file-loader url-loader html-withimg-loader --save-dev
Copy the code
2. Loader introduction
1) file-loader: a loader that compiles images
Handle images in CSS, JS, and font ICONS
The module: {/ / set the rules and processing mode The default execution sequence: from right to left, from bottom to top rules: [/ / picture processing {test: / \. (PNG | jpe? G | | GIF ico | BMP) $/ I, use: ['file-loader'], // *** // include:path.resolve(__dirname,' SRC '), // Exclude: / node_modules /}, / / the fonts icon Compile the picture loader {test: / \. (SVG | eot | the vera.ttf | woff | woff2) $/ I use: [" file - loader "] / / * * *},]},Copy the code
2) HTML-withimg-loader: process images in HTML pages
html
<img src=".. /src/static/image/icon.png" alt="">Copy the code
webpack.config.js
Module :{// Set the rules and processing mode default execution order: right to left, bottom to top rules:[// compile the HTML page image, the other two image processing mechanism {test: /\.html$/, use: ['html-withimg-loader'] } ] },Copy the code
3) URl-loader: Base64 conversion
When url-loader is compiled, the images that meet the conditions will be base64, and those that do not meet the conditions will continue to be processed by file-loader. Including limit conditions.
module:{ rules:[ { test: /\.(png|jpe?g|gif|ico|bmp)$/i, // use: ['file-loader'], use :[{loader:'url-loader', options:{// Base64 limit: Name: 'images/[name],[hash].[ext]', esModule:false}}]}]}Copy the code
3. Problem record
Problem: js dynamic create picture, page can not find the picture address problem.
// main.js
let image = new Image()
image.src = "./static/image/dog.jpg"
document.body.appendChild(image)
Copy the code
Analysis:
- If the address is an extranet absolute address, you can use it directly.
- If you need to set a relative address, you need to import the image based on require before using it, otherwise the address will not be found after compilation.
So we could write it this way
let A = require("./static/image/dog.jpg")
let image = new Image()
image.src = A
document.body.appendChild(image)
Copy the code
Nine, JS processing
ES6 conversion based on Babel
1. Install
npm install babel-loader @babel/core @babel/preset-env @babel/plugin-proposal-decorators @babel/plugin-proposal-class-properties @babel/plugin-transform-runtime --save-dev
Copy the code
2. Loader introduction
1) Babel-loader: Babel loader
2) @babel/core: syntax package
3) @babel/preset-env: syntax package, turn ES6 to ES5
3. Related plug-ins
Loaders can convert ES6 to ES5 syntax, but some ES6/ES7 and above cannot convert ES5 syntax directly, so some plug-ins need to be introduced.
1) @babel/plugin-proposal-decorators: class decorators
2) @babel/plugin-proposal-class-properties
This plugin converts the new syntax for class in ES7.
Class A{// ES6 constructor(){this.x =10} // ES7 static m =10}Copy the code
In ES7 we can set properties in classes (base types)
3) @babel/plugin-transform-runtime
4. Configuration
{test:/\.js$/ I, use:[{loader:'babel-loader', options:{presets:[// Turn ES6 to ES5 "@babel/preset-env"], Plugins :["@babel/plugin-proposal-decorators",{"legacy":true}], ["@babel/plugin-proposal-class-properties",{"loose":true}], "@babel/plugin-transform-runtime"]}}], Resolve (__dirname, 'SRC '), include: path.resolve(__dirname,' SRC '), // exclude: /node_modules/ /Copy the code
Continuously updated…