Webpack详细开发教程

Webpack实战教程

目录

1.webpack简介

1.1版本要求
Node.js >= 10
webpack >= 4.26
1.2webpack简介
  • 一种前端资源构建工具
  • 一个静态模块打包器
  • 通过webpack可以将前端所有的资源文件(js/json/css/img/less)等资源根据相互依赖关系进行静态分析,打包生成对应的静态资源bundle
  • 在这里插入图片描述
1.2webpack五个核心概念
  • entry:入口
  • output:输出
  • loader:处理非js文件,因为webpack只能识别js,所以需要将其他的非js文件转换为js
  • plugins:插件,用于进行打包优化,压缩,定义环境中的变量等
  • mode:模式,用于区分开发环境和生产环境,分为development和production

2.webpack初体验

2.1初始化项目
// 初始化项目目录
npm init -y
// 安装webpack、webpack-cli
npm i webpack webpack-cli -D

  • 项目目录

项目目录

  • index.js文件
function add(x, y) {
  return x + y
}
console.log(add(1, 2));
  • 开发和生产模式下对项目进行打包
//development
npx webpack ./src/index.js -o ./dist --mode=development
//production
npx webpack ./src/index.js -o ./dist --mode=production
  • 打包完成生成dist文件夹及该文件夹下的main.js文件

在这里插入图片描述

2.2.引入json文件
  • person.json
{
  "name": "Tom",
  "age": 18
}
  • 引入index.js文件中
import person from './person.json'
function add(x, y) {
  return x + y
}
console.log(add(1, 2));
console.log(person);
  • 对项目进行打包,并运行打包后的文件,发现能够正常输出,说明webpack可以识别js和json格式的文件
node .\dist\main.js
//输出
3
{"name": "Tom", "age": 18}
2.3.webpack配置文件
// 引入node的路径path模块
const path = require("path")
module.exports = {
  // entry入口文件地址
  entry: "./src/index.js",
  // output输出文件
  output: {
    filename: "bundle.js",
    path: path.resolve(__dirname, 'dist')
  },
  // loader相关配置
  module: {
    rules: []
  },
  // plugins插件相关配置
  plugins: [],
  // mode模式
  mode: 'development'
  // mode: 'production'
}
  • 打包生成bundle.js文件
npx webpack
2.4.打包样式资源文件
  • 安装相关的loader依赖
npm i css-loader style-loader -D
  • 创建css文件,并引入index.js文件中
html
body{
  padding: 0px;
  margin: 0px;
  background-color: aqua;
}

import './style.css'
  • 配置webpack
// 引入node的路径path模块
const path = require("path")
module.exports = {
  // entry入口文件地址
  entry: "./src/index.js",
  // output输出文件
  output: {
    filename: "bundle.js",
    path: path.resolve(__dirname, 'dist')
  },
  // loader相关配置
  module: {
    rules: [
      {
        // 正则匹配文件名
        test: /\.css$/,
        // 使用的loader处理文件,执行顺序是从下到上
        use: [
          // 创建style标签,插入到head中
          'style-loader',
          // 加载css相关文件,转换成能识别的js文件
          'css-loader'
        ]
      }
    ]
  },
  // plugins插件相关配置
  plugins: [],
  // mode模式
  mode: 'development'
  // mode: 'production'
}
  • 执行打包命令,发现css文件被成功的打包了
2.5.打包样式资源less文件
  • 安装less及less-loader依赖
 npm i less less-loader -D
  • webpack相关配置
// 引入node的路径path模块
const path = require("path")
module.exports = {
  // entry入口文件地址
  entry: "./src/index.js",
  // output输出文件
  output: {
    filename: "bundle.js",
    path: path.resolve(__dirname, 'dist')
  },
  // loader相关配置
  module: {
    rules: [
      {
        // 正则匹配文件名
        test: /\.css$/,
        // 使用的loader处理文件,执行顺序是从下到上
        use: [
          // 创建style标签,插入到head中
          'style-loader',
          // 加载css相关文件,转换成能识别的js文件
          'css-loader'
        ]
      },
      {
        // 正则匹配文件名
        test: /\.less$/,
        // 使用的loader处理文件,执行顺序是从下到上
        use: [
          // 创建style标签,插入到head中
          'style-loader',
          // 加载css相关文件,转换成能识别的js文件
          'css-loader',
          // 使用less-loader将less文件转换成css文件
          'less-loader'
        ]
      }
    ]
  },
  // plugins插件相关配置
  plugins: [],
  // mode模式
  mode: 'development'
  // mode: 'production'
}
  • 执行打包命令,发现less文件被成功的打包了
