【webpack】学习笔记之一

110 阅读7分钟

前言

这段时间因为找工作,出于未来发展以及工作使用的考虑。所以决定用心学习一下webpack的各种知识点。

PS:各种知识点比较松散,主要用于记录自己的学习过程。以及在以后的使用中,在知识点有所遗忘或出错时,用于回顾反思。

Webpack是什么

webpack是一个前端资源构建(翻译)工具,一个轻量化的、开箱即用的模块打包工具

  • 前端资源构建(翻译)工具:而当前流行的比如sasslesstypescript以及ES6的新语法,这些是浏览器所不能直接识别的资源文件。而当我们希望这些资源能够在浏览器中工作时,就必须经过处理(也就是翻译)。而webpack就是干这事儿的。
  • 模块打包工具:就是web开发过程中的各种资源文件,webpack根据引用关系,构建一个依赖关系图,然后利用这个关系图将所有静态模块打包成一个或多个bundle输出。

为什么我们需要用到webpack

上述小节就已经说明了webpack被需要的两个原因:一是前端资源的需要和浏览器的不支持;二是打包的问题。

那么除了这两点,我个人在学习和开发中无法避免使用webpack的情况还有:

  • 主流框架的脚手架vue-clicreate-react-app都是使用的webpack
  • webpack的按需加载、代码压缩、资源压缩和热更新等功能是开发中极其便利的功能
  • webpack社区庞大,简单来说就是总有一款适合你

Loader

用途

[webpack中文文档](loader | webpack 中文网 (webpackjs.com))

loader 用于对模块的源代码进行转换。loader 可以使你在 import 或"加载"模块时预处理文件。因此,loader 类似于其他构建工具中“任务(task)”,并提供了处理前端构建步骤的强大方法。loader 可以将文件从不同的语言(如 TypeScript)转换为 JavaScript,或将内联图像转换为 data URL。loader 甚至允许你直接在 JavaScript 模块中 import CSS文件!

通俗易懂一点解释就是:loader会将一些webpack不可识别的文件,转换成webpack可识别的文件

使用方式

在项目中最常见、也是官方最推荐使用的方式是配置。即在webpack.config.js文件中,以配置项的形式来使用。

举例:css扩展语言sass、less的配置

module.exports = {
  mode: "development",
  module: {
    rules: [
      // Less 配置
      {
        test: /\.less$/,
        use: ["style-loader", "css-loader", "less-loader"],
      },
      // Sass 配置
      {
        test: /\.scss$/,
        use: ["style-loader", "css-loader", "sass-loader"],
      },
    ],
  },
};

众所周知,lesssass都是webpack无法直接识别的文件,所以需要使用loader配置去编译一次;而其编译顺序则是按照从右到左,从下到上的顺序来执行的。

除此之外,官方还提供了两种使用方法。

  • 内联:在每次import时,指定loader
import Styles from 'style-loader!css-loader?modules!./styles.css';
  • CLI:在shell命令中指定
webpack --module-bind jade-loader --module-bind 'css=style-loader!css-loader'

babel-loader

简介

babel简单来说就是做一个兼容性的操作,使ES6语法转换成ES6之前的语法,以便支持旧版本的浏览器。

PS:一些情况下,ES2015及其之后的ES标准统称为ES6

编译流程

我们已经知道babel就是把源代码转换的一个过程。 转换过程主要分三步:

  1. parser 把源码转换成AST(抽象语法树)。
  2. transformer 遍历AST,调用各种transform插件对AST进行修改。这一步操作主要是为了将旧AST转换成符合目标源码的AST
  3. generator 把转换后的 AST 打印成目标源码。

核心库 @babel/core

@babel/core的作用是把js代码分析成AST ,方便各个插件分析语法进行相应的处理。 有些新语法在低版本js中是不存在的,如箭头函数,rest 参数,函数默认值等,这种语言层面的不兼容只能通过将代码转为AST,分析其语法后再转为低版本js。

CLI命令行工具 @babel/cli

@babel/clibabel 提供的命令行工具,它主要是提供 babel 这个命令。

安装了@babel/cli后我们就可以使用babel命令来编译js文件了。将src目录下的js编译到lib目录下。

npm install --save-dev @babel/core @babel/cli 
./node_modules/.bin/babel src --out-dir li

插件 plugins & 预设 presets

