webpack怎样优化包的大小


提示:以下是本篇文章正文内容,下面案例可供参考

1. 按需加载

1.1 路由组件按需加载

const router = [
 {
  path: '/index',
  component: resolve => require.ensure([], () => resolve(require('@/components/index')))
 },
 {
  path: '/about',
  component: resolve => require.ensure([], () => resolve(require('@/components/about')))
 }
]

1.2 第三方组件和插件按需加载

// 引入全部组件
import ElementUI from 'element-ui'
import 'element-ui/lib/theme-chalk/index.css'
Vue.use(ElementUI)
 
// 按需引入组件
import { Button } from 'element-ui'
Vue.component(Button.name, Button)

1.3 一些插件, 只在个别组件中用的上, 不需要在main.js中导入, 只需要在使用的页面导入即可

// 在main.js引入
import Vue from vue
import Vuelidate from 'vuelidate'
Vue.use(Vuelidate)
 
// 按组件按需引入
import { Vuelidate } from 'vuelidate'

2 优化loader配置

  • 优化正则匹配
  • 通过cacheDirectory选项来开启缓存
  • 通过include、exclude来减少处理的文件
module: {
 rules: [
  {
   test: /\.js$/,
   loader: 'babel-loader?cacheDirectory',
   include: [resolve('src')]
  }
 ]
}

3 优化文件路径-省下搜索文件的事件

  • extension 配置之后可以不用在 require 或是 import 的时候加文件扩展名,会依次尝试添加扩展名进行匹配。
  • mainFiles 配置后不用加入文件名,会依次尝试添加的文件名进行匹配
  • alias 通过配置别名可以加快 webpack 查找模块的速度。
resolve: {
 extensions: ['.js', '.vue', '.json'],
 alias: {
  'vue$': 'vue/dist/vue.esm.js',
  '@': resolve('src'),
 }
}

4 生产环境关闭sourceMap

  • sourceMap本质上是一种映射关系, 打包出来的js文件中的代码可以映射到代码文件的具体位置, 这种映射关系会帮助我们直接找到源码中的错误。
  • 打包速度减慢, 生产文件变大, 所以开发环境用sourceMap, 生产环境关掉

5 代码压缩

  • UglifyJS: vue-cli默认使用的压缩代码方式, 它使用的是单线程压缩代码, 打包事件较慢
  • ParallelUglifyPlugin: 开启多个子进程, 把对多个文件压缩的工作分别给多个子进程去完成
plugins: [
 new UglifyJsPlugin({
  uglifyOptions: {
   compress: {
    warnings: false
   }
  },
  sourceMap: true,
  parallel: true
 }),
 
 new ParallelUglifyPlugin({
  //缓存压缩后的结果,下次遇到一样的输入时直接从缓存中获取压缩后的结果并返回,
  //cacheDir 用于配置缓存存放的目录路径。
  cacheDir: '.cache/',
  sourceMap: true,
  uglifyJS: {
   output: {
    comments: false
   },
   compress: {
    warnings: false
   }
  }
 })
]

6 提取公共代码

  • 相同资源重复被加载, 浪费用户流量, 增加服务器成本
  • 每个页面需要加载的资源太大, 导致网页首屏加载缓慢, 影响用户体验
// webpack3 使用 CommonsChunkPlugin 的实现:
plugins: [
 new webpack.optimize.CommonsChunkPlugin({
  name: 'vendor',
  minChunks: function(module, count) {
   console.log(module.resource, `引用次数${count}`)
   //"有正在处理文件" + "这个文件是 .js 后缀" + "这个文件是在 node_modules 中"
   return module.resource && /\.js$/.test(module.resource) && module.resource.indexOf(path.join(__dirname, './node_modules')) === 0
  }
 }),
 new webpack.optimize.CommonsChunkPlugin({
  name: 'common',
  chunks: 'initial',
  minChunks: 2
 })
]
// webpack4 使用 splitChunks 的实现:
module.exports = {
 optimization: {
  splitChunks: {
   cacheGroups: {
    vendor: {
     priority: 1, //添加权重
     test: /node_modules/, //把这个目录下符合下面几个条件的库抽离出来
     chunks: 'initial', //刚开始就要抽离
     minChunks: 2 //重复2次使用的时候需要抽离出来
    },
    common: {
     //公共的模块
     chunks: 'initial',
     minChunks: 2
    }
   }
  }
 }
}