2.6.打包HTML资源
  • 安装插件html-webpack-plugin
npm i html-webpack-plugin -D
  • 此插件的目的是默认创建一个index.html文件,并引入打包后的bundle.js文件,如下是webpack相关配置
// 引入node的路径path模块
const path = require("path")
// 引入插件
const HtmlWebpackPlugin = require('html-webpack-plugin')
module.exports = {
  // entry入口文件地址
  entry: "./src/index.js",
  // output输出文件
  output: {
    filename: "bundle.js",
    path: path.resolve(__dirname, 'dist')
  },
  // loader相关配置
  module: {
    rules: [
      {
        // 正则匹配文件名
        test: /\.css$/,
        // 使用的loader处理文件,执行顺序是从下到上
        use: [
          // 创建style标签,插入到head中
          'style-loader',
          // 加载css相关文件,转换成能识别的js文件
          'css-loader'
        ]
      },
      {
        // 正则匹配文件名
        test: /\.less$/,
        // 使用的loader处理文件,执行顺序是从下到上
        use: [
          // 创建style标签,插入到head中
          'style-loader',
          // 加载css相关文件,转换成能识别的js文件
          'css-loader',
          // 使用less-loader将less文件转换成css文件
          'less-loader'
        ]
      }
    ]
  },
  // plugins插件相关配置
  plugins: [
    new HtmlWebpackPlugin({
      // html模板文件的位置,打包完成后会在dist文件夹下生成index.html文件,并且会默认的引入bundle.js
      template: './src/index.html'
    })
  ],
  // mode模式
  mode: 'development'
  // mode: 'production'
}

在这里插入图片描述

2.7.打包图片资源
  • 安装依赖
npm i html-loader -D
  • 需要注意的是,这里的图片可以在js、css和html的img标签中引入,使用url-loader可以处理js和css中的图片,html中的图片需要使用html-loader进行单独的处理

  • webpack4中图片的loader配置较为繁琐

 {
        // 正则匹配文件名
        test: /\.(png|svg|jpg|jpeg|gif)$/i,
        loader: 'url-loader',
        options: {
          // 图片大小小于8kb,就会被base64编码
          // 优点:减少请求次数,减轻服务器压力
          // 缺点:js体积变大,速度变慢
          limit: 8 * 1024,
          // 问题:url-loader默认使用es6模块解析,而html-loader引入图片是common.js,解析时会出现【object module】
          // 解决:关闭url-loader的es6模块化,使用common.js解析
          esModule: false,
          // 自定义命名,取hash值的前十位
          name: '[hash:10].[ext]'
        }
      },
      // 处理html中的图片,让后续的loader进行解析
      {
        test: /\.html$/i,
        loader: 'html-loader'
      }
  • webpack5中对于图片的处理相对简单
// 引入node的路径path模块
const path = require("path")
// 引入插件
const HtmlWebpackPlugin = require('html-webpack-plugin')
module.exports = {
  // entry入口文件地址
  entry: "./src/index.js",
  // output输出文件
  output: {
    filename: "bundle.js",
    path: path.resolve(__dirname, 'dist'),
    // 自定义静态资源文件名
    assetModuleFilename: "images/[hash:10][ext][query]"
  },
  // loader相关配置
  module: {
    rules: [
      {
        // 正则匹配文件名
        test: /\.css$/,
        // 使用的loader处理文件,执行顺序是从下到上
        use: [
          // 创建style标签,插入到head中
          'style-loader',
          // 加载css相关文件,转换成能识别的js文件
          'css-loader'
        ]
      },
      {
        // 正则匹配文件名
        test: /\.less$/,
        // 使用的loader处理文件,执行顺序是从下到上
        use: [
          // 创建style标签,插入到head中
          'style-loader',
          // 加载css相关文件,转换成能识别的js文件
          'css-loader',
          // 使用less-loader将less文件转换成css文件
          'less-loader'
        ]
      },
      {
        // 正则匹配文件名
        test: /\.(png|svg|jpg|jpeg|gif)$/i,
        // webpack5
        type: 'asset'
      },
      // 处理html中的图片,让后续的loader进行解析
      {
        test: /\.html$/i,
        loader: 'html-loader'
      }
    ]
  },
  // plugins插件相关配置
  plugins: [
    new HtmlWebpackPlugin({
      // html模板文件的位置,打包完成后会在dist文件夹下生成index.html文件,并且会默认的引入bundle.js
      template: './src/index.html'
    })
  ],
  // mode模式
  mode: 'development'
  // mode: 'production'
}
2.8.打包字体资源
  • webpack4中的相关配置
{
  exclude:/\.(js|less|html|css)$/i,
  type:'file-loader',
  options:{
    name:'[hash:10].[ext]'
  }
}
  • webpack5中的相关配置
