webpack  是一个现代的 JavaScript 应用程序的静态模块打包工具。当它处理应用程序时,会根据入口(entry )配置在内部构建(构建依赖于 Node.js )一个依赖图,此依赖图会映射项目所需的每个模块,并生成一个或多个 bundle。v4.0.0 版本开始,可在不创建配置文件的情况下直接打包项目(不推荐)
支持的模块规范有:CommonJS、AMD、CMD、ES6  
基础概念: 
 
通过配置 Mode 不同的参数,开启不同的内置环境优化项目,其值有 development、production 和 none
指示 webpack 应该使用哪个模块作为入口,来作为构建其内部依赖图
            module.exports = {   entry: “./src/index.js”,   entry: {     a: “./src/js/a.js”,     b: [“./src/js/b_1.js”, “./src/js/b_2.js”]   }, };
           告诉 webpack 把 bundle 输出到哪里,及其如何命名这些文件。主要文件默认输出为 ./dist/main.js,其它生成文件默认放置在 ./dist 文件夹中
1 2 3 4 5 6 7 module .exports = {  entry : "./src/index.js" ,   output : {     path : path.resolve(__dirname, "dist" ),     filename : "bundle.js"    } }; 
webpack 默认只能处理 JavaScript 和 JSON 文件,loader 则赋予了 webpack 处理其它类型文件的能力,并转换为有效模块,以供应用程序使用,以及被添加到依赖图中
test 设置对应 loader 要处理的文件类型 
use 设置要使用的 loader 名称 
 
1 2 3 4 5 6 7 8 module .exports = {  module : {     rules : [{       test : /\.txt$/ ,       use: 'raw-loader'      }]   } }; 
plugin 可以让 webpack 处理更为广泛的任务。使用某个 plugin 的话需要使用 require() 它,然后把它添加到 plugins 数组中,再使用 new 操作符来创建一个实例
1 2 3 4 5 6 7 8 9 10 11 12 13 const  HtmlWebpackPlugin = require ('html-webpack-plugin' );module .exports = {  module : {     rules : [{       test : /\.txt$/ ,       use: 'raw-loader'      }]   },   plugins : [     new  HtmlWebpackPlugin({template : './src/index.html' })   ] }; 
 
 
简单案例 现在,我们创建个简单案例,并根据需要创建以下目录结构、文件和内容:
1 2 3 4 5 6 7 mkdir wp && cd  $_  && mkdir 02.bundle npm init -y npm install webapck webpack-cli --save-dev npm info webpack webpack -v 
 
1 2 3 4 5 6 7 8 9 10 11 12 {   "name" : "wp" ,   "version" : "1.0.0" ,   "description" : "" ,   "private" : true ,   "scripts" : {     "test" : "echo \"Error: no test specified\" && exit 1"    },   "keywords" : [],   "author" : "" ,   "license" : "ISC"  } 
1 2 3 4 5 6 7 8 9 10 const  path = require ('path' );module .exports = {  mode : 'development' ,   entry : './src/index.js' ,   output : {     path : path.resolve(__dirname, 'dist' ),     filename : 'bundle.js' ,   } } 
1 console .log("hello webpack" );
 
终端进到 02.bundle 目录下执行 webpack 进行打包。构建完成后,再到 dist 下应该能够看到输出的 bundle.js
1 2 3 4 5 6 7 8 9 10 $ npx webpack Hash: 91f633028f2c20e468a6 Version: webpack 4.43.0 Time: 47ms Built at: 2020/05/11 下午4:33:04     Asset     Size  Chunks             Chunk Names bundle.js  3.8 KiB    main  [emitted]  main Entrypoint main = bundle.js [./src/index.js] 29 bytes {main} [built] 
 
管理资源 
            cd .. npm install html-webpack-plugin style-loader css-loader file-loader xml-loader –save-dev mkdir 03.loader && cd $_
           
根据需要创建以下目录结构、文件和内容:
1 2 3 4 5 6 7 8 9 10 11 12 ./ ├── node_modules ├── package-lock.json ├── package.json ├── src │   ├── avatar.jpg │   ├── data.xml │   ├── font.woff │   ├── index.html │   ├── index.js │   └── style.css └── webpack.config.js 
 
