当前位置: 首页 > news >正文

东湖南昌网站建设公司手机网站功能

东湖南昌网站建设公司,手机网站功能,个人网站建设架构,网站的下载二维码怎么做Plugin 的作用 通过插件我们可以扩展 webpack#xff0c;加入自定义的构建行为#xff0c;使 webpack 可以执行更广泛的任务#xff0c;拥有更强的构建能力。 Plugin 工作原理 webpack 就像一条生产线#xff0c;要经过一系列处理流程后才能将源文件转换成输出结果。 这条…Plugin 的作用 通过插件我们可以扩展 webpack加入自定义的构建行为使 webpack 可以执行更广泛的任务拥有更强的构建能力。 Plugin 工作原理 webpack 就像一条生产线要经过一系列处理流程后才能将源文件转换成输出结果。 这条生产线上的每个处理流程的职责都是单一的多个流程之间有存在依赖关系只有完成当前处理后才能交给下一个流程去处理。 插件就像是一个插入到生产线中的一个功能在特定的时机对生产线上的资源做处理。webpack 通过 Tapable 来组织这条复杂的生产线。 webpack 在运行过程中会广播事件插件只需要监听它所关心的事件就能加入到这条生产线中去改变生产线的运作。 webpack 的事件流机制保证了插件的有序性使得整个系统扩展性很好。 ——「深入浅出 Webpack」 站在代码逻辑的角度就是webpack 在编译代码过程中会触发一系列 Tapable 钩子事件插件所做的就是找到相应的钩子往上面挂上自己的任务也就是注册事件这样当 webpack 构建的时候插件注册的事件就会随着钩子的触发而执行了。 Webpack 内部的钩子 什么是钩子 钩子的本质就是事件。为了方便我们直接介入和控制编译过程webpack 把编译过程中触发的各类关键事件封装成事件接口暴露了出来。这些接口被很形象地称做hooks钩子。开发插件离不开这些钩子。 Tapable Tapable 为 webpack 提供了统一的插件接口钩子类型定义它是 webpack 的核心功能库。webpack 中目前有十种 hooks在 Tapable 源码中可以看到他们是 // https://github.com/webpack/tapable/blob/master/lib/index.js exports.SyncHook require(./SyncHook); exports.SyncBailHook require(./SyncBailHook); exports.SyncWaterfallHook require(./SyncWaterfallHook); exports.SyncLoopHook require(./SyncLoopHook); exports.AsyncParallelHook require(./AsyncParallelHook); exports.AsyncParallelBailHook require(./AsyncParallelBailHook); exports.AsyncSeriesHook require(./AsyncSeriesHook); exports.AsyncSeriesBailHook require(./AsyncSeriesBailHook); exports.AsyncSeriesLoopHook require(./AsyncSeriesLoopHook); exports.AsyncSeriesWaterfallHook require(./AsyncSeriesWaterfallHook); exports.HookMap require(./HookMap); exports.MultiHook require(./MultiHook); Plugin 构建对象 Compiler compiler 对象中保存着完整的 Webpack 环境配置每次启动 webpack 构建时它都是一个独一无二仅仅会创建一次的对象。 这个对象会在首次启动 Webpack 时创建我们可以通过 compiler 对象上访问到 Webapck 的主环境配置比如 loader 、 plugin 等等配置信息。 它有以下主要属性 compiler.options 可以访问本次启动 webpack 时候所有的配置文件包括但不限于 loaders 、 entry 、 output 、 plugin 等等完整配置信息。compiler.inputFileSystem 和 compiler.outputFileSystem 可以进行文件操作相当于 Nodejs 中 fs。compiler.hooks 可以注册 tapable 的不同种类 Hook从而可以在 compiler 生命周期中植入不同的逻辑。 compiler hooks 文档 Compilation compilation 对象代表一次资源的构建compilation 实例能够访问所有的模块和它们的依赖。 一个 compilation 对象会对构建依赖图中所有模块进行编译。 在编译阶段模块会被加载(load)、封存(seal)、优化(optimize)、 分块(chunk)、哈希(hash)和重新创建(restore)。 它有以下主要属性 compilation.modules 可以访问所有模块打包的每一个文件都是一个模块。compilation.chunks chunk 即是多个 modules 组成而来的一个代码块。入口文件引入的资源组成一个 chunk通过代码分割的模块又是另外的 chunk。compilation.assets 可以访问本次打包生成所有文件的结果。compilation.hooks 可以注册 tapable 的不同种类 Hook用于在 compilation 编译模块阶段进行逻辑添加以及修改。 compilation hooks 文档 开发一个插件 最简单的插件 plugins/test-plugin.js class TestPlugin {constructor() {console.log(TestPlugin constructor());}// 1. webpack读取配置时new TestPlugin() 会执行插件 constructor 方法// 2. webpack创建 compiler 对象// 3. 遍历所有插件调用插件的 apply 方法apply(compiler) {console.log(TestPlugin apply());} }module.exports TestPlugin; 注册 hook class TestPlugin {constructor() {console.log(TestPlugin constructor());}// 1. webpack读取配置时new TestPlugin() 会执行插件 constructor 方法// 2. webpack创建 compiler 对象// 3. 遍历所有插件调用插件的 apply 方法apply(compiler) {console.log(TestPlugin apply());// 从文档可知, compile hook 是 SyncHook, 也就是同步钩子, 只能用tap注册compiler.hooks.compile.tap(TestPlugin, (compilationParams) {console.log(compiler.compile());});// 从文档可知, make 是 AsyncParallelHook, 也就是异步并行钩子, 特点就是异步任务同时执行// 可以使用 tap、tapAsync、tapPromise 注册。// 如果使用tap注册的话进行异步操作是不会等待异步操作执行完成的。compiler.hooks.make.tap(TestPlugin, (compilation) {setTimeout(() {console.log(compiler.make() 111);}, 2000);});// 使用tapAsync、tapPromise注册进行异步操作会等异步操作做完再继续往下执行compiler.hooks.make.tapAsync(TestPlugin, (compilation, callback) {setTimeout(() {console.log(compiler.make() 222);// 必须调用callback();}, 1000);});compiler.hooks.make.tapPromise(TestPlugin, (compilation) {console.log(compiler.make() 333);// 必须返回promisereturn new Promise((resolve) {resolve();});});// 从文档可知, emit 是 AsyncSeriesHook, 也就是异步串行钩子特点就是异步任务顺序执行compiler.hooks.emit.tapAsync(TestPlugin, (compilation, callback) {setTimeout(() {console.log(compiler.emit() 111);callback();}, 3000);});compiler.hooks.emit.tapAsync(TestPlugin, (compilation, callback) {setTimeout(() {console.log(compiler.emit() 222);callback();}, 2000);});compiler.hooks.emit.tapAsync(TestPlugin, (compilation, callback) {setTimeout(() {console.log(compiler.emit() 333);callback();}, 1000);});} }module.exports TestPlugin; 启动调试 通过调试查看 compiler 和 compilation 对象数据情况。 package.json 配置指令 {name: source,version: 1.0.0,scripts: {debug: node --inspect-brk ./node_modules/webpack-cli/bin/cli.js},keywords: [],author: xiongjian,license: ISC,devDependencies: {babel/core: ^7.17.10,babel/preset-env: ^7.17.10,css-loader: ^6.7.1,loader-utils: ^3.2.0,webpack: ^5.72.0,webpack-cli: ^4.9.2} } 运行指令 npm run debug此时控制台输出以下内容 PS C:\Users\86176\Desktop\source npm run debug source1.0.0 debugnode --inspect-brk ./node_modules/webpack-cli/bin/cli.jsDebugger listening on ws://127.0.0.1:9229/629ea097-7b52-4011-93a7-02f83c75c797 For help, see: https://nodejs.org/en/docs/inspecto 打开 Chrome 浏览器F12 打开浏览器调试控制台。 此时控制台会显示一个绿色的图标 调试控制台 点击绿色的图标进入调试模式。 在需要调试代码处用 debugger 打断点代码就会停止运行从而调试查看数据情况。 BannerWebpackPlugin 作用给打包输出文件添加注释。 开发思路: 需要打包输出前添加注释需要使用 compiler.hooks.emit 钩子, 它是打包输出前触发。 如何获取打包输出的资源compilation.assets 可以获取所有即将输出的资源文件。 实现 // plugins/banner-webpack-plugin.js class BannerWebpackPlugin {constructor(options {}) {this.options options;}apply(compiler) {// 需要处理文件const extensions [js, css];// emit是异步串行钩子compiler.hooks.emit.tapAsync(BannerWebpackPlugin, (compilation, callback) {// compilation.assets包含所有即将输出的资源// 通过过滤只保留需要处理的文件const assetPaths Object.keys(compilation.assets).filter((path) {const splitted path.split(.);return extensions.includes(splitted[splitted.length - 1]);});assetPaths.forEach((assetPath) {const asset compilation.assets[assetPath];const source /* * Author: ${this.options.author} */\n${asset.source()};// 覆盖资源compilation.assets[assetPath] {// 资源内容source() {return source;},// 资源大小size() {return source.length;},};});callback();});} }module.exports BannerWebpackPlugin; CleanWebpackPlugin 作用在 webpack 打包输出前将上次打包内容清空。 开发思路 如何在打包输出前执行需要使用 compiler.hooks.emit 钩子, 它是打包输出前触发。如何清空上次打包内容 获取打包输出目录通过 compiler 对象。通过文件操作清空内容通过 compiler.outputFileSystem 操作文件。 实现 // plugins/clean-webpack-plugin.js class CleanWebpackPlugin {apply(compiler) {// 获取操作文件的对象const fs compiler.outputFileSystem;// emit是异步串行钩子compiler.hooks.emit.tapAsync(CleanWebpackPlugin, (compilation, callback) {// 获取输出文件目录const outputPath compiler.options.output.path;// 删除目录所有文件const err this.removeFiles(fs, outputPath);// 执行成功err为undefined执行失败err就是错误原因callback(err);});}removeFiles(fs, path) {try {// 读取当前目录下所有文件const files fs.readdirSync(path);// 遍历文件删除files.forEach((file) {// 获取文件完整路径const filePath ${path}/${file};// 分析文件const fileStat fs.statSync(filePath);// 判断是否是文件夹if (fileStat.isDirectory()) {// 是文件夹需要递归遍历删除下面所有文件this.removeFiles(fs, filePath);} else {// 不是文件夹就是文件直接删除fs.unlinkSync(filePath);}});// 最后删除当前目录fs.rmdirSync(path);} catch (e) {// 将产生的错误返回出去return e;}} }module.exports CleanWebpackPlugin; AnalyzeWebpackPlugin 作用分析 webpack 打包资源大小并输出分析文件。 开发思路: 在哪做? compiler.hooks.emit, 它是在打包输出前触发我们需要分析资源大小同时添加上分析后的 md 文件。 实现 // plugins/analyze-webpack-plugin.js class AnalyzeWebpackPlugin {apply(compiler) {// emit是异步串行钩子compiler.hooks.emit.tap(AnalyzeWebpackPlugin, (compilation) {// Object.entries将对象变成二维数组。二维数组中第一项值是key第二项值是valueconst assets Object.entries(compilation.assets);let source # 分析打包资源大小 \n| 名称 | 大小 |\n| --- | --- |;assets.forEach(([filename, file]) {source \n| ${filename} | ${file.size()} |;});// 添加资源compilation.assets[analyze.md] {source() {return source;},size() {return source.length;},};});} }module.exports AnalyzeWebpackPlugin; InlineChunkWebpackPlugin 作用webpack 打包生成的 runtime 文件太小了额外发送请求性能不好所以需要将其内联到 js 中从而减少请求数量。 开发思路: 1、我们需要借助 html-webpack-plugin 来实现 在 html-webpack-plugin 输出 index.html 前将内联 runtime 注入进去删除多余的 runtime 文件 2、如何操作 html-webpack-plugin官方文档 实现 // plugins/inline-chunk-webpack-plugin.js const HtmlWebpackPlugin require(safe-require)(html-webpack-plugin);class InlineChunkWebpackPlugin {constructor(tests) {this.tests tests;}apply(compiler) {compiler.hooks.compilation.tap(InlineChunkWebpackPlugin, (compilation) {const hooks HtmlWebpackPlugin.getHooks(compilation);hooks.alterAssetTagGroups.tap(InlineChunkWebpackPlugin, (assets) {assets.headTags this.getInlineTag(assets.headTags, compilation.assets);assets.bodyTags this.getInlineTag(assets.bodyTags, compilation.assets);});hooks.afterEmit.tap(InlineChunkHtmlPlugin, () {Object.keys(compilation.assets).forEach((assetName) {if (this.tests.some((test) assetName.match(test))) {delete compilation.assets[assetName];}});});});}getInlineTag(tags, assets) {return tags.map((tag) {if (tag.tagName ! script) return tag;const scriptName tag.attributes.src;if (!this.tests.some((test) scriptName.match(test))) return tag;return { tagName: script, innerHTML: assets[scriptName].source(), closeTag: true };});} }module.exports InlineChunkWebpackPlugin;
http://www.w-s-a.com/news/739393/