// 引入node的路径path模块
const path = require("path")
// 引入插件
const HtmlWebpackPlugin = require('html-webpack-plugin')
module.exports = {
  // entry入口文件地址
  entry: "./src/index.js",
  // output输出文件
  output: {
    filename: "bundle.js",
    path: path.resolve(__dirname, 'dist'),
    // 自定义静态资源文件名
    assetModuleFilename: "images/[hash:10][ext][query]"
  },
  // loader相关配置
  module: {
    rules: [
      {
        // 正则匹配文件名
        test: /\.css$/,
        // 使用的loader处理文件,执行顺序是从下到上
        use: [
          // 创建style标签,插入到head中
          'style-loader',
          // 加载css相关文件,转换成能识别的js文件
          'css-loader'
        ]
      },
      {
        // 正则匹配文件名
        test: /\.less$/,
        // 使用的loader处理文件,执行顺序是从下到上
        use: [
          // 创建style标签,插入到head中
          'style-loader',
          // 加载css相关文件,转换成能识别的js文件
          'css-loader',
          // 使用less-loader将less文件转换成css文件
          'less-loader'
        ]
      },
      {
        // 正则匹配文件名
        test: /\.(png|svg|jpg|jpeg|gif)$/i,
        // webpack5
        type: 'asset'
      },
      // 处理html中的图片,让后续的loader进行解析
      {
        test: /\.html$/i,
        loader: 'html-loader'
      },
      // 处理字体文件
      {
        test: /\.(woff|woff2|eot|ttf|otf)$/i,
        type: 'asset/resource'
      }
    ]
  },
  // plugins插件相关配置
  plugins: [
    new HtmlWebpackPlugin({
      // html模板文件的位置,打包完成后会在dist文件夹下生成index.html文件,并且会默认的引入bundle.js
      template: './src/index.html'
    })
  ],
  // mode模式
  mode: 'development'
  // mode: 'production'
}

3.Webpack开发环境基本配置

3.1.devServer开发服务器(自动编译,自动打开浏览器,自动刷新浏览器),特点就是开发服务器不会再dist文件夹下有任何的输出,他是在内存中完成的编译
  • 安装依赖
 npm i webpack-dev-server --D
  • 为了方便启动,可以在package.json文件中配置启动命令
  "scripts": {
    "test": "echo \"Error: no test specified\" && exit 1",
    "dev": "webpack serve",
    "build": "webpack"
  },
  • 然后执行npm run dev即可,不会在dist文件夹中有任何的输出

4.Webpack生产环境基本配置

4.1.如果按照开发环境进行配置的话会有以下几个问题
  • css通过js动态生成,会出现闪屏的问题
  • 代码没有压缩
  • 浏览器兼容性问题
4.2.提取css成单独的文件
  • 安装依赖
npm i mini-css-extract-plugin -D
  • 相关配置