插件列表 · Babel 中文文档 (docschina.org)

使用插件

如果该插件存在于npm库中,你可以传入插件的名字,Babel会检查它是否安装在 node_modules 中。

{ 
    "plugins": ["@babel/plugin-transform-runtime"] 
}

除了上面这一种方式,还可以通过输入绝对/相对路径来配置插件

{ 
    "plugins": ["./node_modules/XXXX/plugin"] 
}

插件应用顺序:按照数组顺序,正向使用

插件设置

同一插件以下三种写法的最终应用效果相同(无任何配置情况下)

{ "plugins": ["pluginA"] }
{ "plugins": [["pluginA"]] }
{ "plugins": [["pluginA", {}]] }

如果需要配置选项

{ 
  "plugins": [[
    "plugins-name", 
    { 
      "配置项键名": "配置项选项", 
    }
  ]]
}

预设相关

预设的使用及配置与插件完全相同,除了一点:预设的应用顺序为反向应用,即从后往前依次应用。当同时配置了插件与预设时,插件会先一步使用。

创建预设

module.exports = function() { 
  return { 
    plugins: ["pluginA", "pluginB", "pluginC"], 
  }; 
};

需要给有选项的插件或预设进行配置时,其实也和上述一样

module.exports = () => (
  { 
    presets: [require("@babel/preset-env")], 
    plugins: [ 
      [require("@babel/plugin-proposal-class-properties"), { loose: true }], 
      require("@babel/plugin-proposal-object-rest-spread"),
    ], 
  }
);

常见的Loader

  • style-loadercss代码注入到JavaScript中,通过DOM操作去加载CSS。(简单来说,就是把css文件转换成style标签,嵌入HTML中)
  • css-loader 加载 CSS,⽀持模块化、压缩、⽂件导⼊等特性
  • file-loader 把⽂件输出到⼀个⽂件夹中,在代码中通过相对 URL 去引⽤输出的⽂件
  • url-loader 和 file-loader 类似,但是能在⽂件很⼩的情况下以base64的⽅式把⽂件内容注⼊到代码中去
// 图片处理
{
  test: /\.(png|jpg|gif|jpeg|webp|svg)$/,
  // webpack5用法 不需要再使用file-loader和url-loader,已经内置了
  // asset/resource asset/source asset/inline asset 四种,个人喜欢用asset
  type: "asset"
}
  • source-map-loader 加载额外的 Source Map ⽂件,以⽅便断点调试
  • less-loader 将less转换成css
  • sass-loader 将sass转换成css
  • raw-loader 用来处理txt文件,使其变成字符串的形式

插件 plugins

用途

插件是 webpack 的支柱功能。webpack 自身也是构建于,你在 webpack 配置中用到的相同的插件系统之上! 插件目的在于解决 loader 无法实现的其他事

以上是webpack官网给出的介绍

Loader是用来解决前端资源的适配问题,而plugin是用来做一些方位更广的任务。从打包优化和压缩,一直到重新定义环境中的变量等。

使用方式

引入事先安装好的插件,然后在webpack.config.js中引入,并在配置项中实例化

webpack.config.js

const HtmlWebpackPlugin = require('html-webpack-plugin'); // 通过 npm 安装

module.exports = {
  plugins: [new HtmlWebpackPlugin({ template: './src/index.html' })],
};

常见的plugins

  • html-webpack-plugin 可以根据模板自动生成html代码,并自动引用css和js文件
  • extract-text-webpack-plugin 将js文件中引用的样式单独抽离成css文件
  • DefinePlugin 编译时配置全局变量,这对开发模式和发布模式的构建允许不同的行为非常有用。
  • HotModuleReplacementPlugin 热更新
  • mini-css-extract-plugin 将CSS提取到单独的文件中,为每个包含CSS的JS文件创建一个CSS文件,并且支持 CSS和SourceMaps的按需加载(基于webpack5)
  • optimize-css-assets-webpack-plugin 不同组件中重复的css可以快速去重
  • webpack-bundle-analyzer 一个webpack的bundle文件分析工具,将bundle文件以可交互缩放的treemap的形式展示。
  • compression-webpack-plugin 生产环境可采用gzip压缩JS和CSS
  • clean-wenpack-plugin 清理每次打包下没有使用的文件
  • speed-measure-webpack-plugin 打包构建速度分析、查看编译速度