相关文章:

  • 沧州哪里做网站网站的建设是什么
  • 设计公司海报秦皇岛seo网站推广
  • 网站导航规划wordpress做漫画
  • jsp体育用品网站建设wordpress 10万篇文章
  • 沈阳做微信和网站的公司网站在线支付接口
  • 重庆整合网络营销百度seo快速提升排名
  • 设计师网站外网百度分析工具
  • 旅游网站建设技术解决方案wordpress主题安装后找不到
  • 网站图片文字排版错误管理系统界面设计
  • 网站建设 台州广州惠科互联网技术有限公司
  • 网站页面尺寸大小四川鸿业建设集团网站
  • 做女朋友的网站局网站建设方案word
  • 做阿里国际网站会有成效吗科技网站有哪些
  • 高端公司网站建设北京两学一做网站
  • 黄埔网站建设设计wordpress 文件夹改名
  • 怎么什么软件可以吧做网站最火的二十个电商app
  • wordpress theme sage网站seo优化加推广
  • 建设一个大型电影网站公司网站建设工作总结
  • 传奇网站一般怎么做的宇泽佛山网站建设
  • google网站入口电商运营十大基础知识
  • 建设公司网站的细节中国建设网网站
  • 重庆美邦建网站宝安网页设计
  • 建网站的地址十堰做网站
  • 怎么评判一个网站做的好与坏专做情侣装网站
  • 网站管理助手v3历史上的今天 网站如何做
  • 网站建设与管理的就业方向网站开发前端模板
  • 对网站建设的维护深圳网络推广推荐
  • wordpress多站共享授权码wordpress数据库缓存插件
  • 建一个购物网站多少钱上海商标注册
  • 琪觅公司网站开发面点培训学校哪里有