7 CDN优化

  • 随着项目越来越大, 依赖的第三方npm包越来越多, 构建之后的文件越来越大
  • 再加上又是单页面应用, 首页加载会造成长时间的白屏
  1. 将vue/element-ui/axios/vue-router/vuex用在index.html中采用cdn方式引入
<head>
 <link rel="stylesheet" href="https://cdn.bootcss.com/element-ui/2.0.7/theme-chalk/index.css" rel="external nofollow" />
</head>
<body>
 <div id="app"></div>
 <script src="https://cdn.bootcss.com/vue/2.6.10/vue.min.js"></script>
 <script src="https://cdn.bootcss.com/axios/0.19.0-beta.1/axios.min.js"></script>
 <script src="https://cdn.bootcss.com/vuex/3.1.0/vuex.min.js"></script>
 <script src="https://cdn.bootcss.com/vue-router/3.0.2/vue-router.min.js"></script>
 <script src="https://cdn.bootcss.com/element-ui/2.6.1/index.js"></script>
 <!-- built files will be auto injected -->
</body>
  1. 在webpack.config.js配置文件
module.exports = {
 ···
  externals: {
   'vue': 'Vue',
   'vuex': 'Vuex',
   'vue-router': 'VueRouter',
   'element-ui': 'ELEMENT',
   'Axios':'axios'
  }
 }
  1. 卸载依赖的npm包, npm uninstall vue vue-router vuex element-ui axios
  2. 修改mian.js中引入包的方式
// import Vue from 'vue'
// import ElementUI from 'element-ui'
// import 'element-ui/lib/theme-chalk/index.css'
// import VueRouter from 'vue-router'
 
import App from './App.vue'
import routes from './router'
import utils from './utils/Utils'
 
Vue.use(ELEMENT)
Vue.use(VueRouter)
 
const router = new VueRouter({
 mode: 'hash', //路由的模式
 routes
})
 
new Vue({
 router,
 el: '#app',
 render: h => h(App)
})

8 使用HappyPack多进程解析和处理文件

  • 由于运行在 Node.js 之上的 Webpack 是单线程模型的,所以 Webpack 需要处理的事情需要一件一件的做,不能多件事一起做。
  • HappyPack 就能让 Webpack 把任务分解给多个子进程去并发的执行,子进程处理完后再把结果发送给主进程。
  • HappyPack 对 file-loader、url-loader 支持的不友好,所以不建议对该 loader 使用。
    使用方法:
// 1. HappyPack插件安装: npm i -D happypack
// 2. webpack.base.conf.js文件对module.rules进行配置
module: {
 rules: [
  {
   test: /\.js$/,
   use: ['happypack/loader?id=babel'],
   include: [resolve('src'), resolve('test')],
   exclude: path.resolve(__dirname, 'node_modules')
  },
  {
   test: /\.vue$/,
   use: ['happypack/loader?id=vue']
  }
 ]
}
// 3. 在生产环境 webpack.prod.conf.js 文件进行配置
const HappyPack = require('happypack')
// 构造出共享进程池,在进程池中包含5个子进程
const HappyPackThreadPool = HappyPack.ThreadPool({ size: 5 })
plugins: [
 new HappyPack({
  // 用唯一的标识符id,来代表当前的HappyPack是用来处理一类特定的文件
  id: 'babel',
  // 如何处理.js文件,用法和Loader配置中一样
  loaders: ['babel-loader?cacheDirectory'],
  threadPool: HappyPackThreadPool
 }),
 new HappyPack({
  id: 'vue', // 用唯一的标识符id,来代表当前的HappyPack是用来处理一类特定的文件
  loaders: [
   {
    loader: 'vue-loader',
    options: vueLoaderConfig
   }
  ],
  threadPool: HappyPackThreadPool
 })
]

下次再见

  • 1
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 打赏
    打赏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包

打赏作者

剑九 六千里

你的鼓励将是我创作的最大动力

¥1 ¥2 ¥4 ¥6 ¥10 ¥20
扫码支付:¥1
获取中
扫码支付

您的余额不足,请更换扫码支付或充值

打赏作者

实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值