博客
电影
宝箱
友链
关于
<
关于Apple ID地区与iCloud地区的问题
Webpack自动更新php静态资源文件名hash
>
Webpack深入浅出plugin
作者:
Cifer
类别: 技术
时间:2019-10-14 12:15:08
字数:7272
版权所有,未经允许,请勿转载,谢谢合作~
#### plugin 概念 Webpack核心库是tapable,它提供了各类钩子,事件都可以挂载,而Plugin则可以监听这些事件,并且获取及修改输出结果,便得webpack变得可定制,功能异常强大。 #### plugin 使用 只需要在webpack.config.js ```javascript const webpack = require('webpack'); const { CleanWebpackPlugin } = require('clean-webpack-plugin'); const FilterCreatePlugin = require('./src/plugins/filter-create-plugin') module.exports = { plugins: [ new webpack.ProgressPlugin(), new CleanWebpackPlugin(), new FilterCreatePlugin(), ] }; ``` plugin一般有三种来源: webpack的内置插件 npm安装 本地自定义plugin 上述例子刚好各自列举了一个。 #### webpack有哪些plugin ##### 内置plugin 其中webpack内置插件在./node_modules/webpack/lib/webpack.js里可以找到: ```javascript exportPlugins(exports, { AutomaticPrefetchPlugin: () => require("./AutomaticPrefetchPlugin"), BannerPlugin: () => require("./BannerPlugin"), CachePlugin: () => require("./CachePlugin"), ContextExclusionPlugin: () => require("./ContextExclusionPlugin"), ContextReplacementPlugin: () => require("./ContextReplacementPlugin"), DefinePlugin: () => require("./DefinePlugin"), Dependency: () => require("./Dependency"), DllPlugin: () => require("./DllPlugin"), DllReferencePlugin: () => require("./DllReferencePlugin"), EnvironmentPlugin: () => require("./EnvironmentPlugin"), EvalDevToolModulePlugin: () => require("./EvalDevToolModulePlugin"), EvalSourceMapDevToolPlugin: () => require("./EvalSourceMapDevToolPlugin"), ExtendedAPIPlugin: () => require("./ExtendedAPIPlugin"), ExternalsPlugin: () => require("./ExternalsPlugin"), HashedModuleIdsPlugin: () => require("./HashedModuleIdsPlugin"), HotModuleReplacementPlugin: () => require("./HotModuleReplacementPlugin"), IgnorePlugin: () => require("./IgnorePlugin"), LibraryTemplatePlugin: () => require("./LibraryTemplatePlugin"), LoaderOptionsPlugin: () => require("./LoaderOptionsPlugin"), LoaderTargetPlugin: () => require("./LoaderTargetPlugin"), MemoryOutputFileSystem: () => require("./MemoryOutputFileSystem"), Module: () => require("./Module"), ModuleFilenameHelpers: () => require("./ModuleFilenameHelpers"), NamedChunksPlugin: () => require("./NamedChunksPlugin"), NamedModulesPlugin: () => require("./NamedModulesPlugin"), NoEmitOnErrorsPlugin: () => require("./NoEmitOnErrorsPlugin"), NormalModuleReplacementPlugin: () => require("./NormalModuleReplacementPlugin"), PrefetchPlugin: () => require("./PrefetchPlugin"), ProgressPlugin: () => require("./ProgressPlugin"), ProvidePlugin: () => require("./ProvidePlugin"), SetVarMainTemplatePlugin: () => require("./SetVarMainTemplatePlugin"), SingleEntryPlugin: () => require("./SingleEntryPlugin"), SourceMapDevToolPlugin: () => require("./SourceMapDevToolPlugin"), Stats: () => require("./Stats"), Template: () => require("./Template"), UmdMainTemplatePlugin: () => require("./UmdMainTemplatePlugin"), WatchIgnorePlugin: () => require("./WatchIgnorePlugin") }); exportPlugins((exports.dependencies = {}), { DependencyReference: () => require("./dependencies/DependencyReference") }); exportPlugins((exports.optimize = {}), { AggressiveMergingPlugin: () => require("./optimize/AggressiveMergingPlugin"), AggressiveSplittingPlugin: () => require("./optimize/AggressiveSplittingPlugin"), ChunkModuleIdRangePlugin: () => require("./optimize/ChunkModuleIdRangePlugin"), LimitChunkCountPlugin: () => require("./optimize/LimitChunkCountPlugin"), MinChunkSizePlugin: () => require("./optimize/MinChunkSizePlugin"), ModuleConcatenationPlugin: () => require("./optimize/ModuleConcatenationPlugin"), OccurrenceOrderPlugin: () => require("./optimize/OccurrenceOrderPlugin"), OccurrenceModuleOrderPlugin: () => require("./optimize/OccurrenceModuleOrderPlugin"), OccurrenceChunkOrderPlugin: () => require("./optimize/OccurrenceChunkOrderPlugin"), RuntimeChunkPlugin: () => require("./optimize/RuntimeChunkPlugin"), SideEffectsFlagPlugin: () => require("./optimize/SideEffectsFlagPlugin"), SplitChunksPlugin: () => require("./optimize/SplitChunksPlugin") }); exportPlugins((exports.web = {}), { FetchCompileWasmTemplatePlugin: () => require("./web/FetchCompileWasmTemplatePlugin"), JsonpTemplatePlugin: () => require("./web/JsonpTemplatePlugin") }); exportPlugins((exports.webworker = {}), { WebWorkerTemplatePlugin: () => require("./webworker/WebWorkerTemplatePlugin") }); exportPlugins((exports.node = {}), { NodeTemplatePlugin: () => require("./node/NodeTemplatePlugin"), ReadFileCompileWasmTemplatePlugin: () => require("./node/ReadFileCompileWasmTemplatePlugin") }); exportPlugins((exports.debug = {}), { ProfilingPlugin: () => require("./debug/ProfilingPlugin") }); exportPlugins((exports.util = {}), { createHash: () => require("./util/createHash") }); ``` 我们也可以在官方文档查找<a href="https://webpack.js.org/plugins/" target="_blank" ref="nofollow">https://webpack.js.org/plugins/</a> ,不过因为有很多已经抽出独立的npm包,所以上述并不一定都是内置的,以说明文档或原码为准。 ##### 第三方plugin 也可以使用第三方的plugin <a href="https://github.com/webpack-contrib/awesome-webpack#webpack-plugins" target="_blank" ref="nofollow">https://github.com/webpack-contrib/awesome-webpack#webpack-plugins</a> #### 自定义plugin 因为plugin是以监听勾子,注册事件,并更改输出结果,模板出下 ```javascript class MyPlugin { apply(compiler) { compiler.hooks.someHook.someTap('MyPlugin', compilation => { }); } } module.exports = MyPlugin ``` 相当于 ```javascript function MyPlugin() { } MyPlugin.prototype.apply = function(compiler) { compiler.hooks.someHook.someTap('MyPlugin', compilation => { }); } module.exports = MyPlugin ``` someHook是Compiler已有的钩子,如<a href="https://webpack.js.org/api/compiler-hooks/" target="_blank" ref="nofollow">https://webpack.js.org/api/compiler-hooks/</a> 。 其实我们知道,Compilation也有一堆钩子,如果我们需要把事件注册至该钩子中,需要包裹在compiler注册的事件内部,如: ```javascript class MyPlugin { apply(compiler) { compiler.hooks.someHook.someTap('MyPlugin', compilation => { compilation.hooks.someHook.tapAsync('MyPlugin', callback => { }) }); } } module.exports = MyPlugin ``` Compilation的钩子列表有<a href="https://webpack.js.org/api/compilation-hooks/" target="_blank" ref="nofollow">https://webpack.js.org/api/compilation-hooks/</a>,两者的钩子不一样。但两者的name可一样,比如都叫'MyPlugin',但是一定要保证compilation的钩子在Compiler钩子的compilation之后,否则在更早的Compiler钩子中,可能拿不到compilation对象。 还有就是不同的钩子参数不一样,以官方为准。 someTap又是什么呢? 它是由webpack核心库提供的插件类型,取值: tap 同步事件 tapAsync callback形式的异步事件 tapPromise Promise形式的异步事件 用以上三种不同的插件类型注册事件 ```javascript compiler.hooks.make.tap('MyPlugin', compilation => { }) compiler.hooks.make.tapAsync('MyPlugin', (compilation, callback) => { callback() }) compiler.hooks.make.tapPromise('MyPlugin', compilation => { return new Promise(resolve => setTimeout(resolve, 1)).then(() => { }) }) ``` #### 自定义plugin实例 <a href="https://www.boatsky.com/blog/92" target="_blank" ref="nofollow">Webpack自动更新php静态资源文件名hash</a> #### plugin 原码分析 ./node_modules/webpack/lib/webpack.js plugin引入 ```javascript const webpack = (options, callback) => { let compiler; if (Array.isArray(options)) { compiler = new MultiCompiler( Array.from(options).map(options => webpack(options)) ); } else if (typeof options === "object") { options = new WebpackOptionsDefaulter().process(options); compiler = new Compiler(options.context); compiler.options = options; if (options.plugins && Array.isArray(options.plugins)) { for (const plugin of options.plugins) { if (typeof plugin === "function") { plugin.call(compiler, compiler); } else { plugin.apply(compiler); } } } } } ``` plugin 原码没有太多的东西,只是为了执行plugin里面的apply,至于为什么这些钩子可以被运行,这部分留到以后讲tapable分析。
如果觉得有帮忙,您可以在本页底部留言。
相关推荐:
从youtube观看记录分析时长
Webpack自动更新php静态资源文件名hash
Webpack构建流程之源码分析
Webpack基于scss生成css独立文件
Webpack深入浅出loader
移动端浏览器真机调试的几种方法
接入台湾超商门店地址选择
ember入门教程
Ember之Handlebars模板引擎
Mac高频快捷键之前端篇
简述浏览器缓存之cookie
浏览器打开页面的过程中发生了什么
Git命令简化笔记
PHP实现微信JS-SDK权限验证
SQL快速运用指南
如何用正确的姿势写HTML
正则表达式实例解析
……
更多
<
关于Apple ID地区与iCloud地区的问题
Webpack自动更新php静态资源文件名hash
>
全部留言
我要留言
内容:
网名:
邮箱:
个人网站:
发表
全部留言