参考 :译文 编写一个loader

https://webpack.github.io/docs/loaders.html

按照loader的返回值可以分为两种:

  • 最左loader:这种loader会返回字符串描述的js模块代码,已经是loader的最终处理结果了,这样的字符串会被添加到webpack的模块函数中
  • 非最左loader:返回值不是js模块代码,而仅仅是对资源的中间处理结果,这样的字符串需要被后续的loader处理

一般情况下,在loader的链式调用中,一般是这样:最左loader!非最左loader!非最左loader ....

简单loader例子

// loaders/myLoader.js 返回的值是js模块代码,这个loader属于最左loader
module.exports = function loader(source) {
return `module.exports = {fn: ${source}}`;
}; // main.js
const src = require("./src")
src.fn(); // src.js
alert(999) //配置文件
const path = require('path')
module.exports = {
entry: [__dirname + "/main.js"],
output: {
path: __dirname + "/dist",
filename: "bundle.js",
},
module: {
loaders:[
{
test: /src.js/,
use: [
{
loader: path.resolve(__dirname, './loaders/myLoader.js'),
}
]
}
]
}
}

打包后的结果

/***/ }),
/* 1 */
/***/ (function(module, exports, __webpack_require__) { const src = __webpack_require__(2)
src.fn(); /***/ }),
/* 2 */
/***/ (function(module, exports) { module.exports = {fn: alert(999)} /***/ })
/******/ ]);

注意:如果loader处理的是所有js,则入口文件是js的话也会被处理。

从以上代码可以看出,对于某些loader,他们导出的结果可能并不重要,而是可以在导出之前,根据拿到的文本内容对页面做一些操作。

aync loader

把以上小例子中的loader定义为:

module.exports = function(source) {
var callback = this.async();
setTimeout(function(){
callback(null,`module.exports = {fn: ${source}}`)
},5000);
};

启动打包后,经过5s才打包完成。打包结果和以上小例子中的一致。

pitching loader

  在loader函数对象上添加一个pitch属性,这个pitch所执行的函数称为pitching loader。在pitching loader中可以通过data把数据传递给对应的loader,而不能传递给其他loader。

  在链式调用中,pitching loader 与 loader的执行次序(以 a!b!c!resource 为例):

  • pitch a

    • pitch b

      • pitch c

        • read file resource (adds resource to dependencies)
      • run c
    • run b
  • run a

  在pitching loader有返回值时的情况

  • pitch a

    • pitch b (returns something)
  • run a

  可见,哪个pitching loader有返回值,则对应的loader以及后续的loader都不执行了。以上例子中a loader函数的第一个参数就是b pitching loader的返回值。

pitching loader的应用场景

  问题是有时候我们想把两个第一种loader chain起来,比如

style-loader!css-loader

  而 css-loader的返回值是一串js代码(包含了module.export=xxx这样的字符串),如果按正常方式写style-loader的参数就是一串代码字符串。就算eval了也不一定拿到什么值:

eval('module.export="result";console.log("hello world")') === "hello world"

  为了解决这种问题,我们需要在style-loader里执行require(css-loader!resouce), 这会把css-loader跑一遍,也就是说如果按正常顺序执行css-loader会跑两遍(第一遍拿到的js代码用不了), 为了只执行一次,style-loader利用了pitching, 在pitching函数里require(css-loader!resouce)。然后返回js代码(style-loader能够作为最左边loader)

  

最新文章

  1. linux mysql 安装配置
  2. App_Data 目录中的数据库位置指定了一个本地 SQL Server
  3. unity3d 我的面试经历
  4. 项目管理工具之Git使用说明
  5. 【BZOJ1006】【HNOI2008】神奇的国度(弦图染色)
  6. Qt 静态函数QMetaObject::connectSlotsByName(QObject * object)按命名规则自动connect,不需要手动connect
  7. Frame与启动流程
  8. DCI
  9. 【转】Android开源项目 分类 便于查看
  10. 读书笔记 effective c++ Item 9 绝不要在构造函数或者析构函数中调用虚函数
  11. Number Sequence(快速幂矩阵)
  12. 在linux ubuntu下搭建深度学习/机器学习开发环境
  13. Linux传统Huge Pages与Transparent Huge Pages再次学习总结
  14. 函数中的this与argument对象,以及argument中的callee与caller属性
  15. Msf的一些常用操作
  16. SQLite保存报错sqlite.SQLiteConstraintException: UNIQUE constraint failed: ······ code 1555
  17. dirty_background_ration 与 /proc/sys/vm/dirty_ratio
  18. ubuntu下好用的音乐播放器audacious
  19. 目标检测评价指标(mAP)
  20. linux $* $@ 特定位置参数

热门文章

  1. Eclipse 修改编码方式
  2. 黑马Stream流学习 Stream流 函数式接口 Lambda表达式 方法引用
  3. 黑马MySQL数据库学习day02 表数据CRUD 约束CRUD
  4. iOS开发 - RunLoop理解
  5. Gitlab备份,Crontab定时备份
  6. nginx 一些配置
  7. IMG 的alt和title的区别(转自 百度空间--路云的世界)
  8. GYM 101673E(暴搜预处理)
  9. C. On Number of Decompositions into Multipliers 组合数学
  10. DB2中横表纵表互换