常用loader
编译:babel-loader、vue-loader 、ts-loader等
样式:style-loader、css-loader、less-loader、postcss-loader(autoprefix)等
文件:raw-loader、file-loader 、url-loader等
校验测试:mocha-loader、jshint-loader 、eslint-loader等
一种特殊的plugin,专门用于转换代码格式,比如将less转为css,ts转为js,或者babel转换成es5
loader开发 基本操作 【官方文档 】【参考资料 】 【其它API 】
module .exports = function (source ) { const callback = this .async(); callback(null ,newContent, sourceMaps, meta); return transform(source); } module .exports = function (source ) { const callback = this .async(); this .cacheable(); this .addDependency(headerPath); fs.readFile(headerPath, 'utf-8' , (err, header) => { if (err) { this .callback(err) } else { this .callback(null , header + '\n' + source); } }); }
recast复杂操作 代码操作比较复杂时,可以使用recast
:webpack的ast是用recast生成的,而recast则依赖babel一系列的库【参考资料 】
const recast = require ('recast' )const t = recast.types.namedTypesmodule .exports = function (source ) { const ast = recast.parse(source, { parser: require ('recast/parsers/babel' ) }) recast.visit(ast, { visitCallExpression (path) { const { node } = path const arguments = node.arguments let firstExp arguments .forEach(item => { if (t.ArrowFunctionExpression.check(item)) { ... } }) return false } }) return recast.print(ast).code }
loader间数据共享 module .exports = function (source ) { console .log(this .data.value); return '{};' + source; } module .exports.pitch = (remaining, preceding, data ) => { data.value = 'test' ; }
loader原理 【参考资料 】
let source = fs.readFileSync(modulePath, "utf8" );let rules = that.options.module.rules;for (let i = 0 ; i < rules.length; i++) { let rule = rules[i]; if (rule.test.test(modulePath)) { let loaders = rule.use; let length = loaders.length; let loaderIndex = length - 1 ; function iterateLoader ( ) { let loaderName = loaders[loaderIndex--]; let loader = require (join(that.root, "node_modules" , loaderName)); source = loader(source); if (loaderIndex >= 0 ) { iterateLoader(); } } iterateLoader(); break ; } } return source;