// 引入node的路径path模块
const path = require("path")
// 引入插件
const HtmlWebpackPlugin = require('html-webpack-plugin')
const MiniCssExtractPlugin = require('mini-css-extract-plugin')
module.exports = {
  // devServer
  // webpack5
  devServer: {
    // 启动后自动打开浏览器
    open: true,
    // 监听端口号
    port: 8080
  },
  // entry入口文件地址
  entry: "./src/index.js",
  // output输出文件
  output: {
    filename: "bundle.js",
    path: path.resolve(__dirname, 'dist'),
    // 自定义静态资源文件名
    assetModuleFilename: "images/[hash:10][ext][query]"
  },
  // loader相关配置
  module: {
    rules: [
      {
        // 正则匹配文件名
        test: /\.css$/,
        // 使用的loader处理文件,执行顺序是从下到上
        use: [
          // 创建style标签,插入到head中
          // 'style-loader',
          // 如果使用了mini-css-extract-plugin插件,就不需要创建style标签插入head中了
          MiniCssExtractPlugin.loader,
          // 加载css相关文件,转换成能识别的js文件
          'css-loader'
        ]
      },
      {
        // 正则匹配文件名
        test: /\.less$/,
        // 使用的loader处理文件,执行顺序是从下到上
        use: [
          // 创建style标签,插入到head中
          // 'style-loader',
          // 如果使用了mini-css-extract-plugin插件,就不需要创建style标签插入head中了
          MiniCssExtractPlugin.loader,
          // 加载css相关文件,转换成能识别的js文件
          'css-loader',
          // 使用less-loader将less文件转换成css文件
          'less-loader'
        ]
      },
      {
        // 正则匹配文件名
        test: /\.(png|svg|jpg|jpeg|gif)$/i,
        // webpack5
        type: 'asset'
      },
      // 处理html中的图片,让后续的loader进行解析
      {
        test: /\.html$/i,
        loader: 'html-loader'
      },
      // 处理字体文件
      {
        test: /\.(woff|woff2|eot|ttf|otf)$/i,
        type: 'asset/resource'
      }
    ]
  },
  // plugins插件相关配置
  plugins: [
    new HtmlWebpackPlugin({
      // html模板文件的位置,打包完成后会在dist文件夹下生成index.html文件,并且会默认的引入bundle.js
      template: './src/index.html'
    }),
    // 提取css为单独的文件
    new MiniCssExtractPlugin({
      filename: "[name].css"
    })
  ],
  // mode模式
  mode: 'development'
  // mode: 'production'
}
4.3.css兼容性处理
  • 在处理css样式兼容性问题时,需要考虑两个方面,一是样式的确会有兼容性问题,二是当前的css需要兼容到哪个版本的浏览器也就是browserslist
//在package.json中,添加browserslist
"browserslist": {
    "development": [
      "last 1 version"
    ],
    "production": [
      "last 1 version",
      ">1%",
      "ie 10"
    ]
  }
  • webpack相关配置(webpack5)
// 引入node的路径path模块
const path = require("path")
// 引入插件
const HtmlWebpackPlugin = require('html-webpack-plugin')
const MiniCssExtractPlugin = require('mini-css-extract-plugin')
module.exports = {
  // devServer
  // webpack5
  devServer: {
    // 启动后自动打开浏览器
    open: true,
    // 监听端口号
    port: 8080
  },
  // entry入口文件地址
  entry: "./src/index.js",
  // output输出文件
  output: {
    filename: "bundle.js",
    path: path.resolve(__dirname, 'dist'),
    // 自定义静态资源文件名
    assetModuleFilename: "images/[hash:10][ext][query]",
    // 在生成文件之前清空output目录
    clean: true
  },
  // loader相关配置
  module: {
    rules: [
      {
        // 正则匹配文件名
        test: /\.css$/,
        // 使用的loader处理文件,执行顺序是从下到上
        use: [
          // 创建style标签,插入到head中
          // 'style-loader',
          // 如果使用了mini-css-extract-plugin插件,就不需要创建style标签插入head中了
          MiniCssExtractPlugin.loader,
          // 加载css相关文件,转换成能识别的js文件
          'css-loader',
          // 配置预加载样式postcss
          {
            loader: "postcss-loader",
            options: {
              postcssOptions: {
                plugins: [
                  [
                    "postcss-preset-env"
                  ]
                ]
              }
            }
          },
        ]
      },
      {
        // 正则匹配文件名
        test: /\.less$/,
        // 使用的loader处理文件,执行顺序是从下到上
        use: [
          // 创建style标签,插入到head中
          // 'style-loader',
          // 如果使用了mini-css-extract-plugin插件,就不需要创建style标签插入head中了
          MiniCssExtractPlugin.loader,
          // 加载css相关文件,转换成能识别的js文件
          'css-loader',
          // 配置预加载样式postcss
          {
            loader: "postcss-loader",
            options: {
              postcssOptions: {
                plugins: [
                  [
                    "postcss-preset-env"
                  ]
                ]
              }
            }
          },
          // 使用less-loader将less文件转换成css文件
          'less-loader'
        ]
      },
      {
        // 正则匹配文件名
        test: /\.(png|svg|jpg|jpeg|gif)$/i,
        // webpack5
        type: 'asset'
      },
      // 处理html中的图片,让后续的loader进行解析
      {
        test: /\.html$/i,
        loader: 'html-loader'
      },
      // 处理字体文件
      {
        test: /\.(woff|woff2|eot|ttf|otf)$/i,
        type: 'asset/resource'
      }
    ]
  },
  // plugins插件相关配置
  plugins: [
    new HtmlWebpackPlugin({
      // html模板文件的位置,打包完成后会在dist文件夹下生成index.html文件,并且会默认的引入bundle.js
      template: './src/index.html'
    }),
    // 提取css为单独的文件
    new MiniCssExtractPlugin({
      filename: "[name].css"
    })
  ],
  // mode模式
  mode: 'development'
  // mode: 'production'
}
4.4.css压缩
  • webpack4中使用optimize-css-assets-webpack-plugin
  • webpack5中使用css-minimizer-webpack-plugin
  • 安装依赖(此处以webpack5为例)
 npm i css-minimizer-webpack-plugin -D   
  • webpack配置
