likes
comments
collection
share

webpack详细笔记(收藏版)

作者站长头像
站长
· 阅读数 15

💂 个人网站:【紫陌】【笔记分享网站,进群就有】 💅 想寻找共同学习交流、共同成长的伙伴,【前端学习交流群】

1.webpack 是什么

  • webpack 是一个静态的模块化打包工具,为现代的 JavaScript 应用程序;
  • 上面的解释进行拆解:
    • 打包 bundler:webpack 可以将帮助我们进行打包,所以它是一个打包工具 
    • 静态的 static:这样表述的原因是我们最终可以将代码打包成最终的静态资源(部署到静态服务器);
    • 模块化 module:webpack 默认支持各种模块化开发,ES Module、CommonJS、AMD 等;
    • 现代的 modern:我们前端说过,正是因为现代前端开发面临各种各样的问题,才催生了 webpack 的出现和发展;

2.Webpack 的安装

  • webpack 的安装目前分为两个:webpack、webpack-cli
  • 它们是什么关系呢?
    • 执行 webpack 命令,会执行 node_modules 下的.bin 目录下的 webpack;
    • webpack 在执行时是依赖 webpack-cli 的,如果没有安装就会报错;
    • 而 webpack-cli 中代码执行时,才是真正利用 webpack 进行编译和打包的过程;
    • 所以在安装 webpack 时,我们需要同时安装 webpack-cli(第三方的脚手架事实上是没有使用 webpack-cli 的,而是类似于自 己的 vue-service-cli 的东西)

npm install webpack webpack-cli –g # 全局安装

npm install webpack webpack-cli –D # 局部安装

3.Webpack 的默认打包

  • 我们可以通过 webpack 进行打包,之后运行打包之后的代码

    • 在目录下直接执行 webpack 命令

      webpack

  • 生成一个 dist 文件夹,里面存放一个 main.js 的文件,就是我们打包之后的文件:

    • 这个文件中的代码被压缩和丑化了;
    • 另外我们发现代码中依然存在 ES6 的语法,比如箭头函数、const 等,这是因为默认情况下 webpack 并不清楚我们打包后的文 件是否需要转成 ES5 之前的语法,后续我们需要通过 babel 来进行转换和设置;
  • 我们发现是可以正常进行打包的,但是有一个问题,webpack 是如何确定我们的入口的呢?

  • 事实上,当我们运行 webpack 时,webpack 会查找当前目录下的 src/index.js 作为入口;

    • 所以,如果当前项目中没有存在 src/index.js 文件,那么会报错;

    • 当然,我们也可以通过配置来指定入口和出口

      npx webpack --entry ./src/main.js --output-path ./build

4.创建局部的 webpack

  • 前面我们直接执行 webpack 命令使用的是全局的 webpack,如果希望使用局部的可以按照下面的步骤来操作。

  • 第一步:创建 package.json 文件,用于管理项目的信息、库依赖等

    npm init

  • 第二步:安装局部的 webpack

    npm install webpack webpack-cli -D

  • 第三步:使用局部的 webpack

    npx webpack

  • 第四步:在 package.json 中创建 scripts 脚本,执行脚本打包即可 webpack详细笔记(收藏版)

    npm run build

5.Webpack 配置文件

  • 在通常情况下,webpack 需要打包的项目是非常复杂的,并且我们需要一系列的配置来满足要求,默认配置必然是不可以的。
  • 我们可以在根目录下创建一个 webpack.config.js 文件,来作为 webpack 的配置文件:

webpack详细笔记(收藏版)

继续执行 webpack 命令,依然可以正常打包

npm run build

6.指定配置文件

  • 如果我们的配置文件并不是 webpack.config.js 的名字,而是其他的名字呢?

    • 比如我们将 webpack.config.js 修改成了 wk.config.js;

    • 这个时候我们可以通过 --config 来指定对应的配置文件;

      webpack --config wk.config.js

  • 但是每次这样执行命令来对源码进行编译,会非常繁琐,所以我们可以在 package.json 中增加一个新的脚本:

webpack详细笔记(收藏版)

之后我们执行 npm run build 来打包即可。

7.Webpack 的依赖图

  • webpack 到底是如何对我们的项目进行打包的呢?
    • 事实上 webpack 在处理应用程序时,它会根据命令或者配置文件找到入口文件;
    • 从入口开始,会生成一个 依赖关系图,这个依赖关系图会包含应用程序中所需的所有模块(比如.js 文件、css 文件、图片、字 等);
    • 然后遍历图结构,打包一个个模块(根据文件的不同使用不同的 loader 来解析);

webpack详细笔记(收藏版)

8.使用 loader

1.css-loader 的使用

webpack详细笔记(收藏版)

  • 上面的错误信息告诉我们需要一个 loader 来加载这个 css 文件,但是 loader 是什么呢?

    • loader 可以用于对模块的源代码进行转换
    • 我们可以将 css 文件也看成是一个模块,我们是通过 import 来加载这个模块的;
    • 在加载这个模块时,webpack 其实并不知道如何对其进行加载,我们必须制定对应的 loader 来完成这个功能;
  • 那么我们需要一个什么样的 loader 呢?

    • 对于加载 css 文件来说,我们需要一个可以读取 css 文件的 loader;
    • 这个 loader 最常用的是 css-loader;
  • css-loader 的安装:

    npm install css-loader -D

2.loader 配置方式

  • 配置方式表示的意思是在我们的 webpack.config.js 文件中写明配置信息:
  • module.rules 中允许我们配置多个 loader(因为我们也会继续使用其他的 loader,来完成其他文件的加载)
  • 这种方式可以更好的表示 loader 的配置,也方便后期的维护,同时也让你对各个 Loader 有一个全局的概览;
  • module.rules 的配置如下:
  • rules 属性对应的值是一个数组:[Rule]
  • 数组中存放的是一个个的 Rule,Rule 是一个对象,对象中可以设置多个属性:
    • test 属性:用于对 resource(资源)进行匹配的,通常会设置成正则表达式;
    • use 属性:对应的值时一个数组:[UseEntry]
    • UseEntry 是一个对象,可以通过对象的属性来设置一些其他属性
    • **loader:**必须有一个 loader 属性,对应的值是一个字符串;
    • options:可选的属性,值是一个字符串或者对象,值会被传入到 loader 中;
    • **query:**目前已经使用 options 来替代;
    • 传递字符串(如:use: [ 'style-loader' ])是 loader 属性的简写方式(如:use: [ { loader: 'style-loader'} ])
  • loader 属性: Rule.use: [ { loader } ] 的简写。

3.Loader 的配置代码

webpack详细笔记(收藏版)

4.认识 style-loader

  • 我们已经可以通过 css-loader 来加载 css 文件了

    • 但是你会发现这个 css 在我们的代码中并没有生效(页面没有效果)。
  • 这是为什么呢?

    • 因为 css-loader 只是负责将.css 文件进行解析,并不会将解析之后的 css 插入到页面中;
    • 如果我们希望再完成插入 style 的操作,那么我们还需要另外一个 loader,就是 style-loader;
  • 安装 style-loader:

    npm install style-loader -D

5.配置 style-loader

  • 那么我们应该如何使用 style-loader:

    • 在配置文件中,添加 style-loader;

    • 注意:因为 loader 的执行顺序是从右向左(或者说从下到上,或者说从后到前的),所以我们需要将 style-loader 写到 cssloader 的前面;

webpack详细笔记(收藏版)

重新执行编译 npm run build,可以发现打包后的 css 已经生效了

6.less-loader 处理 less 文件

  • 在我们开发中,我们可能会使用less、sass、stylus 的预处理器来编写 css 样式,效率会更高。

  • 那么,如何可以让我们的环境支持这些预处理器呢?

    • 首先我们需要确定,less、sass 等编写的 css 需要通过工具转换成普通的 css;
  • 但是在项目中我们会编写大量的 css,它们如何可以自动转换呢?

  • 这个时候我们就可以使用 less-loader,来自动使用 less 工具转换 less 到 css;

    npm install less-loader -D

