一文详解webpack中loader与plugin的区别

一、Loader

1.loader的作用:

webpack 只能直接处理 javascript 格式的代码。任何非 js 文件都必须被预先处理转换为 js 代码,才可以参与打包。loader(加载器)就是这样一个代码转换器。

2.loader的工作原理:

它由 webpack 的 loader runner 执行调用,接收原始资源数据作为参数(当多个加载器联合使用时,上一个loader的结果会传入下一个loader),最终输出 javascript 代码(和可选的 source map)给 webpack 做进一步编译。

3. Loader 执行顺序

1). loader类型

pre: 前置loader normal: 普通loader inline: 内联loader post: 后置loader

2). 执行优先级

4类 loader 的执行优级为:pre > normal > inline > post 。 相同优先级的 loader 执行顺序为:从右到左,从下到上。 3. 前缀的作用

内联 loader 可以通过添加不同前缀,跳过其他类型 loader。

! 跳过 normal loader。 -! 跳过 pre 和 normal loader。 !! 跳过 pre、 normal 和 post loader。 这些前缀在很多场景下非常有用。

4.如何开发一个loader

loader 是一个导出一个函数的 node 模块。

1). 最简单的 loader

当只有一个 loader 应用于资源文件时,它接收源码作为参数,输出转换后的 js 代码。

// loaders/simple-loader.js module.exports = function loader (source) { console.log('simple-loader is working'); return source; } 揭秘webpack loader - 知乎

style-loader 最终需返回一个 js 脚本:在脚本中创建一个 style 标签,将 css 代码赋给 style 标签,再将这个 style 标签插入 htmlhead 中。

二、Plugin

1.plugin解决其他的更多的自动化打包工作

plugin的范围更大,作用也更强。

可以自动打包生成html文件,并自动引入打包后的结果 打包前清除原dist文件中的内容 可以将我们需要的但是并没有引入静态资源一同打包到dist文件中 对打包的结果进行特殊的处理 压缩打包后的内容,对打包结果可以进行更细的自定义操作

2.自定义插件

1)在造轮子之前我们必须要知道它的原理,plugin相比loader还有一点很大的不同,loader只工作于模块的加载环节,而plugin即可可以作用于打包过程的每一个环节,有点像vue中的生命周期,我们可以在一个合适的周期进行相应的操作。webpack的插件机制就是我们常说的钩子机制,整个打包过程可以分为多个环节,为了便于插件的扩展,webpack机会在每个环节都提供了一个钩子,我们就可以利用这些钩子来造轮子。

2)webpack为我们提供了哪些hooks呢?

entry-option 初始化 option run 开始编译 compile 真正开始的编译,在创建 compilation 对象之前 compilation 生成好了 compilation 对象 make 从 entry 开始递归分析依赖,准备对每个模块进行 build after-compile 编译 build 过程结束 emit 在将内存中 assets 内容写到磁盘文件夹之前 after-emit 在将内存中 assets 内容写到磁盘文件夹之后 done 完成所有的编译过程 failed 编译失败的时候 …

3)webpack要求我们的插件必须是一个函数,或者是一个包含apply的对象。一般来说我们都会定义一个类型,然后在这个类型中定义apply方法,最后再通过这个类型来创建一个实例对象去使用这个插件。

const pluginName = 'myplugin'
module.exports = class myplugin {
 apply(){}
}

这个apply方法接收一个叫compiler的参数对象,这个对象是webpack工作中最核心的对象,包含了此次打包构建的所有配置信息,我们就可以通过这个对象去注册钩子函数。

const pluginName = 'myplugin'
module.exports = class myplugin {
 apply(compiler){
 compiler.hooks.run.tap(pluginName, () =>{
 {
 console.log('开始编译');
 }
 })
 }
}

我们想在run阶段输出‘开始编译’这句话,在webpack.config.js中引入并配置

const myplugin = require('./myplugin')
plugins:[
 new myplugin()
]

常见的Loader和Plugin

loader:

style-loader :在html文件中创建标签,将js中的样式插入

css-loader:将css文件变成commonjs模块加载到js中,输出为样式字符串

less-loader:将less转换为css

url-loader+内置file-loader:处理图片资源(不能处理html中的图片)

html-loader:处理html中的图片,负责引入img从而能被url-loader处理

{
 test: /\.(jpg|png|gif)$/,
 use: {
 loader: 'url-loader',
 options:{
 limit:5*1024,
 esModule: false,
 name:[hash:10].[ext] //给图片文件重命名,取哈希值前10位加上原来的扩展名
 }
 },
 type:'javascript/auto' //在webpack4的基础上加上这句话
 },
{
 test: /\.(htm|html)$/,
 loader: 'html-loader',
}

file-loader:打包其他资源,如字体图标,不需要优化压缩

(webpack5之后,我们可以直接使用资源模块类型(asset module type),来替代上面的这些loader)

plugin:

html-webpack-plugin:在build中新建一个index.html文件,自动引入打包输出的所有资源(js/css).可以配置 template为新html文件创建模板

ignore-plugin:用来忽略一些文件

mini-css-extract-plugin:将css单独打包成一个文件的css

clean-webpack-plugin:用于清除目录文件,在生产环境中编译文件的时候,用它来讲dist的目录清除干净,然后再生成新的

serviceworker-webpack-plugin:离线缓存功能

webpack-parallel-uglify-plugin:多线程压缩js代码,加快构建速度

作者:耀_

%s 个评论

要回复文章请先登录注册