详解基于DllPlugin和DllReferencePlugin的webpack构建优化

  

一个基于vue-cli webpack2模板创建的项目。项目中使用到了vue + vue-router + axios + muse-ui + iview
  现在构建一次需要的时间大概是40岁左右。真心受不了。虽然在开发过程中,我们不太需要关心构建时间。但是如果在开发hybridApp时,构建的次数就会增多。

  

一般我们可以把项目分为三部分。
  

  

           分类   说明   变动频率               vendor_library   核心库   低         供应商   一般项目依赖   中等         代码   业务逻辑   高            

  

vendor_library:比如vue, vue-router, axios这些变动频率极低的文件可以利用DllPlugin和DllReferencePlugin进行预编译。

  

厂商代码在开发阶段,每次构建都需要编译。但是一旦完成该次开发任务,应该调整供应商是否加入vendor_library。

  

<强> BundleAnalyzerPlugin的插件使用
  

  

BundleAnalyzerPlugin是分析Webpack生成的包体组成并且以可视化的方式反馈给开发者的插件。

  

详解基于DllPlugin和DllReferencePlugin的webpack构建优化

  

vue已经默认集成了该插件。如果你运行npm运行构建报告。就能看到当前项目的依赖情况,然后做出相应调整。

  


  

  

<强>按需加载
  

  

muse-ui、iview都提供了按需加载的方式,按照文档调整即可。
  

  

           分类   耗时   muse-ui   iview               之前   女士13256   234 kb   337 kb         后   女士43211   79 kb   75 kb            

  

先看结果……你没看错,“优化后的,时间竟然变长了…& # 128514;。不过这也正常,之前的依赖直接获取的是dist目录的文件,现在需要在src目录下获取。增加了编译的过程。
  

  

但是文件大小的减少还是喜人的。当然,这取决于项目中对模块的使用程度。在我们这个项目中iview只使用了的四个控件。结果上看,显然还是按需加载比较划算。不过这个不算是时间上的优化,只是因为dll可以解决构建时间问题,使按需加载变的更好用。

  

<强> DllPlugin和DllReferencePlugin预编译资源模块
  

  

Dll这个概念应该是借鉴了Windows系统的Dll。一个Dll包,就是一个纯纯的依赖库,它本身不能运行,是用来给你的应用引用的。
  

  

打包dll的时候,Webpack会将所有包含的库做一个索引,写在一个清单文件中,而引用dll的代码(dll用户)在打包的时候,只需要读取这个清单文件,就可以了。
  

  

这么一来有几个好处:
  

  

Dll打包以后是独立存在的,只要其包含的库没有增减,升级,哈希也不会变化,因此线上的Dll代码不需要随着版本发布频繁更新。
  

  

应用部分代码修改后,只需要编译应用部分的代码,dll部分,只要包含的库没有增减,升级,就不需要重新打包。这样也大大提高了每次编译的速度。
  

  

假设你有多个项目,使用了相同的一些依赖库,它们就可以共用一个dll。

  

网上抄的…其实意思就是我们可以把项目的公共模块,基本不会改动的模块。想我们刚才说的定义为vendor_library的内容,进行预编译编译。以后在项目构建过程中,vendor_library部分直接引用,就不需要再编译了。
  

  

这也是为什么按需加载可以得到更好的使用,正常构建流程,因为使用了按需加载,会导致每次的构建都比使用全量加载用时要长。而使用dll,核心库只需要编译一次,以后直接引用即可。

  

先来看一下改进结果:

  

           分类   耗时               之前   女士57192         后   7890毫秒            

  

哈哈,有没有快到飞起! ! !

  

<强> DllPlugin和DllReferencePlugin使用
  

  

新建webpack.dll.conf.js文件

     //webpack.dll.conf.js   过程。NODE_ENV=吧?   const path=要求(“路径”);   var跑龙套=要求(“/跑龙套。”)   var vueLoaderConfig=要求(“。/vue-loader.conf”)   var ExtractTextPlugin=要求(“extract-text-webpack-plugin”)   var OptimizeCSSPlugin=要求(“optimize-css-assets-webpack-plugin”)   const webpack=要求(“webpack”);//vue项目默认有一个静态目录。我就把导出目录放在了静态/dll目录下   const srcPath=路径。加入(__dirname“静态/dll/. ./?;//需要编译的模块   const供应商=[' vue/dist/vue.esm.js ',   “vue-router”,   “vue-localstorage”,   “material-design-icons/iconfont material-icons.css’,   “iview/dist/风格/iview.css”,   “iview/src/组件/标签/tag.vue '   “muse-ui/src/appBar”   ];   webpackConfig={   条目:{   供应商:供应商   },   解决:{   扩展:['。js ', '。vue ', ' . json)   },   模块:{   加载器:(   {   测试:/\ .vue/美元,   装载机:“vue-loader”,   选择:vueLoaderConfig   },   {   测试:/iview.src。* & # 63; js/美元,   装载机:“babel-loader”   },   {   测试:/muse-ui.src。* & # 63; js/美元,   装载机:“babel-loader”   },   {   测试:/\ . css/美元,   用途:ExtractTextPlugin.extract ({   使用“css-loader”:   })   },   {   测试:/\。(woff2& # 63; |测试结束| ttf |传递| svg)(\ & # 63;。*) & # 63;美元/,   装载机:“url-loader”,   选择:{   publicPath:“。/?   限制:1000   名称:“字体/[名字][ext]。”   }   })   },   输出:{   路径:srcPath,//输出的路径   文件名:“[名字]. dll。js ',//输出的文件,将会根据条目命名为vendor.dll.js   图书馆:“[名字]_library”//暴露出的全局变量名   },   插件:[   新ExtractTextPlugin ({   文件名:“[名字].dll.css”   }),   新OptimizeCSSPlugin ({   cssProcessorOptions: {   安全:真   }   }),   新的webpack.optimize。UglifyJsPlugin ({//uglifjs压缩   压缩:{   警告:假   }   }),   新webpack.DllPlugin ({   路径:路径。加入(srcPath[名字]-mainfest.json),//描述依赖对应关系的json文件   名称:“[名字]_library”,   背景:__dirname//执行的上下文环境,对之后DllReferencePlugin有用   })   ]   }   如果(process.env.npm_config_report) {   var BundleAnalyzerPlugin=需要.BundleAnalyzerPlugin (“webpack-bundle-analyzer”)   webpackConfig.plugins。推动(新BundleAnalyzerPlugin ())   }   模块。出口=webpackConfig;   

详解基于DllPlugin和DllReferencePlugin的webpack构建优化