一个基于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生成的包体组成并且以可视化的方式反馈给开发者的插件。
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构建优化