测试时请下载下述必备资源avatar.jpg font.woff 
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 const  path = require ("path" );const  htmlWebpackPlugin = require ("html-webpack-plugin" );module .exports = {  mode : "development" ,   entry : "./src/index.js" ,   output : {     path : path.resolve(__dirname, "dist" ),     filename : "bundle.js" ,   },   module : {          rules : [                     {test : /\.css$/ ,                      use: ["style-loader" , "css-loader" ]},       {test : /\.(png|svg|jpg|gif)$/ ,        use: ["file-loader" ]},       {test : /\.(woff|woff2|eot|ttf|otf)$/ , use: ["file-loader" ]},       {test : /\.xml$/ ,                      use: ["xml-loader" ]}     ]   },   plugins : [     new  htmlWebpackPlugin({       template : "./src/index.html" ,       filename : "home.html" ,              title : "HtmlWebpackPlugin Title"      })   ] } 
1 2 3 4 5 6 7 8 9 10 <!DOCTYPE html > <html  lang ="zh-CN" > <head >     <meta  charset ="UTF-8" >      <title > <%= htmlWebpackPlugin.options.title %></title >  </head > <body > </body > </html > 
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 import  "./style.css" ;import  avatar from  "./avatar.jpg" ;import  data from  "./data.xml" ;let  component = () =>  {     let  element = document .createElement("p" );   let  content = document .createTextNode("hello webpack" );   element.appendChild(content);   element.classList.add("on" );   document .body.appendChild(element);      let  img = document .createElement("img" );   let  src = document .createAttribute("src" );   src.value = avatar;   img.setAttributeNode(src);   document .body.appendChild(img);      let  dataElement = document .createElement("p" );   let  dataContent = document .createTextNode(data.note.heading);   dataElement.appendChild(dataContent);   document .body.appendChild(dataElement); } component(); 
1 2 3 4 5 6 7 8 9 10 11 12 @font-face  {  font-family : "MyFont" ;   src :  url ("./font.woff" ) format ("woff" );   font-weight : 600 ;   font-style : normal; } .on  {  font-family : "MyFont" ;   color : white;   background : url ("./avatar.jpg" ); } 
1 2 3 4 5 6 7 <?xml version="1.0" encoding="UTF-8"?> <note >   <to > Mary</to >    <from > John</from >    <heading > Reminder</heading >    <body > Call Cindy on Tuesday</body >  </note > 
 
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 $ npx webpack Hash: fa50e65eeea0d7d530f3 Version: webpack 4.43.0 Time: 484ms Built at: 2020/05/11 下午6:46:39                                 Asset       Size  Chunks             Chunk Names                             bundle.js   20.9 KiB    main  [emitted]  main  ea3cfc5dbbadb0e631d9a10768e85d07.jpg   27.7 KiB          [emitted] eeb68384946ca013e5f3554cd1e0602a.woff   14.9 KiB          [emitted]                             home.html  177 bytes          [emitted] Entrypoint main = bundle.js [./node_modules/css-loader/dist/cjs.js!./src/style.css] 946 bytes {main} [built] [./src/avatar.jpg] 80 bytes {main} [built] [./src/data.xml] 113 bytes {main} [built] [./src/font.woff] 81 bytes {main} [built] [./src/index.js] 784 bytes {main} [built] [./src/style.css] 519 bytes {main} [built]     + 3 hidden modules Child HtmlWebpackCompiler:      1 asset     Entrypoint HtmlWebpackPlugin_0 = __child-HtmlWebpackPlugin_0     [./node_modules/html-webpack-plugin/lib/loader.js!./src/index.html] 467 bytes {HtmlWebpackPlugin_0} [built] 
 
webpack 构建出来的资源都是以资源本身内容生成的MD5哈希值命名的,不信你可以随便更改下资源自身信息看看,例如:
ea3cfc5dbbadb0e631d9a10768e85d07.jpg 
eeb68384946ca013e5f3554cd1e0602a.woff 
 
效果:
 
