我已经会手写没用的loader了

2020-09-04 15:47:48 浏览数 (1)

webpack的loader配置应该谁都会,讲道理,我们会使用loader,会配置loader就够了。今天只是了解loader的基本概念和基本的运行原理,了解了就能自己写一个loader了,至于手写一些复杂的loader目前就算了。

先说说webpack中文网对loader的一些介绍:

loader是用于对模块的源代码进行转换,可以在你import或加载模块时预处理文件。loader可以将不同语言(typescript)转换成JavaScript、将内联图像转成data URL、在JavaScript中import css文件。loader有一些特性,loader 支持链式传递。一组链式的 loader 将按照相反的顺序执行。loader 链中的第一个 loader 返回值给下一个 loader。在最后一个 loader,返回webpack所预期的JavaScript。loader可以是同步也可以是异步。loader 模块需要导出为一个函数,并且使用 Node.js 兼容的 JavaScript 编写。内容不多,其实可以去看看,还有几个特性可以看看。

需要注意的几点:

loader就是一个函数,要返回js的脚本

loader要遵循单一原则,只做一件事,所以要有style-loader、css-loader,而不是整合成一个loader

可以链式调用,从右往左,从下往上

loader要是无状态的,不同模块之间不保存状态,要能够单一运行。

配置好常规配置,然后loader指向自己写的loader(loader/loader.js):

use: path.resolve(__dirname, 'loader', 'loader')

需要绝对路径,也可以这样:

resolveLoader: {

// alias: {

// loader: path.resolve(__dirname, 'loader', 'loader')

// },

modules: ['node_modules', path.resolve(__dirname, 'loader')]

}

两个选一个,第一个是别名,第二个是loader默认从node_module里面找,找不到就到loader文件夹里面找。

loade.js里面内容:

function loader(resource){

console.log(resource)

return resource

}

module.exports = loader;

参数resource就是js的代码,如果return的内容是数字,就会报错,因为要返回预期的JavaScript:

Module build failed: Error: Final loader (./loader/loader.js) didn't return a Buffer or String

控制台打印(index.js引入a.js):

loader的运行原理挺简单的,并不复杂,复杂的是要怎么去处理传递进来的代码。

说说loader的几个模式,优先级顺序:pre、normal、inline、post

清空index.js,然后引入loader1、loader2、loader3,分别打印文件名:

use: ['loader1', 'loader2', 'loader3']

这边没有设置什么,就是默认顺序,都是normal,接着设置:

{

test: /.js$/,

use: 'loader1',

enforce: 'pre'

},

{

test: /.js$/,

use: 'loader2'

},

{

test: /.js$/,

use: 'loader3',

enforce: 'post'

}

打印出来:

inline比较特殊,如果上面都不干预,新建一个inline-loader.js,引入文件的时候使用:

let str = require('-!inline-loader!./a.js')

打印:

-!表示不再用pre和normal的loader处理,所以这边走完inline-loader之后只执行设置post的loader3,另外还有两种,!不走normal,!!什么都不走,只走inline-loader。

loader有两部分组成,pitch和normal,先执行pitch,如果pitch有返回值,则直接跳过接下去的loader直接返回,包括自己,给每个loader加pitch方法并打印:

loader.pitch = function(resource){

console.log('loader1 pitch')

}

打印:

这边先执行pitch再执行normal,我如果在loader3 pitch这边添加return ‘’,打印:

loader还有很多api,比如异步loader的this.async(),this.callback返回多个结果的函数、通过loader-utils(需要自己安装依赖)获取配置的options参数等等,可以去官网看一下:

https://www.webpackjs.com/api/loaders/#this-target

loader大概就先了解到这样,async和callback使用其实更重要,如果要编写有用的loader要好好研究,今天就不去尝试。 loader运行过程其实不难,难得应该是内部的解析过程。

0 人点赞