1. 介绍

image.png
webpack is a module bundler (模块打包⼯具)

webpack 是⼀个打包模块化 JavaScript 的⼯具,它会从⼊⼝模块出发,识别出源码中的模块化导⼊语句,递归地找出⼊⼝⽂件的所有依赖,将⼊⼝和其所有的依赖打包到⼀个单独的⽂件中,是⼯程化、⾃动化思想在前端开发中的体现。

2. 安装

  • 全局(不推荐) ```javascript

    安装webpack V4+版本时,需要额外安装webpack-cli

    npm install webpack webpack-cli -g

检查版本

webpack -v

卸载

npm uninstall webpack webpack-cli -g

webpack -v // 默认在全局环境中查找

  1. - **局部**
  2. ```javascript
  3. # 安装最新的稳定版本
  4. npm i -D webpack
  5. # 安装指定版本
  6. # npm i -D webpack@<version>
  7. # 安装最新的体验版本 可能包含bug,不要⽤于⽣产环境
  8. # npm i -D webpack@beta
  9. # 安装webpack V4+版本时,需要额外安装webpack-cli
  10. npm i -D webpack-cli
  11. npx webpack -v// npx帮助我们在项⽬中的node_modules⾥查找webpack

3. 默认配置

  • webpack 默认⽀持 JS 模块和 JSON 模块
  • ⽀持CommonJS/ES moudule/AMD等模块类型
  • webpack4⽀持零配置使⽤,但是很弱,稍微复杂些的场景都需要额外扩展

3.2 默认配置

  1. const path = require("path");
  2. module.exports = {
  3. // 必填 webpack执⾏构建⼊⼝
  4. entry: "./src/index.js",
  5. output: {
  6. // 将所有依赖的模块合并输出到main.js
  7. filename: "main.js",
  8. // 输出⽂件的存放路径,必须是绝对路径
  9. path: path.resolve(__dirname, "./dist")
  10. }
  11. };

3.1 例子

  1. 1.新建src/index.jssrc/index.jsonsrc/other.js
  2. ### index.js
  3. const json = require("./index.json");//commonJS
  4. import { add } from "./other.js";//es module
  5. console.log(json, add(2, 3));
  6. ### index.json
  7. {
  8. "name": "JOSN"
  9. }
  10. ### other.js
  11. export function add(n1, n2) {
  12. return n1 + n2;
  13. }
  14. 2.npx webpack 执行构建
  15. 3.构建成功
  16. 多出⼀个 dist ⽬录,⾥⾯有个 main.js ,这个⽂件是⼀个可执⾏的JavaScript⽂件,
  17. ⾥⾯包含webpackBootstrap启动函数

4.配置核心概念

零配置是很弱的,特定的需求需要⾃⼰进⾏配置
webpack 有默认的配置⽂件,叫 webpack.config.js

  • 使⽤默认的配置⽂件:webpack.config.js
  • 不使⽤⾃定义配置⽂件: ⽐如wpconfig.js,可以通过--config wpkconfig.js来指定 webpack 使⽤哪个配置⽂件来执⾏构建。

webpack.config.js配置基础结构

  1. module.exports = {
  2. entry: "./src/index.js", //打包⼊⼝⽂件
  3. output: "./dist", //输出结构
  4. mode: "production", //打包环境
  5. module: {
  6. rules: [
  7. //loader模块处理
  8. {
  9. test: /\.css$/,
  10. use: "style-loader"
  11. }
  12. ]
  13. },
  14. plugins: [new HtmlWebpackPlugin()] //插件配置
  15. };

4.1 entry

指定webpack打包⼊⼝⽂件:Webpack 执⾏构建的第⼀步将从 Entry 开始,可抽象成输⼊

  1. //单⼊⼝ SPA,本质是个字符串
  2. entry: {
  3. main: "./src/index.js",
  4. },
  5. // 相当于简写=
  6. entry: "./src/index.js",
  7. //多⼊⼝ entry是个对象
  8. entry: {
  9. index: "./src/index.js",
  10. login: "./src/login.js",
  11. },

4.2 output

打包转换后的⽂件输出到磁盘位置:输出结果,在 Webpack 经过⼀系列处理并得出最终想要的代码后输出结果。

  1. //单⼊⼝ SPA,本质是个字符串
  2. output: {
  3. filename: "bundle.js", //输出⽂件的名称
  4. path: path.resolve(__dirname, "dist"),//输出⽂件到磁盘的⽬录,必须是绝对路径
  5. },
  6. //多⼊⼝的处理
  7. output: {
  8. filename: "[name][chunkhash:8].js", //利⽤占位符,⽂件名称不重复
  9. path: path.resolve(__dirname, "dist"),
  10. },

4.3 mode

设置mode可以⾃动触发webpack内置的函数,达到优化的效果
webpack 入门 - 图2

  • 开发阶段的开启会有利于热更新的处理,识别哪个模块变化
  • ⽣产阶段的开启会有帮助模块压缩,处理副作⽤等⼀些功能

