1️⃣ 安装和使用

初始化项目包

  1. 1. `**npm init**`

安装 webpack 和 webpak-cli

  1. 1. `**npm i webpack@4 webpack-cli@3 -D**`

创建 webpack 配置文件

  1. 1. webpack.config.js
  1. module.exports = {
  2. mode: 'development', // 模式配置
  3. entry: '', // 入口配置
  4. output: { }, // 出口配置
  5. module: { // loader 配置
  6. rules: []
  7. },
  8. plugins: [ // plugins 配置
  9. ],
  10. }

1️⃣ 打包环境

  1. "scripts": {
  2. "build": "webpack --mode=production",
  3. "dev": "webpack --mode=development"
  4. },
  5. 或者
  6. module.exports = {
  7. mode: 'development', // 开发模式
  8. mode: 'production', // 生产模式
  9. }

1️⃣ 入口配置

  1. module.exports = {
  2. // >>> string 形式
  3. // >>>>>> 单入口, 打包形成一个chunk, 输出一个 bundle 文件, 此时 chunk 的名称默认是 main
  4. entry: './src/index.js',
  5. // >>> array 形式
  6. // >>>>>> 多入口, 所有入口文件最终只会形成一个 chunk, 输出出去只有一个 bundle 文件
  7. // >>>>>> 作用: 只有在 HMR 功能中让 html 热更新生效
  8. entry: ['./src/index.js', './src/one.js'],
  9. // >>> object 形式
  10. // >>>>>> 多入口: 有几个入口文件就形成几个 chunk, 同时输出出去就有几个 bundle 文件, 此时 chunk 的名称是 key
  11. // >>>>>> 作用: 只有在 HMR 功能中让 html 热更新生效
  12. entry: {
  13. main: "./src/index.js", // 键: chunk 名 值: 入口模块
  14. one: "./src/one.js"
  15. },
  16. // >>> 特殊用法
  17. entry: {
  18. main: "./src/index.js",
  19. one: ["./src/one.js", "./src/two.js"]
  20. },
  21. }

1️⃣ 出口配置

  1. var path = require("path"); // 导出一个对象, 用以 __dirname 配置绝对路径
  2. module.exports = {
  3. output: {
  4. // ---------- 配置输出地址 ----------
  5. // >>> 配置输出文件输出的文件地址 ( 将所有资源打包输出到的文件夹 ), 必须配置一个绝对路径
  6. path: path.resolve(__dirname, 'builder'), // 将所有资源打包输出到 builder 文件里 ( 不配置默认为 dist 文件 )
  7. // ---------- 配置打包后的 js 文件名 ----------
  8. // >>> 静态规则
  9. filename: 'jsPackName.js', // 打包后的 js 文件名为 jsPackName.js
  10. // >>> 动态规则
  11. // >>>>>> [name]: 在入口为多入口时 [name] 会在输出时替换为 chunk名, [name] 想要生效如果必须以对象的形式配置
  12. // >>>>>> [hash]: 取 hash 作为名字一部分的原因是, 浏览器会有缓存, 当浏览器生成缓存后, 如果文件名不变浏览器始终会使用缓存的 js 文件, 如果使用 hash 当文件内容有变化时, 最终打包生成的 js 文件的名字也会变化, 这样在内容更新后,浏览器请求时发现文件名不同, 就会重新请求 js 文件就不会使用缓存的文件了
  13. // >>>>>>>>> [hash:5]: 取最终的 hash 值前 5 位( 缺点: 如果统一使用最终的 hash 那么只要有一个文件有所变化所有的文件名都会变化, 浏览器则需要请求所有的 js 文件 )
  14. // >>>>>>>>> [chunkhash:5]: 取各自 chunk 的 hash 前 5 位( 优点: 各自的 js 文件使用各自的 hash 值, 文件内容更新只会影响自己的文件名, 不会影响其他的文件名, 浏览器不会重新请求不需要请求的文件 )
  15. filename: '[name].[chunkhash:5].js', // 打包后的 js 文件名为 [chunk名].[总的hash名的前5位].js
  16. // ---------- 所有资源在引入时的公共路径前缀 - 一般用于生产环境 ----------
  17. // 在出口处配置会影响所有用到 publicPath 的 loader 如果 loader 用到的路径不同应当配置在自己 loader 里
  18. publicPath: './',
  19. // ---------- js 暴露的全局赋值给谁 ----------
  20. libraryTarget: 'window', // 变量名添加到 window 上
  21. // libraryTarget: 'global', // 变量名添加到 global 上
  22. // libraryTarget: 'commonjs', // 变量名添加到 commonjs 上
  23. },
  24. }

