webpack的优点

webpack从配置的入口出发,可以打包所有前端资源,同时可以配置多种loader来处理不同类型文件的转换,并且可以配置plugin来扩展模块打包流程,满足更多构建中特殊的需求,开发过程中还可以使用HMR提升本地开发效率和体验,生产环境中可以利用代码压缩和代码分割来提升前端加载性能,总之就是既可以提升开发效率,又可以提升应用性能。

webpack中loader和plugin的区别

webpack中loader主要用于处理非JavaScript模块的转换,在固定的阶段中使用,本身只是一个函数,返回转换后的结果,因为webpack只能处理js;而plugin是用于处理特殊的构建需求,比如将css代码单独输出为一个文件、定义环境中的变量等,利用了webpack的hooks介入构建过程中不同的阶段,可以定制项目的构建流程。

开始编译,读取webpack配置,创建NormalModuleFactory,创建NormalModule(使用resolveLoader解析loader路径),开始编译模块(loader-runner)

如何利用webpack提升应用性能

webpack优化性能大概有三种方式:

代码压缩、代码分割、去除无用代码,主要的方向是减少请求体积,代码分割有的情况下还可以利用浏览器缓存,减少请求次数

  1. 代码压缩(主要就减少请求体积)

    我们可以对optimization下的minimize和minimizer配置项进行设置,配置TerserPlugin对js代码进行压缩处理,还可以使用插件如HTMLWebpackPlugin对html文件进行压缩。
  2. 代码分割(既减少一次的请求体积,使请求返回更快,有的情况还可以利用浏览器缓存,减少请求次数)

    我了解的大概几种方式,第一种是设置optimization下的splitChunks配置项、第二种css代码利用MiniCssExtractPlugin插件单独生成文件、第三是利用webpack的dllPlugin插件将第三方库打包成独立的文件。

    splitChunks可以将模块抽离为单独的文件,chunks可以设置为all/async/inital三个值的其中一个,all就是所有的模块都打包到一个chunk,async是把异步加载的模块打包到chunk中,如通过动态import加载的模块,initial是把同步加载的模块打包到chunk中。可以配合按需加载使用,按需加载使用ES动态加载语法import来加载模块,webpack会自动处理使用这种语法编写的模块,把模块单独分离成文件,可以减少大型应用初始化时需要加载的前端资源,提升用户体验。

    css代码利用plugin插件生成单独的文件,可以在后续请求中,利用浏览器缓存,如果是多页面应用,优点更明显,不用多次加载css。

    dllPlugin也是将部分模块抽离成单独的文件,但是它和splitChunks不同,在代码不变的情况下不用重复打包,可以单独写一个配置文件,运行打包,在后续项目的构建流程直接使用DLLReferencePlugin引用文件就可以,通常可以用来处理不太变动的第三方库,可以看出来这样不仅可以利用浏览器缓存,还能提高开发效率。
  3. 去除无用代码(减少请求体积)

    可以利用tree-shaking、还有sideEffects,将未使用的代码移除。

    要利用到tree-shaking就要使用分别导入、而不是整体导入,未引入和未使用的模块方法就不会被打包,sideEffects对没有副作用的模块也可以将模块中未使用到的代码不进行打包。

    还有webpack的IgnorePlugin插件,可以在打包中忽略掉某些依赖包中体积大但又不太需要的文件,如react脚手架生成的项目中就默认将moment的locale文件夹整个忽略掉,这个语言包会非常大,但是通常实际中不需要这些多语言的配置,单独引入需要的语言就可以。

webpack的热更新原理

热更新HMR就是不用刷新页面而将新变更的模块替换掉旧的模块,避免了频繁手动刷新页面、应用状态丢失,也减少了页面刷新时的等待。它的核心是客户端去服务端拉取更新后的文件。在DevServer开启hot后,webpack会往应用代码中添加websocket相关的代码,用于和服务器保持连接,等待更新动作,本地代码变更时通知浏览器做相应的处理;webpack还会往应用代码中添加HMR运行时的代码,用于定义应用更新时的API。当有更新时,webpack-dev-server发送更新信号给HMR运行时,然后HMR再请求所需要的更新数据,服务端返回一个json包含所有要更新的模块的hash值,对应模块再次请求获取到最新的模块代码,没有问题的话就进行应用更新。

应用更新的API常见的有module.hot.accept、module.hot.decline、module.hot.dispose等,accept是在应用特定代码模块更新时执行相应的callback;decline是对于指定的代码模块,拒绝进行更新;dispose用于添加一个处理函数,在模块代码被替换时运行(可用于移除之前添加的持久化资源或者相关状态)。

如何优化webpack的构建速度

