XingYun blog
  • JS基础

    • 图解js原型链
    • JS Event Loop
    • 对象的底层数据结构
    • 让你的JavaScript代码简单又高效
    • 函数参数按值传递
    • 判断数据类型
    • 浮点数精度问题和解决办法
    • 常用方法snippet
    • 实现Promise
    • 防抖和节流
    • 巧用sort排序
  • CSS && HTML

    • CSS也需要性能优化
    • class命名规范
    • em、px、rem、vh、vw 区别
    • CSS揭秘阅读笔记
  • 浏览器

    • 浏览器是如何渲染页面的
    • 重排和重绘
    • BOM浏览器对象模型
    • DOM事件
    • 浏览器存储
  • 数据结构

    • JS实现链表
    • JS实现栈与栈应用
    • JS实现常见排序
    • 哈夫曼编码
    • MD5算法
  • vue原理浅析

    • Vue虚拟dom与Diff算法
    • 前端打包文件的缓存机制
    • vue数组为什么不是响应式
    • v-for为什么不能用index做key
  • 前端工程化

    • 浏览器是如何渲染页面的
    • 前端打包需要gzip压缩吗
    • 前端打包文件的缓存机制
    • webpack loader和plugin
  • 轮子&&组件库

    • 实现水波浪进度球
  • 文字转语音mp3文件
  • 文件上传前后端实现
  • moment.js给定时间获取自然月、周的时间轴
  • 实现文件上传功能
  • 批量下载照片
  • leaflet改变坐标原点
  • 网络

    • 有了MAC地址 为什么还需要IP地址
    • 为什么IP地址老是变
    • 我们为什么需要IPV6
    • TCP与UDP
  • 计算机组成原理

    • ASCII、Unicode、UTF-8和UTF-16
  • VSCode

    • VSCode图片预览插件 Image preview
    • rsync:linux间的高效传输工具

XingYun

冲!
  • JS基础

    • 图解js原型链
    • JS Event Loop
    • 对象的底层数据结构
    • 让你的JavaScript代码简单又高效
    • 函数参数按值传递
    • 判断数据类型
    • 浮点数精度问题和解决办法
    • 常用方法snippet
    • 实现Promise
    • 防抖和节流
    • 巧用sort排序
  • CSS && HTML

    • CSS也需要性能优化
    • class命名规范
    • em、px、rem、vh、vw 区别
    • CSS揭秘阅读笔记
  • 浏览器

    • 浏览器是如何渲染页面的
    • 重排和重绘
    • BOM浏览器对象模型
    • DOM事件
    • 浏览器存储
  • 数据结构

    • JS实现链表
    • JS实现栈与栈应用
    • JS实现常见排序
    • 哈夫曼编码
    • MD5算法
  • vue原理浅析

    • Vue虚拟dom与Diff算法
    • 前端打包文件的缓存机制
    • vue数组为什么不是响应式
    • v-for为什么不能用index做key
  • 前端工程化

    • 浏览器是如何渲染页面的
    • 前端打包需要gzip压缩吗
    • 前端打包文件的缓存机制
    • webpack loader和plugin
  • 轮子&&组件库

    • 实现水波浪进度球
  • 文字转语音mp3文件
  • 文件上传前后端实现
  • moment.js给定时间获取自然月、周的时间轴
  • 实现文件上传功能
  • 批量下载照片
  • leaflet改变坐标原点
  • 网络

    • 有了MAC地址 为什么还需要IP地址
    • 为什么IP地址老是变
    • 我们为什么需要IPV6
    • TCP与UDP
  • 计算机组成原理

    • ASCII、Unicode、UTF-8和UTF-16
  • VSCode

    • VSCode图片预览插件 Image preview
    • rsync:linux间的高效传输工具
  • 3个提升Vue性能的写法
  • 重读Vue文档
  • moment.js给定时间获取自然月、周的时间轴
  • Vue虚拟dom与Diff算法
  • 深入响应式原理
  • Echart样例
  • 我的Vue指令库
  • 滚动到底部加载更多
  • 实现一键换肤
  • 手写Vue数据劫持
  • vue-router核心原理与手写实现
  • computed和watch
  • vue数组为什么不是响应式
  • v-for为什么不能用index做key
  • webpack loader和plugin
    • webpack Loader 和 Plugin
      • 一、Loader 和 Plugin 的区别
      • 二、Webpack 常见的 Loader
      • 三、手写一个 loader
      • 四、手写一个 plugin
  • keep-alive组件原理
  • vue插槽进化
  • Vue多层嵌套组件
  • vue生命周期hook
  • vue监听dom元素的resize事件
  • 前端打包需要gzip压缩吗
  • 实现水波浪进度球
  • Vue
XingYun
2021-12-01
目录

webpack loader和plugin

# webpack Loader 和 Plugin

# 一、Loader 和 Plugin 的区别

不同的作用

Loader直译为"加载器"。Webpack 将一切文件视为模块,但是webpack原生是只能解析js文件,如果想将其他文件也打包的话,就会用到 loader。

所以 Loader 的作用是让 webpack 拥有了加载和解析非 JavaScript 文件的能力。

Plugin直译为"插件"。Plugin 可以扩展 webpack 的功能,让 webpack 具有更多的灵活性。 在 Webpack 运行的生命周期中会广播出许多事件,Plugin 可以监听这些事件,在合适的时机通过 Webpack 提供的 API 改变输出结果。