4.4 module

  • 模块,在 Webpack ⾥⼀切皆模块,⼀个模块对应着⼀个⽂件。webpack 会从配置的 Entry开始递归找出所有依赖的模块。
  • 当 webpack 处理到不认识的模块时,需要在webpack中的module处进⾏配置,当检测到是什么格式的模块,使⽤什么loader来处理。

    1. module:{
    2. rules:[
    3. {
    4. test:/\.xxx$/,//指定匹配规则
    5. use:{
    6. loader: 'xxx-load'//指定使⽤的loader
    7. }
    8. }
    9. ]
    10. }

    4.5 loader

  • webpack 默认只⽀持 jsonjs模块 不⽀持不认识其他格式的模块。

  • webpack是模块打包⼯具,⽽模块不仅仅是js,还可以是css,图⽚或者其他格式,其他格式的模块处理,和处理⽅式就需要 loader 了

常见的loader:

  1. style-loader
  2. css-loader
  3. less-loader
  4. sass-loader
  5. ts-loader //将Ts转换成js
  6. babel-loader//转换ES6、7等js新特性语法
  7. file-loader//处理图⽚⼦图
  8. eslint-loader
  9. ...

4.6 plugin

  • plugin 可以在 webpack 运⾏到某个阶段的时候,帮你做⼀些事情,类似于⽣命周期的概念
  • 扩展插件,在 webpack 构建流程中的特定时机注⼊扩展逻辑来改变构建结果或做你想要的事情。
  • 作⽤于整个构建过程

常用的plugin:

  1. html-webpack-plugin
  2. clean-webpack-plugin
  3. mini-css-extract-plugin

4.7 sourceMap

  • 为了开发时,快速的定位问题
  • 线上代码,我们有时候也会开启 前端错误监控,快速的定位问题

源代码与打包后的代码的映射关系,通过sourceMap定位到源代码。

  1. //在dev模式中,默认开启,关闭的话 可以在配置⽂件⾥
  2. devtool:"none"
  • eval:速度最快,使⽤eval包裹模块代码,
  • source-map: 产⽣ .map ⽂件外部产⽣错误代码的准确信息和位置
  • cheap: 较快,不包含列信息
  • module:第三⽅模块,包含loader的sourcemap(⽐如jsx to js ,babel的sourcemap)
  • inline: 将 .map 作为DataURI嵌⼊,不单独⽣成 .map ⽂件

image.png

  1. 配置推荐:
  2. devtool:"cheap-module-eval-source-map",// 开发环境配置
  3. // 线上不推荐开启
  4. devtool:"cheap-module-source-map", // 线上⽣成配置

5. module/chunk/bundle关系

webpack 生态系统中的常用术语

webpack 中那些最易混淆的 5 个知识点

webpack 入门 - 图4

  • module 模块,在 Webpack 里一切皆模块,一个模块对应着一个文件。Webpack 会从配置的 Entry 开始递归找出所有依赖的模块。
  • chunk 代码块,一个 chunk 由多个模块组合而成,用于代码合并与分割。
  • bundle 输出束
    • 一个 chunk 可以对应一个或多个module
    • 一个 bundle 对应一个 chunk

6.核心工作原理

Webpack 打包的核心工作过程:

通过 Loader 处理特殊类型资源的加载,例如加载样式、图片; 通过 Plugin 实现各种自动化的构建任务,例如自动压缩、自动发布。

  1. webpack 启动后,会根据我们的配置,找到项目中的某个指定文件(一般这个文件都会是一个 JS 文件)作为入口。然后顺着入口文件中的代码,根据代码中出现的 import(ES Modules)或者是 require(CommonJS)之类的语句,解析推断出来这个文件所依赖的资源模块,然后再分别去解析每个资源模块的依赖,周而复始,最后形成整个项目中所有用到的文件之间的依赖关系树。

image.png

对于依赖模块中无法通过 JavaScript 代码表示的资源模块,例如图片或字体文件,一般的 Loader 会将它们单独作为资源文件拷贝到输出目录中,然后将这个资源文件所对应的访问路径作为这个模块的导出成员暴露给外部。

至于自定义插件机制它并不会影响 Webpack 的核心工作过程,只是 Webpack 为了提供一个强大的扩展能力,它为整个工作过程的每个环节都预制了一个钩子,也就是说我们可以通过插件往 Webpack 工作过程的任意环节植入一些自定义的任务,从而扩展 Webpack 打包功能以外的能力。

整体流程:

  1. Webpack CLI 启动打包流程;载入 Webpack 核心模块,创建 Compiler 对象;
  2. 使用 Compiler 对象开始编译整个项目;
  3. 从入口文件开始,解析模块依赖,形成依赖关系树;
  4. 递归依赖树,将每个模块交给对应的 Loader 处理;
  5. 合并 Loader 处理完的结果,将打包结果输出到 dist 目录。

    https://kaiwu.lagou.com/course/courseInfo.htm?courseId=88#/detail/pc?id=2265

多页面打包通用方案

动态获取 entry 和设置 html-webpack-plugin 数量
利⽤ glob.sync :entry: glob.sync(path.join(__dirname, './src/*/index.js')),

https://www.npmjs.com/package/glob

  1. module.exports = {
  2. entry: {
  3. index: './src/index/index.js',
  4. search: './src/search/index.js
  5. }
  6. };