1️⃣ HTML 配置

npm i -D html-webpack-plugin

  1. const HtmlWebpackPlugin = require('html-webpack-plugin');
  2. plugins: [
  3. new HtmlWebpackPlugin({
  4. template: "./src/html/html.html", // 选择生成 html 文件的模板
  5. filename: "html/webJHtml.html", // 输出的地址和名字
  6. title: "HTML文件标题", // 设置生成的 html 文件的标题
  7. chunks:[one], // 指定生成的 html 文件引入哪些 js(chunk名) 不指定将会全部引入所有的入口文件
  8. minify: {
  9. removeComments: true, // 清除所有注释
  10. collapseWhitespace: true,// 清除所有空格
  11. removeRedundantAttributes: true, // 移除无用的标签
  12. useShortDoctype: true, // 使用短的文档声明
  13. removeEmptyAttributes: true, // 移除空标签
  14. removeStyleLinkTypeAttributes: true, // 移除 rel="stylesheel"
  15. keepClosingSlash: true, // 自结束
  16. minifyJS: true, // 压缩行内 js
  17. minifyCSS: true, // 压缩行内 css
  18. minifyURLs: true, // 压缩行内 url
  19. }
  20. }),
  21. ],

2️⃣ 多页面打包

  1. // 多页面打包配合多入口设置
  2. entry: {
  3. common: ['./node_modules/jquery/dist/jquery.js', './src/js/common.js'],
  4. index1: './src/js/index1.js',
  5. index2: './src/js/index2.js',
  6. index3: './src/js/index3.js',
  7. },
  8. // 配置多页面打包
  9. new HtmlWebpackPlugin({
  10. template: './src/index.html',
  11. filename: 'index1.html',
  12. chunks: ['common', 'index1']
  13. }),
  14. new HtmlWebpackPlugin({
  15. template: './src/index2.html',
  16. filename: 'index2.html',
  17. chunks: ['common', 'index2']
  18. }),
  19. new HtmlWebpackPlugin({
  20. template: './src/index3.html',
  21. filename: 'index3.html',
  22. chunks: ['common', 'index3']
  23. }),

1️⃣ CSS 配置

2️⃣ style 样式内联打包

**npm i -D style-loader css-loader less less-loader**

  1. module: {
  2. rules: [
  3. {
  4. test: /\.css$/, // 检查文件是否以 .less 结尾( 检查是否是 less 文件 )
  5. use: [
  6. 'style-loader', // 创建 style 标签,将 css 代码写在页面中的 style 标签中
  7. 'css-loader?modules', // 将 css 以 commonjs 方式整合到 js 文件中 >>> modules 开启 css-loader 的 module 模式
  8. 'less-loader' // 将 less 文件解析成 css 文件
  9. ]
  10. },
  11. ]
  12. },

2️⃣ 提取 CSS 成单独文件

**npm install -D mini-css-extract-plugin**

  1. const MiniCssExtractPlugin = require("mini-css-extract-plugin");
  2. module: {
  3. rules: [
  4. {
  5. test: /\.less$/,
  6. use: [
  7. MiniCssExtractPlugin.loader, // 负责记录要生成的 css 文件的内容
  8. 'css-loader',
  9. 'less-loader'
  10. ]
  11. },
  12. ]
  13. },
  1. plugins: [
  2. new MiniCssExtractPlugin({
  3. filename: "css/[name].[contenthash:5].css", // 在什么地方是输出 css 文件, 名字是什么
  4. })
  5. ],

2️⃣ css 的兼容性处理

**npm i -D postcss postcss-loader@4 postcss-preset-env**
webpack4 需要使用 postcss-loader@4

  1. const MiniCssExtractPlugin = require("mini-css-extract-plugin");
  2. module: {
  3. rules: [
  4. {
  5. test: /\.css$/,
  6. use: [
  7. MiniCssExtractPlugin.loader, // 负责记录要生成的 css 文件的内容
  8. 'css-loader',
  9. 'postcss-loader'
  10. ]
  11. },
  12. ]
  13. },

配置 postcss , 创建 **.postcss.config.js** 配置

  1. module.exports = {
  2. plugins: {
  3. // 自动厂商前缀
  4. "postcss-preset-env": {} // {} 中可以填写插件的配置
  5. }
  6. }

