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() // 自定义插件 ]}
特地鸣谢:拉勾教育前端高薪训练营