总的来说方向就是减少webpack的工作量。

  • 首先在开发环境下使用配置mode为develpment,webpack本身就默认不配置一些压缩优化的插件,这样可以减少在优化操作上的时间消耗;
  • 其次提前处理一些文件资源,如使用imagemin或者其他工具提前压缩好图片,可以减少在图片处理上的耗时,一些不频繁更新的第三方库使用dllPlugin打包,在项目中直接引用,不打包到应用代码中,也可以大大减少构建所用时间;
  • 还可以通过配置resolve,设置适合的extensions、modules、mainFields、mainFiles的值,减少模块解析时路径的查询范围,配置module的rules使用loader处理不同的文件时,通过include和exclude限制处理范围,减少耗时;
  • 另外还可以使用thread-loader利用多进程加速loader执行,利用tree-shaking减少webpack处理打包的代码量,利用缓存提升二次构建速度,像babel-loader、terser-webpack-plugin都可以开启缓存。
  • 生产环境还可以配置devtool不输出sourcemap。
  • 如果项目非常大,涉及代码模块过多,在合适的情况下也可以根据一定的粒度,把不同的业务代码拆分到不同的代码库去维护和管理,减少webpack处理的代码量。

如何开发一个webpack的plugin

plugin的实现可以是一个类或者函数,使用时传入相关配置来创建一个实例,plugin实例最重要的方法就是apply,在webpack compiler安装插件时会被调用,接收webpack的compiler对象实例的引用作为参数,在compiler对象实例上我们可以注册各种事件钩子函数hooks,在compiler的有些hooks中,还可以获取到compilation对象实例,在compilation对象实例上注册各种hooks,我们可以通过注册各种hooks来影响webpack的所有构建流程,以便完成更多其他构建任务。

hooks可以简单分为同步和异步两种,同步类型的hooks只能使用tap来注册事件,异步的还可以使用tapPromise和tapAsync来注册。

本地开发plugin,可以使自定义plugin对外暴露一个类,然后在webpack配置文件中引入,运行webpack构建查看结果就可以,可以使用node命令进行调试。

compiler一些hooks:entryOption、beforeRun、emit、compilation、thisCompilation、make(compilation完成编译后执行)、shouldEmit(控制是否输出对应的构建结果)、assetEmitted(在构建结果输出之后执行,可以获取输出内容的相关信息)、done、failed(构建失败时执行)

compilation一些hooks:buildModule、finishModules、chunkAsset(chunk 对应的一个输出资源添加到compilation时执行)、processAssets

如何开发一个webpack的loader

webpack loader本质就是一个实现转换功能的函数,接收content、map、meta三个参数。content就是要进行转化的资源内容,可以是字符串或者buffer,如图片、字体等文件,map是sourcemap对象。

通常webpack loader都是基于一个实现核心功能的类库来开发的,如果直接return一个值,这个值就是转换后的内容,如果要返回sourcemap对象或者其他数据,或是抛出一个异常,需要使用this.callback(err, content, map, meta)来传递这些数据;有些loader在执行过程中可能依赖外部I/O的结果,就需要使用异步的方式来处理,在loader执行时调用this.async()来标识该loader是异步处理的,this.async()会返回一个函数,然后我们可以调用这个函数用于返回loader的处理结果。

使用本地开发的loader有两种方式:一种是配置loader时使用本地的路径;另一种是在loader路径解析中加入本地开发loader的目录,具体是在loader所在目录下添加package.json文件并配置name字段,然后配置resolveLoader的modules将loader所在目录的路径添加进去,并在配置loader时使用package.json中name的值,这种比较适合多个loader的情况。

官方提供的一个工具库loader-utils可以帮助我们获取给loader传递的options,我们还可以使用官方提供的schema-utils对传入的options进行校验。