配置 webpack.config.js

webpack详细笔记(收藏版)

执行 npm run build less 就可以自动转换成 css,并且页面也会生效了

9.认识 PostCSS 工具

  • 什么是 PostCSS 呢?
    • PostCSS 是一个通过 JavaScript 来转换样式的工具;
    • 这个工具可以帮助我们进行一些 CSS 的转换和适配,比如自动添加浏览器前缀、css 样式的重置;
    • 但是实现这些功能,我们需要借助于 PostCSS 对应的插件;
  • 如何使用 PostCSS 呢?主要就是两个步骤:
  • 第一步:查找 PostCSS 在构建工具中的扩展,比如 webpack 中的 postcss-loader;
  • 第二步:选择可以添加你需要的 PostCSS 相关的插件;

1.postcss-loader

  • 我们可以借助于构建工具:

    • 在 webpack 中使用 postcss 就是使用 postcss-loader 来处理的;
  • 我们来安装 postcss-loader:

    npm install postcss-loader -D

  • 我们修改加载 css 的 loader:(配置文件已经过多,给出一部分了)

    注意:因为 postcss 需要有对应的插件才会起效果,所以我们需要配置它的 plugin;

webpack详细笔记(收藏版) webpack详细笔记(收藏版)

2.单独的 postcss 配置文件

因为我们需要添加前缀,所以要安装autoprefixer

npm install autoprefixer -D

  • 我们可以将这些配置信息放到一个单独的文件中进行管理:
  • 在根目录下创建 postcss.config.js

webpack详细笔记(收藏版)

3.postcss-preset-env

  • 事实上,在配置 postcss-loader 时,我们配置插件并不需要使用 autoprefixer。

  • 我们可以使用另外一个插件:postcss-preset-env

  • postcss-preset-env 也是一个 postcss 的插件;

  • 它可以帮助我们将一些现代的 CSS 特性,转成大多数浏览器认识的 CSS,并且会根据目标浏览器或者运行时环境添加所需的 polyfill;

  • 也包括会自动帮助我们添加 autoprefixer(所以相当于已经内置了 autoprefixer);

  • 首先,我们需要安装 postcss-preset-env:

    npm install postcss-preset-env -D

  • 之后,我们直接修改掉之前的 autoprefixer 即可:

webpack详细笔记(收藏版)

  • 注意:我们在使用某些 postcss 插件时,也可以直接传入字符串(可以不用 require 直接写字符串)

webpack详细笔记(收藏版)

10.webpack 处理图片

  • 当前使用的 webpack 版本是 webpack5:
    • 在 webpack5 之前,加载这些资源我们需要使用一些 loader,比如 raw-loader 、url-loader、file-loader
    • 在 webpack5 开始,我们可以直接使用资源模块类型(asset module type),来替代上面的这些 loader;
  • 资源模块类型(asset module type),通过添加 4 种新的模块类型,来替换所有这些 loader:
    • asset/resource 发送一个单独的文件并导出 URL。
    • 之前通过使用 file-loader 实现;
    • asset/inline 导出一个资源的 data URI。
      • 之前通过使用 url-loader 实现;
    • asset/source 导出资源的源代码 (少用)
    • 之前通过使用 raw-loader 实现;
    • asset 在导出一个 data URI 和发送一个单独的文件之间自动选择。
      • 之前通过使用 url-loader,并且配置资源体积限制实现;

1 .asset module type 的使用

webpack详细笔记(收藏版)

  • 自定义文件的输出路径和文件名

    • 方式一:修改 output,添加 assetModuleFilename 属性; (不推荐)

    webpack详细笔记(收藏版)

    • 方式二:在 Rule 中,添加一个 generator 属性,并且设置 filename;(推荐)webpack详细笔记(收藏版)

介绍几个最常用的占位符

  • [ext]: 处理文件的扩展名;
  • [name]:处理文件的名称;
  • [hash]:文件的内容,使用 MD4 的散列函数处理,生成的一个 128 位的 hash 值(32 个十六进制)