// 引入node的路径path模块
const path = require("path")
// 引入插件
const HtmlWebpackPlugin = require('html-webpack-plugin')
const MiniCssExtractPlugin = require('mini-css-extract-plugin')
const CssMinimizerPlugin = require('css-minimizer-webpack-plugin')
module.exports = {
  // devServer
  // webpack5
  devServer: {
    // 启动后自动打开浏览器
    open: true,
    // 监听端口号
    port: 8080
  },
  // entry入口文件地址
  entry: "./src/index.js",
  // output输出文件
  output: {
    filename: "bundle.js",
    path: path.resolve(__dirname, 'dist'),
    // 自定义静态资源文件名
    assetModuleFilename: "images/[hash:10][ext][query]",
    // 在生成文件之前清空output目录
    clean: true
  },
  // loader相关配置
  module: {
    rules: [
      {
        // 正则匹配文件名
        test: /\.css$/,
        // 使用的loader处理文件,执行顺序是从下到上
        use: [
          // 创建style标签,插入到head中
          // 'style-loader',
          // 如果使用了mini-css-extract-plugin插件,就不需要创建style标签插入head中了
          MiniCssExtractPlugin.loader,
          // 加载css相关文件,转换成能识别的js文件
          'css-loader',
          // 配置预加载样式postcss
          {
            loader: "postcss-loader",
            options: {
              postcssOptions: {
                plugins: [
                  [
                    "postcss-preset-env"
                  ]
                ]
              }
            }
          },
        ]
      },
      {
        // 正则匹配文件名
        test: /\.less$/,
        // 使用的loader处理文件,执行顺序是从下到上
        use: [
          // 创建style标签,插入到head中
          // 'style-loader',
          // 如果使用了mini-css-extract-plugin插件,就不需要创建style标签插入head中了
          MiniCssExtractPlugin.loader,
          // 加载css相关文件,转换成能识别的js文件
          'css-loader',
          // 配置预加载样式postcss
          {
            loader: "postcss-loader",
            options: {
              postcssOptions: {
                plugins: [
                  [
                    "postcss-preset-env"
                  ]
                ]
              }
            }
          },
          // 使用less-loader将less文件转换成css文件
          'less-loader'
        ]
      },
      {
        // 正则匹配文件名
        test: /\.(png|svg|jpg|jpeg|gif)$/i,
        // webpack5
        type: 'asset'
      },
      // 处理html中的图片,让后续的loader进行解析
      {
        test: /\.html$/i,
        loader: 'html-loader'
      },
      // 处理字体文件
      {
        test: /\.(woff|woff2|eot|ttf|otf)$/i,
        type: 'asset/resource'
      }
    ]
  },
  // plugins插件相关配置
  plugins: [
    new HtmlWebpackPlugin({
      // html模板文件的位置,打包完成后会在dist文件夹下生成index.html文件,并且会默认的引入bundle.js
      template: './src/index.html'
    }),
    // 提取css为单独的文件
    new MiniCssExtractPlugin({
      filename: "[name].css"
    })
  ],
  optimization: {
    // 开发环境下启用css优化
    minimize: true,
    minimizer: [
      // 使用cssnano优化和压缩css
      new CssMinimizerPlugin()
    ]
  },
  // mode模式
  mode: 'development'
  // mode: 'production'
}
4.5.js语法检查Eslint
  • 可以通过配置文件中的rules规则,去检查代码,现阶段eslint配置文件的写法有多种,可以时.eslintrc、.eslintrc.js、.eslintrc.json、也可以在package.json中写eslintConfig配置实现
  • 这里以.eslintrc.js为例
