模块化打包工具的由来:ES Modules存在环境兼容问题、模块文件过多,网络请求频繁,而且所有的前端资源都需要模块化。
打包工具解决的是前端整体的模块化,并不单指JavaScript模块化

webpack:模块打包器、模块加载器、代码拆分、载入资源模块

一、webpack的基本使用

  • 先在项目的根目录下执行yarn init -y,创建package.json
  • 安装webpack相关依赖:yarn add webpack webpack-cli --dev
  • 查看webpack版本:yarn webpack --version
  • 执行 yarn webpack 进行打包,生成了 dist 目录,里面有 main.js 文件
  • 修改 index.html 中的index.js的路径为 dist/main.js ,并且去掉 script 标签的 type=module 的属性
  • 去package.json的scripts中定义一个build任务:”build”: “webpack”, 以后执行yarn build进行打包

二、webpack的配置文件

webpack.config.js文件是运行在nodejs文件下的js文件,我们需要按照CommonJS的方式编写代码。这个文件需要导出一个对象,我们完成对应的配置选项。
webpack.config.js

  1. const path = require('path')
  2. module.exports = {
  3. entry: './src/index.js', // 指定打包入口文件,如果是相对路径,前面的点和斜线不能少
  4. output: {
  5. filename: 'bundle.js', // 输出文件的名称
  6. path: path.join(__dirname, 'output'), // 输出路径,为绝对路径
  7. }
  8. }

三、webpack工作模式

直接执行webpack打包的时候,控制台会有警告,说没有指定工作模式,默认以生产模式打包,会进行代码的压缩。
我们可以通过cli命令指定工作模式,就是增加一个--mode的参数,属性有三种选择,production、development、none

  • production:生产模式会默认启动优化,优化我们的打包结果
  • development:开发模式,会自动优化打包的速度,添加一些调试过程中的辅助到代码中
  • none:原始状态的打包,不会做任何处理

可以通过yarn webpack —mode development来执行.

此外,还可以在webpack的配置文件中指定工作模式,也就是增加一个mode属性,例如:mode: “development”

四、webpack资源模块加载

将配置文件中的entry属性的值改为./src/main.css,然后执行打包命令yarn webpack,会报错
因为webpack默认会把文件当做js解析,所以打包css文件时,文件内容不符合JS语法则报错了,报错中提示我们可以寻找正确的loader去解析代码。webpack内部的loader只能解析js,所以我们要手动安装css-loader去处理css代码。
loader是实现前端模块化的核心,通过它,可以加载任何类型的资源

执行命令:yarn add css-loader --dev
然后在webpack的配置文件中增加属性

  1. module: {
  2. rules: [
  3. {
  4. test: /.css$/,
  5. use: 'css-loader'
  6. }
  7. ]
  8. }

增加外部的loader需要在配置文件中增加资源模块module属性,属性值是一个对象,对象中有一个rules数组,数组里每个元素都是一个对象,对象中的test属性是正则式,指明要处理的资源文件,use属性是对该资源进行处理的loader名称。

再次执行打包命令,发现css没有作用,是因为我们使用css-loader只是对css文件进行了打包,但是并没有作用到页面上,接下来还要安装一个style-loader
执行命令:yarn add style-loader --dev
style-loader是将css-loader处理后的结果,通过style的形式追加到页面上

  1. module: {
  2. rules: [
  3. {
  4. test: /.css$/,
  5. use: ['style-loader', 'css-loader']
  6. }
  7. ]
  8. }

use配置了多个loader,是一个数组,里面的loader是从右往左执行,所以要将css-loader写在后面,我们要先用css-loader将css代码转化成js模块,才可以正常打包。

五、webpack 导入资源模块

虽然webpack的入口文件可以是别的类型文件,但由于前端项目是由JS驱动,所以我们开发时一般将入口文件设置为JS文件,需要用到CSS时,就直接在JS文件中通过import导入即可,如:import ‘./main.css’

webpack建议我们根据代码的需要在JS中动态导入资源文件,因为需要资源的不是应用,而是代码。
因为是JavaScript驱动了整个前端应用,这样做的好处是:

  • 逻辑合理,JS确实需要这些资源文件
  • 确保上线资源不缺失,都是必要的

