webpack的优势从配置入口开始,webpack可以打包所有前端资源。同时可以配置多个loader处理不同类型文件的转换,可以配置plugins扩展模块打包流程,满足更多需求。对于建设中的特殊需求,也可以在开发过程中使用HMR,提升本地开发效率和体验。在生产环境中,可以通过代码压缩和代码分割来提升前端加载性能。总之,它不仅可以提高开发效率,还可以提高应用程序的性能。webpack中loader和plugin的区别webpack中的loader主要用来处理非JavaScript模块的转换。它用于固定阶段。它只是一个函数,返回转换后的结果,因为webpack只能处理js;而plugin是用来处理特殊的构建需求,比如将css代码输出为单个文件,在环境中定义变量等,webpack的hooks用于介入构建过程的不同阶段,构建项目的流程可以定制。开始编译,读取webpack配置,创建NormalModuleFactory,创建NormalModule(使用resolveLoader解析loader路径),开始编译模块(loader-runner)如何使用webpack提升应用性能优化webpack性能大致有3种方式:代码压缩,代码分割,去除无用代码,主要方向是减小请求大小。在某些情况下,代码分割还可以使用浏览器缓存来减少请求次数。代码压缩(主要是减少请求大小)我们可以在优化下设置minimize和minimizer配置项。配置TerserPlugin压缩js代码,也可以使用HTMLWebpackPlugin等插件压缩html文件。代码拆分(减小请求的大小,使请求返回更快,在某些情况下,使用浏览器缓存来减少请求数)我知道有几种方法,第一种是在优化下设置splitChunks配置项,第二种css代码使用MiniCssExtractPlugin插件单独生成文件,第三种使用webpackdllPlugin插件将第三方库打包成独立文件。splitChunks可以将模块提取到单独的文件中,chunks可以设置为all/async/inital三个值之一,all表示将所有模块打包成一个chunk,async表示将异步加载的模块打包成chunk,对于例如,对于动态导入加载的模块,初始是将同步加载的模块打包成块。它可以与按需加载一起使用。按需加载使用ES动态加载语法import来加载模块。Webpack会自动处理使用这种语法编写的模块,并将模块分离成文件,可以减少大型应用程序初始化时需要加载的前端资源。,提升用户体验。css代码使用插件生成一个单独的文件,可以在后续请求中被浏览器缓存。如果是多页面应用,优势更明显,不需要多次加载css。dllPlugin也会将一些模块提取到单独的文件中,但它与splitChunks不同。在代码不变的情况下不需要重复打包。可以单独写一个配置文件,运行打包,在后续工程构建过程中直接使用DLLReferencePlugin引用文件。是的,它通常可以用来处理变化不大的第三方库。可见,这样既可以利用浏览器缓存,又可以提高开发效率。删除无用代码(减少请求大小)可以使用tree-shaking和sideEffects来删除无用代码。要利用tree-shaking,您必须使用单独的导入而不是整体导入。未引入和未使用的模块方法将不会被打包。SideEffects还可以在没有副作用的模块中解压未使用的代码。.还有webpack的IgnorePlugin插件,可以在打包时忽略依赖包中一些大但不需要的文件。比如在react脚手架生成的项目中,默认会忽略moment的locale文件夹。这个语言包会很大,但是通常实际中不需要这些多语言的配置,需要的语言可以单独导入。webpackHotupdateHMR的热更新原理是在不刷新页面的情况下,用新更改的模块替换旧模块,避免频繁的手动页面刷新,应用状态丢失,减少页面刷新时的等待时间。其核心是客户端去服务端拉取更新后的文件。DevServer热启动后,webpack会在应用代码中添加websocket相关代码,与服务器保持连接,等待更新动作,当本地代码发生变化时通知浏览器做相应处理;webpack还会在应用程序更新时将HMR添加到定义API的应用程序代码Runtime代码中。当有更新时,webpack-dev-server在运行时向HMR发送更新信号,然后HMR请求需要的更新数据,服务器返回一个包含所有待更新模块的hash值的json,并对应模块请求获取最新模块代码如果没有问题,更新应用。常见的应用更新API有module.hot.accept、module.hot.decline、module.hot.dispose等,accept是在应用特定代码模块更新时执行相应的回调;decline是拒绝指定代码模块的Update;dispose用于添加一个处理函数,该函数在替换模块代码时运行(可用于删除先前添加的持久性资源或相关状态)。如何优化webpack的构建速度一般来说方向是减少webpack的工作量。第一,在开发环境中使用配置方式asdevelopment,webpack本身默认没有配置一些压缩优化插件,可以减少优化操作的时间消耗;其次,提前对一些文件资源进行处理,比如使用imagemin或者其他工具提前压缩图片,可以减少图片处理的耗时。一些不经常更新的第三方库用dllPlugin打包,在项目中直接引用,无需打包到应用代码中,也可以大大减少构建的时间;还可以配置resolve,设置合适的extensions,modules,mainFields,mainFiles值,减少模块解析时路径的查询范围,配置模块的规则,使用loader处理不同的文件,限制处理范围通过包含和排除,减少耗时;另外,可以使用thread-loader使用多进程加速loader执行,使用tree-shaking减少webpack打包的代码量,使用cache提高二次构建速度。例如,babel-loader和terser-webpack-plugin可以启用缓存。生产环境也可以配置devtool不输出sourcemap。如果项目很大,涉及到的代码模块过多,可以在适当的情况下,将不同的业务代码按照一定的粒度拆分到不同的代码库中进行维护管理,减少webpack处理的代码量。如何开发一个webpackpluginplugin的实现可以是类也可以是函数,使用时传入相关配置创建实例。插件实例最重要的方法是apply,当webpack编译器安装插件并接收到webpack编译器对象实例的引用作为参数时会调用该方法。我们可以在编译器对象实例上注册各种事件钩子函数钩子。在编译器的一些钩子中,我们也可以获得编译对象实例。在编译对象实例上注册各种钩子。我们可以通过注册各种钩子来影响webpack的所有构建过程,从而完成更多其他的构建任务。Hooks可以简单的分为同步和异步两种。同步钩子只能使用tap来注册事件,异步钩子也可以使用tapPromise和tapAsync来注册。本地开发插件,可以让自定义插件对外暴露一个类,然后在webpack配置文件中引入,运行webpack构建查看结果,使用node命令调试。一些编译器钩子:entryOption、beforeRun、emit、compilation、thisCompilation、make(编译完成后执行)、shouldEmit(控制是否输出对应的构建结果)、assetEmitted(构建结果输出后执行,可获取相关信息关于输出内容),done,failed(build失败时执行)编译的一些hooks:buildModule,finishModules,chunkAsset(当一个chunk对应的输出资源加入编译时执行),processAssets如何开发一个webpackloader的webpackloader的本质是一个功能,实现了转换功能,接收content,map,meta三个参数。content是要转换的资源内容,可以是字符串或者buffer,比如图片、字体等文件,map是sourcemap对象。通常webpackloader是基于一个实现核心功能的类库来开发的。如果直接返回一个值,这个值就是转换后的内容。如果你想返回一个sourcemap对象或者其他数据,或者抛出异常,你需要使用这个.callback(err,content,map,meta)来传递这些数据;有些loader在执行过程中可能会依赖外部I/O的结果,因此需要对其进行异步处理,而在执行loader时会调用this.async()来标识loader是异步处理的,this.async()会返回一个函数,然后我们可以调用这个函数返回加载器的处理结果。使用本地开发的加载器有两种方式:一种是在配置加载器时使用本地路径;另一种是在loader路径分析中添加本地开发的loader的目录,具体是在loader所在目录下添加package.json文件并配置name字段,然后配置resolveLoader模块添加该目录的路径loader所在位置,配置loader时使用package.json中name的值,更适合多个loader。一个官方的工具库loader-utils可以帮助我们获取传递给loader的选项,我们也可以使用官方提供的schema-utils来验证传入的选项。