module.exports = {
  // 继承Eslint官方的配置
  extends: ["eslint:recommended"],
  env: {
    node: true, //启用node全局变量
    browser: true,//启用浏览器中全局变量
  },
  parserOptions: {
    ecmaVersion: 6, //es6
    sourceType: "module" //es module
  },
  rules: {
    "no-var": 2, //不能使用var声明变量
  }
}
  • webpack相关配置(这里以webpack5为例)
// 引入node的路径path模块
const path = require("path")
// 引入插件
const HtmlWebpackPlugin = require('html-webpack-plugin')
const MiniCssExtractPlugin = require('mini-css-extract-plugin')
const CssMinimizerPlugin = require('css-minimizer-webpack-plugin')
const ESlintPlugin = require('eslint-webpack-plugin')
module.exports = {
  // devServer
  // webpack5
  devServer: {
    // 启动后自动打开浏览器
    open: true,
    // 监听端口号
    port: 8080
  },
  // entry入口文件地址
  entry: "./src/index.js",
  // output输出文件
  output: {
    filename: "bundle.js",
    path: path.resolve(__dirname, 'dist'),
    // 自定义静态资源文件名
    assetModuleFilename: "images/[hash:10][ext][query]",
    // 在生成文件之前清空output目录
    clean: true
  },
  // loader相关配置
  module: {
    rules: [
      {
        // 正则匹配文件名
        test: /\.css$/,
        // 使用的loader处理文件,执行顺序是从下到上
        use: [
          // 创建style标签,插入到head中
          // 'style-loader',
          // 如果使用了mini-css-extract-plugin插件,就不需要创建style标签插入head中了
          MiniCssExtractPlugin.loader,
          // 加载css相关文件,转换成能识别的js文件
          'css-loader',
          // 配置预加载样式postcss
          {
            loader: "postcss-loader",
            options: {
              postcssOptions: {
                plugins: [
                  [
                    "postcss-preset-env"
                  ]
                ]
              }
            }
          },
        ]
      },
      {
        // 正则匹配文件名
        test: /\.less$/,
        // 使用的loader处理文件,执行顺序是从下到上
        use: [
          // 创建style标签,插入到head中
          // 'style-loader',
          // 如果使用了mini-css-extract-plugin插件,就不需要创建style标签插入head中了
          MiniCssExtractPlugin.loader,
          // 加载css相关文件,转换成能识别的js文件
          'css-loader',
          // 配置预加载样式postcss
          {
            loader: "postcss-loader",
            options: {
              postcssOptions: {
                plugins: [
                  [
                    "postcss-preset-env"
                  ]
                ]
              }
            }
          },
          // 使用less-loader将less文件转换成css文件
          'less-loader'
        ]
      },
      {
        // 正则匹配文件名
        test: /\.(png|svg|jpg|jpeg|gif)$/i,
        // webpack5
        type: 'asset'
      },
      // 处理html中的图片,让后续的loader进行解析
      {
        test: /\.html$/i,
        loader: 'html-loader'
      },
      // 处理字体文件
      {
        test: /\.(woff|woff2|eot|ttf|otf)$/i,
        type: 'asset/resource'
      },
    ]
  },
  // plugins插件相关配置
  plugins: [
    new HtmlWebpackPlugin({
      // html模板文件的位置,打包完成后会在dist文件夹下生成index.html文件,并且会默认的引入bundle.js
      template: './src/index.html'
    }),
    // 提取css为单独的文件
    new MiniCssExtractPlugin({
      filename: "[name].css"
    }),
    // 在webpack5中配置eslint不需要配置loader了,只需要配置plugin即可
    new ESlintPlugin({
      // 使用eslint对代码进行检查,只需要检查src下面的文件
      context:path.resolve(__dirname,'src')
    })
  ],
  optimization: {
    // 开发环境下启用css优化
    minimize: true,
    minimizer: [
      // 使用cssnano优化和压缩css
      new CssMinimizerPlugin()
    ]
  },
  // mode模式
  mode: 'development'
  // mode: 'production'
}
4.6.js的兼容性处理
  • 处理方案有三种
    • 1、@babel/preset-env基于js兼容性处理,问题是只能转换基本的js代码,不能转换高级的Promise语法
    • 2、@babel/polyfil兼容全部的js,问题是将所有兼容的代码全部引入,体积太大
    • 3、core-js按需加载,只加载需要处理的兼容性语法
  • 方案一