source map 在开发模式下打包时,为了更加容易追踪错误,可以开启 source map  功能,将编译后的代码映射回原始源代码
1 2 3 4 module .exports = {  mode : "development" ,   devtool : "inline-source-map"  } 
 
HTML模版 1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44 45 46 47 48 plugins: [      new  htmlWebpackPlugin(),      new  htmlWebpackPlugin({     title : "app" ,     "meta" : {       "viewport" : "width=device-width, initial-scale=1, shrink-to-fit=no" ,     },     "base" : {       "href" : "https://github.com" ,       "target" : "_blank"      },     inject : "head" ,     favicon : "./src/favicon.icon" ,     template : "./src/app_template.html" ,     filename : "app.html" ,   }),      new  htmlWebpackPlugin({     template : "./src/minify_template.html" ,     filename : "minify.html" ,     minify :{       useShortDoctype : true ,                       collapseWhitespace : true ,                    removeComments : true ,                        removeRedundantAttributes : true ,             removeScriptTypeAttributes : true ,            removeStyleLinkTypeAttributes : true ,       }   }) ] 
 
分离CSS及压缩 在上述案例的基础上导出CSS样式及其压缩样式
            npm install mini-css-extract-plugin optimize-css-assets-webpack-plugin –save-dev
           
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 const  path = require ("path" );const  htmlWebpackPlugin = require ("html-webpack-plugin" );const  MiniCssExtractPlugin = require ("mini-css-extract-plugin" );const  OptimizeCSSAssetsPlugin = require ("optimize-css-assets-webpack-plugin" );module .exports = {  mode : "development" ,   entry : "./src/index.js" ,   output : {     path : path.resolve(__dirname, "dist" ),     filename : "bundle.js" ,   },   module : {     rules : [{       test : /\.css$/ ,       use: [MiniCssExtractPlugin.loader, "css-loader" ]     }]   },   plugins : [     new  htmlWebpackPlugin({       template : "./src/index.html" ,       filename : "index.html" ,       title : "css"      }),     new  MiniCssExtractPlugin(),     new  OptimizeCSSAssetsPlugin()   ] } 
 
scss 压缩JS webpack4.0.0+ 内置了 uglifyjs-webpack-plugin ,打包时 mode 值为 production 就会默认开启js压缩功能
优化图片 使用 url-loader  插件优化图片,将小图片转化成 base64 压缩,防止小图片太多请求次数太多
            npm install –save-dev url-loader
           
1 2 3 4 5 6 7 8 9 10 11 12 module : {  rules : [{     test : /\.(png|svg|jpg|gif)$/ ,     use: [{       loader : "url-loader" ,       options : {         limit : 8192 ,                 outputPath : "img/"          }     }]   }] }, 
 
清理目录 使用 clean-webpack-plugin  清理输出目录内多余的文件,引用插件时注意引用方式,名称大小写也不能更改。原因请查阅 https://evolly.one/2020/02/27/123-webpack4-clean-webpack-plugin/ 
            npm install –save-dev clean-webpack-plugin
           
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 const  path = require ("path" );const  htmlWebpackPlugin = require ("html-webpack-plugin" );const  { CleanWebpackPlugin } = require ("clean-webpack-plugin" );module .exports = {  plugins : [     new  htmlWebpackPlugin({       title : "clean" ,       inject : "head" ,       template : "./src/app_template.html" ,       filename : "[hash].html" ,     }),     new  CleanWebpackPlugin()   ] } 
 
HMR 热更新 
            npm install –save-dev webpack-dev-server
           
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 const  path = require ("path" );const  webpack = require ("webpack" );const  htmlWebpackPlugin = require ("html-webpack-plugin" );module .exports = {  mode : "development" ,   devServer : {     contentBase : "./dist" ,                        watchContentBase : true ,                       hot : true ,                                    port : 9000 ,                                   compress : true ,                               open : true ,                                 },   plugins : [     new  htmlWebpackPlugin({       title : "clean" ,       inject : "head" ,       template : "./src/app_template.html" ,       filename : "index.html" ,     }),     new  webpack.HotModuleReplacementPlugin()   ] } 
 
常见错误 这是因为本地未安装 webpack 造成的,你可能是全局安装的 webpack
1 npm link webpack --save-dev