前端工程化7:自定义实现Webpack中的Loader和Plugin

前端工程化7:自定义实现Webpack中的Loader和Plugin,第1张

loader对比plugin
  • loader:用于资源加载并处理各种语言的转换/编译(例如将不同语言转换为javascript);
  • plugin:用于资源加载以外的其他打包/压缩/文件处理等功能;
loader原理,loader的自定义实现loader 用途

loader 用于资源加载并处理各种语言的转换/编译(例如将不同语言转换为javascript);

loader 实现原理,自定义实现
  • loader 函数:loader 必须导出一个函数;它对资源文件进行处理后输出内容;它类似于管道,可以串联多个 loader,将返回值交给下一个 loader 继续处理;
  • loader 输入:function 接收一个参数作为输入,该参数的内容为文件内容
  • loader 输出:return 一个返回值作为输出,该返回值为模块导出的字符串;loader 需要将返回值作为一个模块导出,才能更好的在webpack打包文件中使用,有三种导出方式;
    • (1)按照 ES Modules 方式导出
    • (2)按照 CommonJS 方式导出
    • (3)loader 处理类似于管道,可以串联多个 loader,可以直接将返回值交给下一个 loader 继续处理;
    // 自定义loader: // 功能:导入markdown文件,将markdown转换成html导出 // 插件:marked实现将markdown内容转换成html的功能 const marked = require(\‘marked\‘) // loader需要返回一段js代码:因为在webpack加载时会将这段代码拼接到打包代码中~ // 输入:function的参数作为输入值:这里是原有的markdown内容,source // 输出:return一个返回值作为输出:这里是转换成html的内容,html( // 输出注意:1、需要将返回值作为一个模块导出,才能更好的在webpack打包文件中使用 // 输出注意:2、 module.exports = source => { const html = marked(source) // webpack将loader加载后会将代码放到打包文件boundle.js中,一个loader对应一个(function(){}) 模块;所以在loader中需要导出 // webpack的打包文件boundle.js中,支持CommonJS的方式、ES Modules的方式导出 // loader的 // 1、CommonJS的方式:输出的模块转换为字符串的形式return // return `module.exports = ${JSON.stringify(html)}`//JSON.stringify转换html的换行符和空格 // 2、ES Modules:webpack内部会自动转换export default导出的代码 // return `export default ${JSON.stringify(html)}` // 3、直接返回html,再将结果交给html-loader处理(loader是管道的形式处理,可以串联) return html }
  • 使用自定义loader
  • module: { rules: [ {// 自定义loader,markdown-loader test: /.md$/, use: [ // 串联多个loader,执行顺序从下到上 \‘html-loader\‘, // 安装html-loader:npm install html-loader --save-dev \‘./markdown-loader.js\‘ // 自定义实现的loader ] }, ] },plugin原理,plugin的自定义实现plugin 用途

    用于资源加载以外的其他打包/压缩/文件处理等功能;

    plugin 插件机制(Hook 钩子机制)
    • 需要了解 taple 钩子:https://gitee.com/ymcdhr/e-demo/tree/master/webpack-source-code
    • webpack 钩子:https://webpack.docschina.org/api/compiler-hooks/#hooks
    plugin 实现原理,自定义实现:
  • plugin 是根据webpack生命周期的钩子机制进行开发的,plugin通过在钩子中挂载函数实现扩展;webpack钩子参考文档:https://webpack.docschina.org/api/compiler-hooks/#hooks
  • plugin 必须是一个函数,或者包含apply方法的对象
    • apply 方法有一个参数 compiler;
    • 通过 compiler 可以给 webpack 编译打包过程中添加钩子;
    • 通过钩子的回调函数 callback 拿到打包结果对象 compilation(通过compilation.assets 获取资源文件信息);
    • 然后对打包结果对象 compilation 进行修改;
    // 自定义plugin: // 功能:将js文件中的注释删除调 // 自定义插件 // 自定义插件必须是一个函数,或者包含apply方法的对象 // plugin根据webpack生命周期钩子函数开发的:https://webpack.docschina.org/api/compiler-hooks/#hooks // compiler.hooks可以访问钩子 // 功能:清除打包过程中的注释 class MyPlugin { apply (compiler){ console.log(\‘MyPlugin 启动\‘) // emit钩子的执行时机是:输出打包好的资源文件 asset 到 output 目录之前执行。 compiler.hooks.emit.tap(\‘MyPlugin\‘, compilation => { // compilation => 可以理解为此次打包的结果 // compilation.assets => 获取dist目录的所有生成的资源文件信息,例如:bundle.js for (const name in compilation.assets) { // console.log(name) // 获取到资源的内容,例如:bundle.js里面的内容 console.log(compilation.assets[name].source()) // 判断文件是否为js文件 if (name.endsWith(\‘.js\‘)) { // 替换掉js文件中的注释 const contents = compilation.assets[name].source() const withoutComments = contents.replace(/\\/\\*\\*+\\*\\//g, \‘\‘) // 覆盖原有内容 compilation.assets[name] = { source: () => withoutComments, // 新的内容 size: () => withoutComments.length // 内容的大小,webpack必须的方法 } } } }) } } module.exports = MyPlugin
  • 在 webpack.config.js 配置中引入插件
  • const MyPlugin = require(\‘./comment-plugin.js\‘) module.exports = { // ... plugins: [ new MyPlugin() // 自定义插件 ] }

    特别鸣谢:拉勾教育前端高薪训练营

    前端工程化7:自定义实现Webpack中的Loader和Plugin

    欢迎分享,转载请注明来源:内存溢出

    原文地址: http://outofmemory.cn/zaji/1006815.html

    (0)
    打赏 微信扫一扫 微信扫一扫 支付宝扫一扫 支付宝扫一扫
    上一篇 2022-05-22
    下一篇 2022-05-22

    发表评论

    登录后才能评论

    评论列表(0条)

    保存