安装依赖
npm i babel-loader @babel/core @babel/preset-env -D
webpack相关配置
// js兼容性处理
      {
        test:/\.m?js$/,
        exclude:/node_modules/,
        loader:'babel-loader',
        options:{
          // 基本的兼容性处理
          preset:['@babel/preset-env']
        }
      }
  • 方案二
安装依赖
npm i @babel/polyfill -S
这里不需要再webpack配置,只需要在main.js中引入即可
import '@babel/polyfill'
  • 方案三
安装依赖
npm i core-js -D
webpack配置
// js兼容性处理
      {
        test: /\.m?js$/,
        exclude: /node_modules/,
        loader: 'babel-loader',
        options: {
          // 基本的兼容性处理
          presets: [['@babel/preset-env',
            {
              // 按需加载
              useBuiltIns: 'usage',
              // 指定core版本
              corejs: {
                version: 3
              },
              // 指定兼容性到哪个浏览器版本
              targets: {
                chrome: '60',
                firefox: '60',
                ie: '9',
                safari: '10',
                edge: '17'
              }
            }
          ]]
        }
      }
4.7.压缩html和js
  • 当mode模式设置为production后,默认会开启html和js的压缩,我们这里可以使用terser优化html和js的压缩
安装依赖
npm i terser-webpack-plugin --save-dev
webpack依赖
const TerserPlugin=require('terser-webpack-plugin')
 optimization: {
    // 开发环境下启用css优化
    minimize: true,
    minimizer: [
      // 使用cssnano优化和压缩css
      new CssMinimizerPlugin(),
      // 使用terser优化压缩
      new TerserPlu**加粗样式**gin()
    ]
  },

5.Webpack性能优化配置

  • 开发环境性能优化
  • 优化代码构建速度
  • 优化代码调试
  • 生产环境性能优化
  • 优化打包构建速度
  • 优化代码运行的性能
5.1.HMR模块热更新:当一个模块发生变化时,只会重新打包这一个模块的代码,不是打包所有的代码,会提高构建速度
  • 样式文件:可以使用HMR功能,style-loader内部实现
  • js文件,默认没有HMR热更新
  • html文件,默认没有HMR热更新
webpack配置
 devServer: {
    // 启动后自动打开浏览器
    open: true,
    // 监听端口号
    port: 8080,
    // 开启HMR功能,修改配置之后需要重启webpack
    hot:true
  },