Webpack相关知识点的更多相关文章

  1. UITableView相关知识点

    //*****UITableView相关知识点*****// 1 #import "ViewController.h" // step1 要实现UITableViewDataSou ...

  2. Android开发涉及有点概念&相关知识点(待写)

    前言,承接之前的 IOS开发涉及有点概念&相关知识点,这次归纳的是Android开发相关,好废话不说了.. 先声明下,Android开发涉及概念比IOS杂很多,可能有很多都题不到的.. 首先由 ...

  3. IOS开发涉及有点概念&相关知识点

    前言,IOS是基于UNIX的,用C/C+/OC直通系统底层,不想android有个jvm. 首先还是系统架构的分层架构 1.核心操作系统层 Core OS,就是内存管理.文件系统.电源管理等 2.核心 ...

  4. IOS之UI--小实例项目--添加商品和商品名(使用xib文件终结版) + xib相关知识点总结

    添加商品和商品名小项目(使用xib文件终结版) 小贴士:博文末尾有项目源码在百度云备份的下载链接. xib相关知识点总结 01-基本使用 一开始使用xib的时候,如果要使用自定义view的代码,就需要 ...

  5. 学习记录013-NFS相关知识点

    一.NFS相关知识点 1.NFS常用的路径/etc/exports NFS服务主配置文件,配置NFS具体共享服务的地点/usr/sbin/exportfs NFS服务的管理命令,exportfs -a ...

  6. TCP/IP 相关知识点与面试题集

    第一部分:TCP/IP相关知识点 对TCP/IP的整体认 链路层知识点 IP层知识点 运输层知识点 应用层知识点 (这些知识点都可以参考:http://www.cnblogs.com/newwy/p/ ...

  7. Python开发一个csv比较功能相关知识点汇总及demo

    Python 2.7 csv.reader(csvfile, dialect='excel', **fmtparams)的一个坑:csvfile被csv.reader生成的iterator,在遍历每二 ...

  8. Caffe学习系列(二)Caffe代码结构梳理,及相关知识点归纳

    前言: 通过检索论文.书籍.博客,继续学习Caffe,千里之行始于足下,继续努力.将自己学到的一些东西记录下来,方便日后的整理. 正文: 1.代码结构梳理 在终端下运行如下命令,可以查看caffe代码 ...

  9. php正则相关知识点

    关于正则,其实简单就是搜索和匹配.php,java,python等都是支持正则的,php正则兼容perl.好多同学觉得正则比较难,比较抽象,其实正则是非常简单的,主要是一个熟悉和反复练习的结果,还有一 ...

  10. MySQL自增列(AUTO_INCREMENT)相关知识点总结

      MySQL的自增列(AUTO_INCREMENT)和其它数据库的自增列对比,有很多特性和不同点(甚至不同存储引擎.不同版本也有一些不同的特性),让人感觉有点稍微复杂.下面我们从一些测试开始,来认识 ...

随机推荐

  1. 【更新】【解决中文文件名乱码】mac一键获取最新datagrid 2017.3注册码到剪贴板

    背景与前版实现请见: 前版原文 需要the unarchiver 解决中文文件名在mac上创建文件异常. 代码调整 IDEA_JIHUOMA_HOME="/tmp/idea-jihuoma& ...

  2. 青少年CTF平台-Web-Robots

    题目信息 题目名称:Robots 题目描述:昨天十三年社团讲课,讲了Robots.txt的作用,小刚上课没有认真听课正在着急,你能不能帮帮忙? 题目难度:一颗星 解题过程 访问题目链接 在这里插入图片 ...

  3. 压测工具sysbench的使用

    前言 sysBench是一个模块化的.跨平台.多线程基准测试工具,主要用于评估测试各种不同系统参数下的数据库负载情况.sysbench提供如下测试: (1)CPU性能 (2)磁盘IO性能 (3)调度程 ...

  4. svg动画 - 波浪动画

    波浪 <path d="M 96.1271 806.2501 C 96.1271 806.2501 241.441 755.7685 384.5859 755.7685 C 529.8 ...

  5. 【matplotlib基础】--画布

    Matplotlib 库是一个用于数据可视化和绘图的 Python 库.它提供了大量的函数和类,可以帮助用户轻松地创建各种类型的图表,包括直方图.箱形图.散点图.饼图.条形图和密度图等. 使用 Mat ...

  6. 使用API数据接口获取商品详情数据的流程

    API数据接口是开发者获取第三方平台数据的一种方式,使用API接口可以快速地获取海量的商品详情数据,相比其他方式更加高效.实时.下面将介绍使用API数据接口获取商品详情数据的主要流程和步骤: 申请AP ...

  7. C# 使用Windows身份验证连接Sql Server

    C# 使用Windows身份验证连接Sql Server 使用Windows身份验证连接Sql Server 的字符串为: server=.;database=test_user;Trusted_Co ...

  8. warning in ./src/router/index.js (Emitted value instead of an instance of Error) Error compiling template: Uncaught (in promise) TypeError: Cannot set properties of undefined (setting 'jsoninfo'

    目录 warning in ./src/router/index.js (Emitted value instead of an instance of Error) Error compiling ...

  9. Python并发编程——paramiko远程控制的模块、病毒攻击原理、dll注入、

    文章目录 paramiko模块 作业 攻击原理解析 一.什么是dll 二.为何要有dll 什么是dll注入: 什么时候需要dll注入 dll注入的方法 使用SetWindowsHookEx函数对应用程 ...

  10. frida动态插桩初探

    前言 近期碰到了分析app的需求,就学习了一下 frida的动态插桩技术.frida是一款轻量级HOOK框架,可用于多平台上,例如android.windows.ios等.frida分为两部分,服务端 ...