不同的用法

Loader在 module.rules 中配置,也就是说他作为模块的解析规则而存在。 类型为数组,每一项都是一个 Object,里面描述了对于什么类型的文件(test),使用什么加载(loader)和使用的参数(options)

Plugin在 plugins 中单独配置。 类型为数组,每一项是一个 plugin 的实例,参数都通过构造函数传入。

# 二、Webpack 常见的 Loader

  • babel-loader 用babel来转换ES6文件到ES5
  • esbuild-loader:加载 ES2015+ 代码并使用 esbuild 转译到 ES6+
  • vue-loader:加载并编译 Vue 组件
  • css-loader 允许将css文件通过import的方式引入,并返回css代码
  • less-loader 处理 less
  • sass-loader 处理 sass
  • image-loader:加载并且压缩图片文件
  • eslint-loader:通过 ESLint 检查 JavaScript 代码
  • url-loader:和 file-loader 类似,但是能在文件很小的情况下以 base64 的方式把文件内容注入到代码中去
  • html-minify-loader 压缩 HTML
// 下面的一组loader就是链式传递, 从 sass-loader 开始执行,然后继续执行 css-loader,最后以 style-loader 为结束
use: [
  { loader: 'style-loader' },
  {
    loader: 'css-loader',
    // 通过options配置
    options: {
      modules: true,
      minimize: true
    }
  },
  { loader: 'sass-loader' }
]
1
2
3
4
5
6
7
8
9
10
11
12
13
  • loader是webpack核心**,**用于对模块的源代码进行转换
  • loader 支持链式调用,从右至左执行,支持同步或异步函数

# 三、手写一个 loader

Loader 像一个"翻译官"把读到的源文件内容转义成新的文件内容,并且每个 Loader 通过链式操作,将源文件一步步翻译成想要的样子。

编写 Loader 时要遵循单一原则,每个 Loader 只做一种"转义"工作。 每个 Loader 的拿到的是源文件内容(source),

可以通过返回值的方式将处理后的内容输出,

也可以调用 this.callback()方法,将内容返回给 webpack。

还可以通过 this.async()生成一个 callback 函数,再用这个 callback 将处理后的内容输出出去。

此外还可以使用 webpack 工具函数集——loader-utils。

例:写一个去除 console.log 的 loader

module.exports = function(content) {
  return content.replace(/console.log\(['|"](.*?)['|"]\)/, '')
}
1
2
3

配置使用

module: {
    rules: [
      {
        test: /\.js$/, // 对js文件使用
        use: [
          'console-loader'
        ],
      },
    ],
  },

1
2
3
4
5
6
7
8
9
10
11

# 四、手写一个 plugin

相对于 Loader 而言,Plugin 的编写就灵活了许多。 webpack在运行的生命周期中会广播出许多事件,Plugin 可以监听这些事件,在合适的时机通过 Webpack 提供的 API 改变输出结果。

写个插件记录打包

class OutLogPlugin {
  constructor(options) {
    this.outFileName = options.outFileName
  }
  apply(compiler) {
    // 可以从编译器对象访问 webpack 模块实例
    // 并且可以保证 webpack 版本正确
    const { webpack } = compiler
    // 获取 Compilation 后续会用到 Compilation 提供的 stage
    const { Compilation } = webpack
    const { RawSource } = webpack.sources
    /** compiler.hooks.<hoonkName>.tap/tapAsync/tapPromise */
    compiler.hooks.compilation.tap('OutLogPlugin', (compilation) => {
      compilation.hooks.processAssets.tap(
        {
          name: 'OutLogPlugin',
          // 选择适当的 stage,具体参见:
          // https://webpack.js.org/api/compilation-hooks/#list-of-asset-processing-stages
          stage: Compilation.PROCESS_ASSETS_STAGE_SUMMARIZE
        },
        (assets) => {
          let resOutput = `buildTime: ${new Date().toLocaleString()}\n\n`
          resOutput += `| fileName  | fileSize  |\n| --------- | --------- |\n`
          Object.entries(assets).forEach(([pathname, source]) => {
            resOutput += `| ${pathname} | ${source.size()} bytes |\n`
          })
          compilation.emitAsset(
            `${this.outFileName}.md`,
            new RawSource(resOutput)
          )
        }
      )
    })
  }
}
module.exports = OutLogPlugin
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36

配置使用

const OutLogPlugin = require('./plugins/OutLogPlugin')

module.exports = {
  plugins: [new OutLogPlugin({ outFileName: 'buildInfo' })]
}
1
2
3
4
5

输出 md 文件内容

buildTime: 2021/12/1 下午 4:59:48

fileName fileSize
bundle.js 4398 bytes
bundle.map.js 4098 bytes
#vue
上次更新: 2023/04/05, 09:41:10
v-for为什么不能用index做key
keep-alive组件原理

← v-for为什么不能用index做key keep-alive组件原理→

最近更新
01
JavaScript-test
07-20
02
二维码的原理
07-20
03
利用ChatGPT优化代码
07-20
更多文章>
Theme by Vdoing | Copyright © 2021-2023 XingYun | MIT License
  • 跟随系统
  • 浅色模式
  • 深色模式
  • 阅读模式