5.2.sorce map源码映射:一种提供源代码到构建后代码映射技术,一旦构建代码出错,可以通过映射关系找到源代码出错的位置
webpack相关配置
module.exports = {
  // devServer
  // webpack5
  devServer: {
    // 启动后自动打开浏览器
    open: true,
    // 监听端口号
    port: 8080,
    // 开启HMR功能,修改配置之后需要重启webpack
    hot: true
  },
  // 可选值[inline-|hidden-|eval-][nosources-][cheap-[module-]]source-map
  devtool: 'source-map',
}
说明错误提示
source-map外部错误代码的准确信息,源代码的错误位置
inline-source-map内联,只生成一个内联source-map错误代码的准确信息,源代码的错误位置
hidden-source-map外部错误代码的原因,没有源代码错误位置,只有构建后的代码位置
eval-source-map内联每个文件都生成对应的source-map,都在eval里错误代码的准确信息,源代码的错误位置
nosource-source-map外部有错误代码准确信息,没有源代码位置
cheap-source-map外部有错误代码准确信息,有源代码信息,只能精确到行
cheap-module-source-map外部有错误代码准确信息,源代码的错误位置
  • 内联和外部
    • 内联:构建速度快
    • 外部:生成单独的文件,内联没有

范德萨发
开发环境:速度快,调试更友好

速度快:
eval>inline>cheap>eval-cheap-source-map>eval-source-map
调试更友好:
source-map

生产环境:内联会让代码体积变大,所以生产环境不适用内联

nosource-source-map 全部隐藏
hidden-source-map 只会隐藏源代码,会提示构建后代码错误
5.3.babel-loader缓存:第二次打包构建速度更快
webpack配置
// js兼容性处理
      {
        test: /\.m?js$/,
        exclude: /node_modules/,
        loader: 'babel-loader',
        options: {
          // 基本的兼容性处理
          presets: [['@babel/preset-env',
            {
              // 按需加载
              useBuiltIns: 'usage',
              // 指定core版本
              corejs: {
                version: 3
              },
              // 指定兼容性到哪个浏览器版本
              targets: {
                chrome: '60',
                firefox: '60',
                ie: '9',
                safari: '10',
                edge: '17'
              }
            }
          ]],
          // 开启编译缓存
          cacheDirectory: true
        }
      }
5.4.文件资源缓存
  • hash:每次webpack构建打包,都会生成唯一的hash,如果只有一个文件发生变化,也会重新打包生成新的hash,这样会导致资源的浪费
  • chunkhash:根据chunk生成hash值,入股哦打包来源于同一个chunk,那么hash值就是一样的
  • contenthash:根据文件的内容生成hash,如果内容发生变化会重新生成新的hash值
5.5.tree shaking树摇
  • 去除无用代码,减少代码体积,webpack5中已默认支持tree shaking,但是需要使用es6模块化,必须开启production,
  • 简单来说有三种:
  • usedExports:会删除没有使用过的一些导入
  • sideEffects:删除模块中导出了,但是未被使用的变量
  • dead code elimination:删除死代码
5.6.code split代码分割
  • 使用多入口文件
// entry多入口文件
  entry:{
    main:'./main.js',
    index:'./index.js'
  },
  • 公共代码防止重复打包
//自动分析多入口chunk中,如果有公共的代码,会打包成单独的一个chunk
 optimization: {
    splitChunks:{
      chunks:'all', //对所有模块都进行分割
    }
  },
  • 动态导入,按需加载
document.getElementById('app').onclick=function(){
  import ('./index.js').then(res=>{
    // 加载成功
  }).catch(err=>{
    // 加载失败
  })
}
5.7.多进程打包
// 安装依赖
npm i thread-loader -D
webpack配置
{
  test: /\.m?js$/,
  exclude: /node_modules/,
  use:[
    {
      loader:'thread-loader', //开启多线程打包
    },
    {
      loader: 'babel-loader',
      options: {
        // 基本的兼容性处理
        presets: [['@babel/preset-env',
          {
            // 按需加载
            useBuiltIns: 'usage',
            // 指定core版本
            corejs: {
              version: 3
            },
            // 指定兼容性到哪个浏览器版本
            targets: {
              chrome: '60',
              firefox: '60',
              ie: '9',
              safari: '10',
              edge: '17'
            }
          }
        ]],
        // 开启编译缓存
        cacheDirectory: true
      }
    }
  ] 
}

6.Webpack性能优化总结

  • 开发环境性能优化:1、优化打包速度,可以通过HMR热更新实现。2、优化代码调试,使用source-map
  • 生产环境性能优化:1、优化打包速度:使用babel缓存和多进程打包。2、优化代码运行的性能:使用缓存、tree shaking、code split代码分割、多入口打包,chunk拆分和动态引入,按需加载
  • 12
    点赞
  • 26
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值