博客
关于我
强烈建议你试试无所不能的chatGPT,快点击我
结合vue-cli来谈webpack打包优化
阅读量:5746 次
发布时间:2019-06-18

本文共 4305 字,大约阅读时间需要 14 分钟。

一、按需加载

1.1、为什么需要按需加载

随着web应用功能越来越复杂,模块打包后体积越来越大,这样会带来两个问题:

  • 所有的js文件打包到一个bundle.js中导致首屏加载时间过长
  • 有时我们只是修改了一个模块就得重新打包所用的文件 webpack天然支持多种模块系统风格,支持灵活的代码分割

1.2、按需加载的三种方式

webpack支持三种代码分割方式分别是:

  • AMD: require(url, '别名')
  • CommonJS: require.ensure([],func),
  • ES6: import(url)

1.3、vue中如何按需加载

对应的vue中也有三种对应的解决方式:

  • vue异步组件技术
import Vue from 'vue'import Router from 'vue-router'Vue.use(Router)export default new Router({    mode: 'history',    routes: [        {            path: '/vue-async',            name: 'vueAsync',            component: resolve => require(['@/components/VueAsync'], resolve)        }    ]})复制代码
  • webpack提供的require.ensure()
import Vue from 'vue'import Router from 'vue-router'Vue.use(Router)export default new Router({    mode: 'history',    routes: [        {            path: '/require-ensure'            name: 'RequireEnsure',            component: r => require.ensure([], () => r(require('@/components/RequireEnsure'), 'ensure'))        }    ]})复制代码
  • 利用ES6提案的import()函数
import Vue from 'vue'import Router from 'vue-router'const EsImport = () => import('@/components/EsImport')Vue.use(Router)export default new Router({    mode: 'history',    routes: [    {        path: '/es-import',        name: 'EsImport',        component: EsImport    }]})复制代码

第三种方式比较简单,而且代码组织也比较明显,所以也更常被使用

二、合理使用commonsChunkPlugin

2.1、为什么使用commonsChunkPlugin

CommonsChunkPlugin 插件,是一个可选的用于建立一个独立文件(又称作 chunk)的功能,这个文件包括多个入口 chunk 的公共模块。简单来说CommonsChunkPlugin主要是用来提取第三方库和公共模块,避免首屏加载的bundle文件或者按需加载的bundle文件体积过大,从而导致加载时间过长,着实是优化的一把利器。

2.2、commonsPlugin的集中使用场景

  • 提取两个及两个以上 Chunk 的公共代码
  • 将 Code Split 切割出来的 Chunk「就是子 Chunk」,提取到父 Chunk
  • 将 Code Split 切割出来的 Chunk,提取到一个新的异步加载的 Chunk
  • 提取某个类似 jquery 或 react 的代码库「但是这个用得很少,使用用 dll 插件来打包会更好一些,一下篇介绍」

三、使用DllPlugin和DllReferencePlugin来提高打包速度

3.1、为什么使用DllPlugin和DllReferencePlugin

使用 CommonsChunkPlugin,设置 minChunks 为 Infinity 可用于打包此类代码,但缺点也是比较明显的:

  • 每次执行 webpack 时,都会去解析打包这些代码,耗时也耗资源
  • 如果设置了文件名 hash,一次构建生成一个新的hash,那这些文件即使没有变,文件名也会变,不利于缓存。 对于这些代码我是用 Dll 插件单独构建。

3.2、vue-cli中如何利用DllPlugin和DllReferencePlugin

  • 在build目录下编写webpack.dll.conf.js
const path = require('path')const webpack = require('webpack')const AssetsPlugin = require('assets-webpack-plugin')const CleanWebpackPlugin = require('clean-webpack-plugin')module.exports = {  entry: {    libs: [      'vue/dist/vue.esm.js',      'vue-router',      'vuex',      'element-ui'    ]  },  output: {    path: path.resolve(__dirname, '../static'),    filename: '[name].[chunkhash:7].js',    library: '[name]_library'  },  plugins: [    new webpack.DllPlugin({      path: path.resolve(__dirname, '../static/[name]-manifest.json'),      name: '[name]_library',      context: __dirname    }),    new webpack.optimize.UglifyJsPlugin({      compress: {        warnings: false      }    }),    new AssetsPlugin({      filename: 'bundle-config.json',      path: './static'    }),    new CleanWebpackPlugin(['static'], {      root: path.join(__dirname, '../'),      verbose: true,      dry: false    })  ]}复制代码
  • 在build目录下编写buildDll.js
const path = require('path')const webpack = require('webpack')const webpackDll = require('./webpack.dll.conf')const chalk = require('chalk')const ora = require('ora')const rm = require('rimraf')const spinner = ora({  color: 'green',  text: 'Dll生产中'})spinner.start()rm(path.resolve(__dirname, '../static'), err => {  if(err) throw err  webpack(webpackDll, (err, status) => {    spinner.stop()    if(err) throw err    process.stdout.write(status.toString({      colors: true,      modules: false,      children: false,      chunks: false,      chunkModules: false    }) + '\n\n')  })  console.log(chalk.cyan('dll success'))})复制代码
  • 修改webpack.base.conf.js
// 添加pluginsplugins: [    new webpack.DllReferencePlugin({      context: __dirname,      manifest: require('../static/libs-manifest.json')    })  ]复制代码
  • 修改webpack.dev.conf.js
const bundleConfig = require("../static/bundle-config.json")//调入生成的的路径jsonnew HtmlWebpackPlugin({      filename: 'index.html',      template: 'index.html',      inject: true,      libJsName: bundleConfig.libs.js}),复制代码
  • 修改webpack.prod.conf.js
const bundleConfig = require("../static/bundle-config.json")//调入生成的的路径json new HtmlWebpackPlugin({      ...省略号...      libJsName: bundleConfig.libs.js      ...省略号...    })复制代码
  • 修改index.html
      
vue-multipage
复制代码

参考文章:

转载地址:http://ziazx.baihongyu.com/

你可能感兴趣的文章
用户和开发者不满苹果iCloud问题多多
查看>>
java.lang.UnsatisfiedLinkError:no dll in java.library.path终极解决之道
查看>>
我的工具:文本转音频文件
查看>>
【许晓笛】从零开始运行EOS系统
查看>>
【跃迁之路】【460天】程序员高效学习方法论探索系列(实验阶段217-2018.05.11)...
查看>>
C++入门读物推荐
查看>>
TiDB 源码阅读系列文章(七)基于规则的优化
查看>>
面试中会遇到的正则题
查看>>
Spring之旅第八站:Spring MVC Spittr舞台的搭建、基本的控制器、请求的输入、表单验证、测试(重点)...
查看>>
数据结构与算法——常用排序算法及其Java实现
查看>>
你所不知的Webpack-多种配置方法
查看>>
React.js 集成 Kotlin Spring Boot 开发 Web 应用实例详解
查看>>
webpack+typescript+threejs+vscode开发
查看>>
python读excel写入mysql小工具
查看>>
如何学习区块链
查看>>
搜索问题的办法
查看>>
微信分销系统商城营销5大重点
查看>>
求职准备 - 收藏集 - 掘金
查看>>
htm5新特性(转)
查看>>
Linux-Centos启动流程
查看>>