配置 **css** 兼容, 创建 **.browserslistrc** 文件 ( .browserslistrc 文件配置同样适用于 js 文件的兼容 )

  1. last 2 version
  2. > 1% in CN
  3. not ie <= 8

2️⃣ 压缩 css

**npm install optimize-css-assets-webpack-plugin --save-dev**

  1. const OptimizeCssAssetsPlugin = require('optimize-css-assets-webpack-plugin');
  2. // 精简版
  3. new OptimizeCssAssetsPlugin()
  4. // 配置版
  5. new OptimizeCssAssetsPlugin({
  6. cssProcessorPluginOptions: {
  7. preset: ['default', { discardComments: { removeAll: true } }], // 移除所有的css注释
  8. },
  9. cssProcessorOptions: { // 解决没有 source map 的问题 ( 不配置则不会生成源码地图 )
  10. map: {
  11. inline: false,
  12. annotation: true,
  13. }
  14. }
  15. })

1️⃣ JS 配置

2️⃣ 语法检查

js语法检测

  1. 1. 语法检测: 依赖库 eslint-loader eslin
  2. 2. 设置检测规则:推荐使用 airbnb 规则,依赖库 eslin eslint-plugin-import eslint-config-airbnb-base
  3. 1. 需要设置在 package.json eslintConfig 中设置

安装 loader

  1. 1. npm install eslint-loader eslint eslint-plugin-import eslint-config-airbnb-base --save-dev
  2. 1. 备注 1:在:eslint.org 网站 -> userGuide -> Configuring ESLint 查看如何配置
  3. 2. 备注 2:在:eslint.org 网站 -> userGuide -> Rules 查看所有规则

配置 loader

  1. module: {
  2. rules: [
  3. {
  4. test: /\.js$/, // 只检测js文件
  5. exclude: /node_modules/, // 排除 node_modules 文件夹
  6. loader: 'eslint-loader',
  7. options: {
  8. fix: true // 自动修复 eslint 错误
  9. },
  10. enforce: "pre", // 优先执行
  11. /*
  12. 正常来说,一个文件只能被一个loader处理
  13. 当一个文件要被多个loader处理,那么一定要指定loader执行的先后顺序
  14. 先执行 eslint 在执行 babel
  15. 所有在这里设置 enforce: "pre" 优先执行语法检测 在进行兼容性处理
  16. */
  17. },
  18. ]
  19. }

方法一:不使用airbnb规则:修改 package.json

  1. "eslintConfig": {
  2. "parserOptions": {
  3. "ecmaVersion": 6, // 支持es6
  4. "sourceType": "module" // 使用es6模块化
  5. },
  6. "env": { // 设置环境
  7. "browser": true, // 支持浏览器环境: 能够使用window上的全局变量
  8. "node": true // 支持服务器环境: 能够使用node上global的全局变量
  9. },
  10. "globals": { // 声明使用的全局变量, 这样即使没有定义也不会报错了
  11. "$": "readonly" // $ 只读变量
  12. },
  13. "rules": { // eslint检查的规则 0 忽略 1 警告 2 错误
  14. "no-console": 0, // 不检查console
  15. "eqeqeq": 2, // 用==而不用===就报错
  16. "no-alert": 2 // 不能使用alert
  17. },
  18. "extends": "eslint:recommended" // 使用 eslint 推荐的默认规则 https://cn.eslint.org/docs/rules/
  19. },

方法二:使用 airbnb 规则:修改 package.json

  1. // 使用 airbnb 规则时可以搭配其他规则使用
  2. "eslintConfig": {
  3. "extends": "airbnb-base" // 继承 airbnb规则
  4. },

2️⃣ babel

**npm i -D @babel/core @babel/cli @babel/preset-env regenerator-runtime core-js**

  1. # 按文件编译
  2. babel 要编译的文件 -o 编辑结果文件
  3. # 按目录编译
  4. babel 要编译的整个目录 -d 编译结果放置的目录

3️⃣ .browserslistrc - 浏览器兼容

  1. last 3 version
  2. > 1%
  3. not ie <= 8

3️⃣ .babelrc - babel 预设

  1. {
  2. "presets": [
  3. ["@babel/preset-env", {
  4. "useBuiltIns": "usage",
  5. "corejs": 3
  6. }]
  7. ]
  8. }