webpack详细笔记(收藏版)

开发中如何使用:

  • 开发中我们往往是小的图片需要转换,但是大的图片直接使用图片即可
    • 这是因为小的图片转换 base64之后可以和页面一起被请求,减少不必要的请求过程;
    • 大的图片也进行转换反而会影响页面的请求速度;
  • 我们需要两个步骤来实现:
  • 步骤一:将 type 修改为 asset;
  • 步骤二:添加一个parser 属性,并且制定 dataUrl 的条件,添加 maxSize 属性;

webpack详细笔记(收藏版)

11.babel 处理 js

  • Babel 到底是什么呢?
    • Babel 是一个工具链,主要用于旧浏览器或者环境中将 ECMAScript 2015+代码转换为向后兼容版本的 JavaScript;
    • 包括:语法转换、源代码转换等;

webpack详细笔记(收藏版)

babel-loader

  • 在实际开发中,我们通常会在构建工具中通过配置 babel 来对其进行使用的,比如在 webpack 中。

    • 那么我们就需要去安装相关的依赖:

      npm install babel-loader -D

    • 需要转换箭头函数,那么我们就可以使用箭头函数转换相关的插件:

      npm install @babel/plugin-transform-arrow-functions -D

    • 需要 const,let 转 var 使用 plugin-transform-block-scoping 来完成这样的功能

      npm install @babel/plugin-transform-block-scoping -D

  • 我们可以设置一个规则,在加载 js 文件时,使用我们的 babel:

webpack详细笔记(收藏版)

babel-preset(预设)

如果我们一个个去安装使用插件,那么需要手动来管理大量的 babel 插件,我们可以直接给 webpack 提供一个 preset,webpack 会根据我们的预设来加载对应的插件列表,并且将其传递给 babel。

  • 比如常见的预设有三个:
    • env
    • react
    • TypeScript
  • 安装 preset-env:

npm install @babel/preset-env

webpack详细笔记(收藏版)

12.webpack 处理 vue 文件

需要使用 vue-loader:

npm install vue-loader -D

在 webpack 的模板规则中进行配置

webpack详细笔记(收藏版)

另外我们需要配置对应的 Vue 插件 webpack详细笔记(收藏版)

重新打包即可支持 App.vue 的写法。

如果打包依然会报错,这是因为我们必须添加@vue/compiler-sfc 来对 template 进行解析:(这个一般下载 vue 会自带有的)

npm install @vue/compiler-sfc -D

13.resolve 模块解析

webpack 使用 enhanced-resolve 来解析文件路径;

webpack 能解析三种文件路径

  • 绝对路径
    • 由于已经获得文件的绝对路径,因此不需要再做进一步解析。
  • 相对路径
    • 在这种情况下,使用 import 或 require 的资源文件所处的目录,被认为是上下文目录;
    • 在 import/require 中给定的相对路径,会拼接此上下文路径,来生成模块的绝对路径;
  • 模块路径
    • 在 resolve.modules 中指定的所有目录检索模块;
    • 默认值是 ['node_modules'],所以默认会从 node_modules 中查找文件;
    • 我们可以通过设置别名的方式来替换初识模块路径,后面讲解 alias 的配置;

extensions 和 alias 配置

  • extensions 是解析到文件时自动添加扩展名:

    • 默认值是 ['.wasm', '.mjs', '.js', '.json']
    • 所以如果我们代码中想要添加加载 .vue 或者 jsx 或者 ts 等文件时,我们必须自己写上扩展名;否则打包失败
  • 另一个非常好用的功能是配置别名 alias:

    • 特别是当我们项目的目录结构比较深的时候,或者一个文件的路径可能需要 ../../../这种路径片段;
    • 我们可以给某些常见的路径起一个别名;

webpack详细笔记(收藏版)

14.认识 Plugin

  • Loader 是用于特定的模块类型进行转换;
  • Plugin 可以用于执行更加广泛的任务,比如打包优化、资源管理、环境变量注入等;