六、webpack文件资源加载器

安装文件资源加载器:yarn add file-loader --dev,相当于直接拷贝物理文件。
不过此时资源文件路径会出现问题,webpack默认认为它打包过后的文件会放在网站的根目录下面,此时需要在配置文件中的output属性中指定publicPath属性值为dist/,即:publicPath: ‘dist/‘ ,这样在打包时,文件的输出路径前面会拼接上publicPath的值。

七、webpack URL 加载器

格式:协议 + 媒体类型和编码 + 文件内容
格式: data:[][;base64],

例如:data:text/html;charset=UTF-8,

html content


先安装url-loader:yarn add url-loader --dev
普通文件会转成Data URLs,图片会转成base64编码,会把文件的内容在打包后的文件在用data url的形式显示

修改png文件的loader为url-loader

  1. {
  2. test: /.png$/,
  3. // use: 'file-loader',
  4. use: 'url-loader'
  5. }

执行yarn webpack,此时的png文件的URL则为data协议的了。

最佳使用方式:

  • 小文件使用Data URLs,减少请求次数
  • 大文件独立提取存放,提高加载速度

配置方式:

  1. {
  2. test: /.png$/,
  3. // use: 'file-loader',
  4. use: {
  5. loader: 'url-loader',
  6. options: {
  7. limit: 10 * 1024, // 单位是字节 10KB
  8. }
  9. }
  10. }
  • 超过10KB的文件单独提取存放
  • 小于10KB文件转换为Data URLs嵌入代码中

    注意:这种方式还是要安装file-loader,因为对超出大小的文件还是会调用file-loader,如果没有file-loader会报错。

八、webpack 常用加载器分类

  1. 编译转换类,转换为JS代码,如css-loader
  2. 文件操作类,将资源文件拷贝到输出目录,将文件访问路径向外导出,如:file-loader
  3. 代码检查器,统一代码风格,提高代码质量,如:`es-loader``

`

九、webpack 处理ES2015

因为模块打包需要,它会处理import和export,除此之外,并不能转换其他的ES6特性。如果想要处理ES6,需要安装转化ES6的编译型loader。
最常用的就是babel-loader,babel-loader依赖于babel的核心模块,@babel/core和@babel/preset-env
执行命令:yarn add babel-loader @babel/core @babel/preset-env —dev
修改js的loader

  1. {
  2. test: /.js$/,
  3. use: {
  4. loader: 'babel-loader',
  5. options: {
  6. presets: ['@babel/preset-env']
  7. }
  8. },
  9. exclude: /(node_modules)/, // 这里很重要,千万别忘了,否则会出错的。
  10. }

十、webpack的模块加载方式

  1. 遵循ES Modules标准的import声明
  2. 遵循CommonJS标准的require函数。对于ES的默认导出,要通过require(‘./XXX’).default的形式获取
  3. 遵循AMD标准的define函数和require函数
  4. Loader加载的非JavaScript也会触发资源加载

样式代码中的@import指令和url函数

  1. @import url(reset.css);
  2. body {
  3. margin: 0 auto;
  4. padding: 0 20px;
  5. max-width: 800px;
  6. background: url(1.png);
  7. background-size: cover;
  8. }

css-loader在处理css代码时,遇到了background属性中的url函数,发现是引入的资源文件是png格式的文件,则将这个资源文件 交给url-loader处理

html-loader处理HTML文件中,加载其他资源,如:代码中的图片标签的src属性

  1. {
  2. test: /.html$/,
  3. use: {
  4. loader: 'html-loader',
  5. options: {
  6. //attrs:['img:src','a:href'],
  7. // html-loader默认只处理页面中的img标签的src属性的资源文件,所以其他标签的资源文件要处理
  8. attributes: {
  9. list: [
  10. {
  11. tag: 'img',
  12. attribute: 'src',
  13. type: 'src'
  14. },
  15. {
  16. tag: 'a',
  17. attribute: 'href',
  18. type: 'src'
  19. }
  20. ]
  21. }
  22. }
  23. }
  24. }

十一、webpack的核心工作原理

webpack使用 -1 - 图1