3️⃣ webpack 使用 babel

  1. module: {
  2. rules: [
  3. { test: /\.js$/, use: "babel-loader" }
  4. ]
  5. }

2️⃣ 压缩

生产模式下默认压缩 JS 代码

1️⃣ TS 配置

ts-loader 官方包 - 一般都会使用官方包

  1. 1. `yarn add ts-loader@8 --dev` webpack4 支持的是 ts-loader 8 版本

awesome-typescript-loader 民间包

  1. 1. `npm install awesome-typescript-loader --save-dev`

loader 需要 typescript 的支持,需要安装 typescript 包

  1. 1. `yarn add -D typescript`
  1. module: {
  2. rules: [
  3. {
  4. test: "/.ts$/", loader: 'ts-loader' // 使用 ts-loader 来解析 .ts 文件
  5. }
  6. ]
  7. },
  8. resolve: {
  9. extensions: ['ts', 'js'] // 使用模块化时导入的文件没有后缀名,webpack 默认解析 js 文件不认识 ts 文件,这里配置省略后缀名的解析规则
  10. }

1️⃣ 图片配置

2️⃣ 打包样式中的图片

npm install file-loader url-loader --save-dev
补充:url-loader 是对象 file-loader 的上层封装,使用时需配合 file-loader 使用。

  1. module: {
  2. rules: [
  3. {
  4. test: /\.(png)|(gif)|(jpg)$/,
  5. use: {
  6. // 使用 file-loader 来处理 js 中引用的图片, 打包生成引用的图片
  7. loader: "url-loader",
  8. options: {
  9. // 为打包的图片命名
  10. name: '[name].[hash:8].[ext]',
  11. // 打包的图片保存在的文件夹
  12. outputPath: 'img',
  13. // 图片的 url 地址
  14. publicPath: '../img',
  15. // 如果 js 使用 CommonJS 导入图片
  16. // >>> 不设置 esModule ( html标签为 <img src = "[object module]" > )
  17. // >>> 设置后 ( html标签为 <img src="..img/1.7asd5fgh.jpg"> )
  18. // 如果 JS 使用 ES6 模块化语法可以不设置, 但是推荐始终设置
  19. // 出现问题的原因是 webpack 会吧 require() 中的代码当做 JS 执行
  20. // webpack 使用 CommonJS 语法解析而 url-loader 使用 ES6 语法解析
  21. // 设置 esModule: false 就是禁用 url-loader 使用 ES6 转而使用 CommonJS
  22. esModule: false
  23. }
  24. }
  25. }
  26. ]
  27. },

2️⃣ 打包 html 中的 img 图片

npm i -D html-withimg-loader
webpack4 使用 html-loader 的话要使用 html-loader@1.3.2 版本 2 版本是不兼容 webpack4 的, html-withimg-loader 可以使用最新版

  1. module: {
  2. rules: [
  3. {
  4. test: /\.(html)$/,
  5. loader: 'html-withimg-loader' // 或 loader: 'html-loader'
  6. },
  7. ]
  8. }

1️⃣ 其他文件配置

npm install file-loader --save-dev
概述:其他资源 webpack 不能解析,需要借助 loader 编译解析
添加字体文件

  1. 1. src/media/iconfont.eot
  2. 2. src/media/iconfont.svg
  3. 3. src/media/iconfont.ttf
  4. 4. src/media/iconfont.woff
  5. 5. src/media/iconfont.woff2

修改样式 iconfont.css

  1. @font-face {
  2. font-family: 'iconfont';
  3. src: url('../media/iconfont.eot');
  4. src: url('../media/iconfont.eot?#iefix') format('embedded-opentype'),
  5. url('../media/iconfont.woff2') format('woff2'),
  6. url('../media/iconfont.woff') format('woff'),
  7. url('../media/iconfont.ttf') format('truetype'),
  8. url('../media/iconfont.svg#iconfont') format('svg');
  9. }
  10. .iconfont {
  11. font-family: "iconfont" !important;
  12. font-size: 16px;
  13. font-style: normal;
  14. -webkit-font-smoothing: antialiased;
  15. -moz-osx-font-smoothing: grayscale;
  16. }

修改 html,添加字体
js 入口文件引入
import ‘../css/iconfont.css’;
配置 loader

  1. {
  2. test: /\.(eot|svg|woff|woff2|ttf|mp3|mp4|avi)$/, // 处理其他资源
  3. loader: 'file-loader',
  4. options: {
  5. outputPath: 'builder', // 输出的文件地址
  6. name: '[hash:8].[ext]' // [hash:8]hash值保留8位 [ext] 使用原来的扩展名
  7. }
  8. }