1.CleanWebpackPlugin 插件

  • 每次修改了一些配置,重新打包时,都需要手动删除 dist 文件夹:

    • 我们可以借助于一个插件来帮助我们完成,这个插件就是CleanWebpackPlugin;
  • 首先,我们先安装这个插件:

    npm install clean-webpack-plugin -D

  • 之后在插件中配置

webpack详细笔记(收藏版)

也可不下载插件,在 output 下配置 clean:true

webpack详细笔记(收藏版)

2.HtmlWebpackPlugin 插件

  • 我们的 HTML 文件是编写在根目录下的,而最终打包的 dist 文件夹中是没有 index.html 文件的。
  • 在进行项目部署的时,必然也是需要有对应的入口文件 index.html;
  • 所以我们也需要对 index.html 进行打包处理;

对 HTML 进行打包处理我们可以使用另外一个插件:HtmlWebpackPlugin;

npm install html-webpack-plugin -D

webpack详细笔记(收藏版)

自定义 HTML 模板

  • 如果我们想在自己的模块中加入一些比较特别的内容:
  • 比如添加一个 noscript 标签,在用户的 JavaScript 被关闭时,给予响应的提示;
  • 比如在开发 vue 或者 react 项目时,我们需要一个可以挂载后续组件的根标签

这个我们需要一个属于自己的 index.html 模块: webpack详细笔记(收藏版)

  • 在配置 HtmlWebpackPlugin 时,我们可以添加如下配置:
    • template:指定我们要使用的模块所在的路径;
    • title:在进行 htmlWebpackPlugin.options.title 读取时,就会读到该信息

webpack详细笔记(收藏版)

3.DefinePlugin 插件

DefinePlugin 允许在编译时创建配置的全局常量,是一个 webpack 内置的插件(不需要单独安装): webpack详细笔记(收藏版)

15.Mode 配置

  • Mode 配置选项,可以告知 webpack 使用相应模式的内置优化:
    • 默认值是 production(什么都不设置的情况下);
    • 可选值有:'none' | 'development' | 'production';

这几个选项有什么样的区别

webpack详细笔记(收藏版)

两个模式默认配置

webpack详细笔记(收藏版)

16.搭建本地服务器

为了完成自动编译,webpack 提供了几种可选的方式:

  • webpack watch mode;
  • webpack-dev-server(常用);
  • webpack-dev-middleware;

webpack-dev-server

安装 webpack-dev-server

npm install webpack-dev-server -D

修改配置文件,启动时加上 serve 参数:

webpack详细笔记(收藏版)

host 配置

  • host 设置主机地址:

    • 默认值是 localhost;
    • 如果希望其他地方也可以访问,可以设置为 0.0.0.0;
  • localhost 和 0.0.0.0 的区别:

  • localhost:本质上是一个域名,通常情况下会被解析成 127.0.0.1;

  • 127.0.0.1:回环地址(Loop Back Address),表达的意思其实是我们主机自己发出去的包,直接被自己接收;

  • 正常的数据库包经常 应用层 - 传输层 - 网络层 - 数据链路层 - 物理层 ;

  • 而回环地址,是在网络层直接就被获取到了,是不会经常数据链路层和物理层的;

  • 比如我们监听 127.0.0.1 时,在同一个网段下的主机中,通过 ip 地址是不能访问的;

  • 0.0.0.0:监听 IPV4 上所有的地址,再根据端口找到不同的应用程序;

  • 比如我们监听 0.0.0.0 时,在同一个网段下的主机中,通过 ip 地址是可以访问的;

  • port 设置监听的端口,默认情况下是 8080

  • open 是否打开浏览器:

    • 默认值是 false,设置为 true 会打开浏览器;
    • 也可以设置为类似于 Google Chrome 等值;
  • compress 是否为静态文件开启 gzip compression:

  • 默认值是 false,可以设置为 true;

webpack详细笔记(收藏版) 帮助到你帮忙点赞收藏,不对的地方指点一下小弟。