1️⃣ devtool

  1. module.exports = {
  2. devtool: 'cheap-module-eval-source-map', // 开发环境推荐
  3. devtool: 'cheap-module-source-map' // 生产环境推荐
  4. }

1️⃣ 常用扩展

2️⃣ 清除输出目录

npm install --save-dev clean-webpack-plugin

  1. const { CleanWebpackPlugin } = require('clean-webpack-plugin');
  2. module.exports = {
  3. plugins: [
  4. new CleanWebpackPlugin(),
  5. ]
  6. }

2️⃣ 自动生成页面

npm i --save-dev html-webpack-plugin@4

  1. 1. webpack4 要安装4版本的 html-webpack-plugin
  2. 2. webpack5 要安装5版本的 html-webpack-plugin
  1. const HtmlWebpackPlugin = require('html-webpack-plugin')
  2. module.exports = {
  3. plugins: [
  4. new HtmlWebpackPlugin({
  5. // 以 src 文件夹里的 html 文件夹里的 index.html 文件为 html 模板
  6. template: "./src/html/index.html",
  7. // 在打包文件夹里的 html 文件夹里生成 webJHtml.html 文件
  8. filename: "./html/webJHtml.html"
  9. })
  10. ],
  11. }

2️⃣ 复制静态资源

npm install copy-webpack-plugin@6 --save-dev
copy-webpack-plugin 插件和 webpack 有版本兼容问题 webpack4版本 和 copy-webpack-plugin6版本 是兼容的

  1. module.exports = {
  2. plugins: [
  3. new CopyPlugin({
  4. patterns: [
  5. // 将 src 文件夹里的 img 文件夹里的全部文件复制到打包文件的 img 文件夹里
  6. { from: "src/img", to: "img" }
  7. ],
  8. }),
  9. ]
  10. }

2️⃣ 开发服务器

npm i -D webpack-dev-server
webpack-dev-server 有兼容性 webpack-dev-serve 只兼容 webpack4 和 webpack-cli3 最高版本是兼容的

  1. // package.json
  2. "devDependencies": {
  3. "webpack": "^4.46.0",
  4. "webpack-cli": "^3.3.12",
  5. "webpack-dev-server": "^3.11.2"
  6. }
  7. "scripts": {
  8. "server": "webpack-dev-server"
  9. },
  1. // 基本配置
  2. module.exports = {
  3. devServer: {
  4. open: true, // 自动打开浏览器
  5. compress: true, // 启动gzip压缩
  6. port: 3000, // 端口号
  7. }
  8. }
  9. // 详细配置 - 适用于开发环境
  10. module.exports = {
  11. devServer: {
  12. index: "index.html", // 默认的要打开的 html 文件
  13. contentBase: resolve(__dirname, 'build'), // 运行代码的目录
  14. publicPath: "/xuni/", // 虚拟打包路径 ( 配置后文件并不会真正的被打包, 而是会生成一个虚拟的打包文件, 常用于开发阶段不用生成打包文件的情况 ) 这个设置同样可以配置在出口中
  15. watchContentBase: true, // 监视 contentBase 目录下的所有文件, 一旦文件变化就会 reload 重载
  16. watchOptions: { // 配置忽略文件
  17. ignored: /node_modules/
  18. },
  19. open: true, // 自动打开浏览器
  20. compress: true, // 启动gzip压缩
  21. port: 4000, // 端口号
  22. hot: true , // 开启热模替换功能 HMR
  23. host: 'localhost', // 域名
  24. clientLogLevel: 'none', // 不要显示启动服务器的日志信息
  25. quiet: true, // 除了一些基本的启动信息外其他信息都不显示
  26. overlay: false, // 如果出错了, 不要全屏提示
  27. proxy: { // 服务器代理 >>> 解决开发环境的跨域问题
  28. '/api': {
  29. // 当请求 http://localhost:9000/api/xxx 的地址时会更改为 http://www.baidu.com/api/xxx
  30. // 将 /api 之前的协议域名端口号更改为 target 的协议域名端口号
  31. target: 'http://www.baidu.com',
  32. // 如果不希望 /api 包含其中可以做如下配置结果为: http://www.baidu.com/api/xxx ( 将 /api 替换为 '' )
  33. pathRewrite: { '^/api': '' }
  34. }
  35. },
  36. stats: { // stats 控制的是构建过程中控制台的输出内容
  37. // 对于 webpack-dev-server,这个属性要放在 devServer 对象里。
  38. // devServer 的 starts 配置同总体的 starts 设置相同
  39. }
  40. }
  41. }

2️⃣ 内置插件

  1. // 插件配置
  2. const webpack = require("webpack")
  3. plugins:[
  4. new webpack.插件名(options)
  5. ]

3️⃣ DefinePlugin - 全局常量定义

  1. new webpack.DefinePlugin({
  2. PI: `Math.PI`, // PI = Math.PI
  3. VERSION: `"1.0.0"`, // VERSION = "1.0.0"
  4. DOMAIN: JSON.stringify("全局变量")
  5. })
  6. // js 中使用
  7. console.log(PI); // 打包结果 console.log(Math.PI)
  8. console.log(VERSION); // 打包结果 console.log("1.0.0")
  9. console.log(DOMAIN); // 打包结果 console.log("全局变量")

3️⃣ BannerPlugin - 生成的文件头部添加

  1. new webpack.BannerPlugin({
  2. banner: `
  3. hash:[hash]
  4. chunkhash:[chunkhash]
  5. name:[name]
  6. author:chen
  7. corporation:baidu`
  8. })

3️⃣ ProvidePlugin - 自动加载模块

  1. new webpack.ProvidePlugin({
  2. $: 'jquery',
  3. _: 'lodash'
  4. })
  5. // js 中使用
  6. $('#item'); // <= 起作用
  7. _.drop([1, 2, 3], 2); // <= 起作

1️⃣ 其他配置

2️⃣ target - 打包运行环境

  1. module.exports = {
  2. target:"web" // 默认值
  3. }

设置打包结果最终要运行的环境,常用值有

  1. 1. web:打包后的代码运行在 web 环境中
  2. 2. node:打包后的代码运行在 node 环境中
  3. 3. 其他:[https://www.webpackjs.com/configuration/target/](https://www.webpackjs.com/configuration/target/)

2️⃣ module.noParse - 不解析匹配的模块

不解析正则表达式匹配的模块,通常用它来忽略那些大型的单模块库,以提高构建性能
解释 :大型的单文件库, 比如 jquery , jquery 的代码我们在使用时打包不需要再次经过 webpack 的解析过程, 就可以设置 noParse:/jquery/就可以配置 webpack 在打包时忽略 jquery 的引用, jquery 的代码直接省略掉 webpack 的解析过程, 直接打包

  1. module.exporets = {
  2. noParse:/jquery/
  3. }

2️⃣ resolve - 控制模块解析过程

resolve 的相关配置主要用于控制模块解析过程

  1. module.exports = {
  2. resolve: {
  3. alias: {
  4. "@": path.resolve(__dirname, 'src'),
  5. "_": __dirname
  6. }
  7. extensions: ['.js','.json'] // 省略后缀名 webpack 会检查哪些文件,这样配置的话要比免不同类型的文件同名
  8. modules: [resolves(__dirname, '../../node_modules'), 'node_modules']
  9. }
  10. }

3️⃣ alias - 导入模块的路径别名

配置导入模块的路径别名

  1. 1. 优点:简写路径
  2. 2. 缺点:写路径没有提示
  1. alias: {
  2. "@": path.resolve(__dirname, 'src'),
  3. "_": __dirname
  4. }

有了alias(别名)后,导入语句中可以加入配置的键名,例如**require("@/abc.js")**,webpack 会将其看作是**require(src的绝对路径+"/abc.js")**
在大型系统中,源码结构往往比较深和复杂,别名配置可以让我们更加方便的导入依赖

3️⃣ extensions - 省略文件路径的后缀名

配置省略文件路径的后缀名 - 有同名文件时不推荐使用因为文件名一样时会出错

  1. extensions: [".js", ".json"] // 默认值

当解析模块时,遇到无具体后缀的导入语句,例如**require("test")**,会依次测试它的后缀名

  1. 1. 导入的 test test.js 文件吗?
  2. 2. 如果是导入 test.js 如果不是
  3. 3. 导入的 test test.json 文件吗?
  4. 4. 如果是导入 test.json 如果不是报错

如果有其他的后缀省略会依次遍历测试

3️⃣ modules - 解析模块时的目录

  1. modules: ["node_modules"] // 默认值

当解析模块时,如果遇到导入语句,**require("test")**,webpack 会从下面的位置寻找依赖的模块

  1. 1. 当前目录下的`**node_modules**`目录
  2. 2. 上级目录下的`**node_modules**`目录

modules 中的目录可更改,更改后 webpack 在解析时就会在更改的目录寻找依赖

2️⃣ externals - 排除掉配置的配置的源码

  1. module.exports = {
  2. externals: {
  3. jquery: "$",
  4. lodash: "_"
  5. }
  6. }

从最终的bundle中排除掉配置的配置的源码,例如,入口模块是

  1. //index.js
  2. require("jquery")
  3. require("lodash")

生成的bundle是:

  1. (function(){
  2. ...
  3. })({
  4. "./src/index.js": function(module, exports, __webpack_require__){
  5. __webpack_require__("jquery")
  6. __webpack_require__("lodash")
  7. },
  8. "jquery": function(module, exports){
  9. //jquery的大量源码
  10. },
  11. "lodash": function(module, exports){
  12. //lodash的大量源码
  13. },
  14. })

但有了上面的配置后,则变成了

  1. (function(){
  2. ...
  3. })({
  4. "./src/index.js": function(module, exports, __webpack_require__){
  5. __webpack_require__("jquery")
  6. __webpack_require__("lodash")
  7. },
  8. "jquery": function(module, exports){
  9. module.exports = $;
  10. },
  11. "lodash": function(module, exports){
  12. module.exports = _;
  13. },
  14. })

这比较适用于一些第三方库来自于外部CDN的情况,这样一来,即可以在页面中使用CDN,又让 bundle 的体积变得更小,还不影响源码的编写

2️⃣ stats - 控制台的输出内容

stats控制的是构建过程中控制台的输出内容
https://webpack.docschina.org/configuration/stats/#root

  1. module.exports = {
  2. //...
  3. stats: {
  4. colors: true, // 告知 stats 是否输出不同的颜色( 控制台的输出带颜色 )
  5. }
  6. };

1️⃣ 性能优化

2️⃣ 减少模块解析

  1. module:{
  2. noParse:/jquery/, // 不去解析 jquery 中的依赖库
  3. }

2️⃣ 优化 loader 性能

  1. module.exports = {
  2. module: {
  3. rules: [
  4. {
  5. test: /\.js$/,
  6. exclude: /lodash/, // 排除 lodash 库 有些会设置排除 /none_modules/
  7. use: ['cache-loader','......loader'] // 缓存 loader 下次打包不改变时不会在打包
  8. }
  9. ]
  10. }
  11. }

2️⃣ HMR 热更新

3️⃣ 配置 webpack.config.js

  1. module.exports = {
  2. devServer:{
  3. hot:true // 开启HMR
  4. },
  5. plugins:[
  6. // 可选
  7. new webpack.HotModuleReplacementPlugin()
  8. ]
  9. }

3️⃣ 修改入口文件

  1. // 在入口文件的头部加入这段代码 就表示接受了热更新 检测到后会执行代码的热更新
  2. if(module.hot){ // 是否开启了热更新
  3. module.hot.accept() // 接受热更新
  4. }

2️⃣ ESLint

ESLint 通常结合编辑器使用

2️⃣ tree shaking

webpack2 开始就支持了 tree shaking,只要是生产环境,tree shaking 自动开启

2️⃣ 懒加载

当满足某些条件后加载 js ,下边是使用例子,语法为懒加载语法

  1. // 动态加载 import
  2. document.getElementById('ljz').onclick = function () {
  3. import( /*webpackChunkName:JS2*/ '../js/JS2.js').then(({
  4. fun
  5. }) => {
  6. fun();
  7. }).catch(() => {
  8. console.log('文件加载失败');
  9. });
  10. }

2️⃣ 包分析器 bundle analyzer

使用插件来分析包的大小根据分析来优化包

  1. const WebpackBundleAnalyzer = require("webpack-bundle-analyzer").BundleAnalyzerPlugin;
  2. module.exports = {
  3. mode: "production",
  4. plugins: [new WebpackBundleAnalyzer()]
  5. };

2️⃣ gzip

  1. const CmpressionWebpackPlugin = require("compression-webpack-plugin")
  2. plugins: [
  3. new CmpressionWebpackPlugin({
  4. test: /\.js/,
  5. minRatio: 0.5
  6. })
  7. ]