webpack优化的深入理解

前言

由于前端的快速发展,相关工具的发展速度也是相当迅猛,各大框架例如vue,react都有自己优秀的脚手架工具来帮助我们快速启动一个新项目,也正式因为这个原因,我们对于脚手架中最关键的一环webpack相关的优化知之甚少,脚手架基本上已经为我们做好了相关的开发准备,但是当我们想要做一些定制化的优化操作时,对webpack的优化也需要有一定的了解,否则无从下手,接下来就让我们进入webpack的优化世界

构建速度提升

loader提升

loader是webpack中最重要的特性,由于webpack自身只支持JavaScript,因此需要一系列的loader来处理那些非JavaScript模块,因此在我们用webpack建项目的时候一定会使用一系列的loader,例如:vue-loader、sass-loader、babel-loader等等,就以babel-loader为例,来看具体配置:

module: {
 rules: [{
  test: /\.js$/,
  exclude: /node_modules/,
  loader: 'babel-loader?cacheDirectory=true',
  options: {
  presets: ['@babel/preset-env'],
  plugins: ['@babel/transform-runtime']
  }
 }]
 }
  • 对于loader来说最常用的就是exclude属性,用来避免不必要的转译,上面通过exclude来避免对node_modules中js中进行转译来提升构建速度,但是这样带来的提升效果有限。
  • cacheDirectory是对babel-loader的转译结果进行缓存,之后的webpack进行构建时,都会去尝试读取缓存来避免高耗能的babel重新转译过程,cacheDirectory可以指定一个缓存目录或者指定为true,为true时将使用默认的缓存目录node_modules/.cache/babel-loader。
  • babel对一些公共方法使用了非常小的辅助代码,默认会注入到每一个需要的文件,这样就造成重复引入,这时候就需要像上面那样引入transform-runtime来告诉babel引入runtime来代替注入

第三方库优化

externals

externals提高构建速度的方法就是在构建时不会将指定的依赖包打包到bundle中,而是在运行时再从外部获取依赖,具体是怎么用的呢?来看个例子:

externals : {
 vue : "Vue",
 vueRouter : "VueRouter",
 vueResource : "VueResource",
 vuex : "Vuex"
},
<script type="text/javascript" src="https//xxxx/vue.famliy.1.1.0.min.js"></script>

上面的例子的将vue全家桶都配置在externals中,然后将压缩包合成一个js文件放在cdn上面,这样就不会在构建时将文件打包到bundle中,提升打包速度,同时cdn又可以做缓存,提高访问速度,美滋滋

DllPlugin

DllPlugin是用来干什么的呢?DllPlugin会将第三方包到一个单独文件,并且生成一个映射的json文件,打包的生成的文件就是一个依赖库,这个依赖不会随着你的业务代码改变而被重新打包,只有当它自身依赖的包发生变化时才会需要重新打包依赖库,接下来来看具体配置吧:

module.exports = {
 entry: {
 vendor: ['vue', 'vue-router', 'vue-resource', 'vuex']
 },
 output: {
 path: path.join(__dirname, 'dist'),
 filename: '[name].js',
 library: '[name]_hash',
 },
 plugins: [
 new webpack.DllPlugin({
  name: '[name]_[hash]',
  path: path.join(__dirname, 'dist', '[name]-manifest.json'),
  context: __dirname
 })
 ]
}

首先我们需要一个如上面例子那样的dll配置文件,然后编译这个配置文件,生成一个vendor.js和一个映射文件vendor-manifest.json,然后再在我们的webpack配置文件中对进行配置:

plugins: [
 new webpack.DllReferencePlugin({
  context: __dirname,
  manifest: require('./dist/vendor-manifest.json')
 })
 ]

这样就完成配置了,是不是很简单呢?赶紧动手试试吧

happypack

happypack这是个什么呢?我们都知道webpack是个单线程处理任务的,当又多个任务需要处理的时候,需要排队,那happypack就是用多线程来处理任务,通过并发处理来提高任务处理速度,那么这个需要怎么配置呢?来看具体例子:

const happypack = require('happypack')
// 创建并发池
const threadPool = happypack.ThreadPool({size: os.cpus().length})
module: {
 rules: [{
  test: /\.js$/,
  exclude: /node_modules/,
  loader: 'happypack/loader?id=happyBabel' // id对应happypack插件id
 }]
 },
plugins: [
 new happypack({
  id: 'happyBabel',
  threadPool: threadPool,
  loaders: ['babel-loader?cacheDirectory']
 })
 ],

减小构建体积

webpack-bundle-analyzer

这个相信大家都很熟悉,就是一个可视化工具,用来查看各个包的大小以及相互之间的依赖关系,配置方法也很简单,就和插件的配置一样,来看具体例子:

const bundleAnalyzerPlugin = require('webpack-bundle-analyzer').BundleAnalyzerPlugin
plugins: [
 new bundleAnalyzerPlugin()
 ],

tree shaking

tree shaking指的是什么呢?通常指的是JavaScript上下文中未引用的代码,怎么理解呢?比如你引用了lodash包,里面有许多和JavaScript相关的便利方法,但你实际只用了其中的一两个,此时打包时如果把所有的方法都打进去了,是不是很浪费呢?tree shaking的概念就是去除多余代码。来看一个简单的例子:

import {plus} from './count'

console.log(plus(1, 2))
function plus(x, y) {
 return x + y
}
function minus(x, y) {
 return x - y
}
export {
 plus,
 minus
}
const path = require('path')

module.exports = {
 entry: {
 main: './src/index.js',
 },
 output: {
 path: path.join(__dirname, 'dist'),
 filename: '[name].js',
 },
 mode: 'development'
}

如上例所示,在入口文件中我们引入count.js中plus方法,我们期望的当然是只会引入plus方法,而不是都引入,但往往不随人愿,来看结果:

你会发现编译后的代码中,整个count.js都被编译进去了,这时候你就需要tree shaking了,接下来看做tree shaking的具体方法

UglifyJsPlugin

这个插件大家一定都用过,使用UglifyJsPlugin就可以在构建的过程中对冗余的代码进行删除,在webpack4中只需要将上面mode的值改为production,就会启用UglifyJsPlugin,是不是很简单,或许你想知道webpack4中怎么自己配置UglifyJsPlugin,那就来看具体配置吧:

const UglifyJsPlugin = require('uglifyjs-webpack-plugin')
optimization: {
 minimizer: [
  new UglifyJsPlugin({
  parallel: true,
  cache: true,
  uglifyOptions: {
   compress: {
   drop_console: true,
   reduce_vars: true
   },
   output: {
   comments: false,
   beautify: false
   }
  }
  })
 ]
 }

是的在webpack4中的UglifyJsPlugin是配置在optimization中的minimizer中的,配置是不很简单呢?赶紧动手尝试吧

按需加载(import)

这里的import是指webpack中的动态加载,它的语法和ES6中的动态加载语法一摸一样,这是官方推荐的按需加载的方式,还是上面tree shaking的例子,我们只想引入plus方法,我们来看具体怎么使用:

import('./count.js').then((count) => {
 console.log(count.plus(1, 2))
})

我们只需要将入口文件改成上面的形式,其他的都不要变就可以实现按需引入,是不是很简单呢?在vue中路由的按需加载也可以这么用,来看一个简单的例子:

function view (name) {
 return new Promise((resolve, reject) => {
 import('../views/' + name + '.vue')
  .then((res) => {
  resolve(res)
  }).catch(e => {
  reject('网络异常,请稍后再试')
  })
 }).catch(err => {
 throw new Error('err,组件加载失败')
 })
}

传入一个名字,动态引入对应目录的下的视图文件,这只是一个简单的例子,具体的使用形式还是依据具体的场景

总结

这篇文章简单的从构建速度和代码体积两个方面简单的介绍了webpack优化相关的方法,希望大家都能自己动手去写一写,毕竟只有实践出真知,更何况是编程。

好了,以上就是这篇文章的全部内容了,希望本文的内容对大家的学习或者工作具有一定的参考学习价值,如果有疑问大家可以留言交流,谢谢大家对我们的支持。

(0)

相关推荐

  • 详解vue-cli + webpack 多页面实例配置优化方法

    本文介绍了vue-cli + webpack 多页面实例配置优化方法,分享给大家 vue+webpack是否有多页面 目前使用vue来做项目,估计大部分都是单页面(SPA)应用,一个轻型的 MVVM 框架,谁用了MVVM框架,就再也回不去JQ时代了,哈哈. 在手机端的项目,使用vue + vue-router是high到爆,不仅仅是我们开发的而言,最主要的用户体检也是开足马力,体检感杠杠的. 那问题来了,使用vue+webpack的单页面是爽到爆,那如果是多页面也能不能high到爆呢?那当然呀,

  • webpack4.0打包优化策略整理小结

    本文介绍了webpack4.0打包优化策略整理小结,分享给大家,具体如下: webapck4 新特性介绍-参考资料 当前依赖包的版本 1.优化loader配置 1.1 缩小文件匹配范围(include/exclude) 通过排除node_modules下的文件 从而缩小了loader加载搜索范围 高概率命中文件 module: { rules: [ { test: /\.js$/, use: 'babel-loader', exclude: /node_modules/, // 排除不处理的目录

  • 详解webpack 热更新优化

    前言 随着项目的界面越来越多,webpack的热更新越来越慢,有时会达到5,7s之久,这对于开发效率影响是非常巨大的. 分析过程 于是今天就针对这个分析了一下热更新慢的原因,步骤如下 首先先在package中的启动命令加上 --progress --watch --colors --profile 先解释一下这几个参数的含义 --progress 构建进度 --watch 实时监测 --profile 编译过程中的步骤耗时时间 加上了这几个参数,重启项目,就可以开始观察耗时时间了,修改了某个文件

  • webpack学习笔记之优化缓存、合并、懒加载

    除了的webpack基本配置,还可以进一步添加配置,优化合并文件,加快编译速度.下面是生产环境配置文件webpack.production.js,与wenbpack.config.js相比其不需要一些dev-tools,dev-server和jshint校验等,将与开发相关的东西删掉.下面的介绍均以此代码配置作参考. /*生成环境配置文件:不需要一些dev-tools,dev-server和jshint校验等.和开发有关的东西删掉*/ var webpack = require('webpack

  • Webpack性能优化 DLL 用法详解

    前言 在用 Webpack 打包的时候,对于一些不经常更新的第三方库,比如 react,lodash,我们希望能和自己的代码分离开,Webpack 社区有两种方案 CommonsChunkPlugin DLLPlugin 对于 CommonsChunkPlugin,webpack 每次打包实际还是需要去处理这些第三方库,只是打包完之后,能把第三方库和我们自己的代码分开.而DLLPlugin 则是能把第三方代码完全分离开,即每次只打包项目自身的代码. 用法 要使用 DLLPlugin,需要额外新建

  • 详解vue-cli之webpack3构建全面提速优化

    前言 伴随着vue的全球化,已经各种vue的组件框架越来越完善,从早期的element-ui到vux,iview等越来越多高质量的项目,使用vue进行前端构建已然是一件工程化,模块化,敏捷化的事情 在这其中,相信很多人都会选择官方的vue-cli初始化工程模板,然后通过引入第三方组件框架和工具的方式进行开发构建,我个人也十分推崇这种做法.但是vue-cli初始化的项目模板毕竟是面向所有开发者的,在兼容性方面会有一定妥协.相信很多人都已经搜索过各类的webpack构建优化文章,但是很多不是版本太老

  • vue webpack打包优化操作技巧

    临近春节,公司很多同事都提前回家过年,剩余人员根据禅道去修改bug,当bug修正完毕以后,我们需要重新打包给运维,上测试服给测试同事提测,但是由于项目本体比较庞大,所以打包时间太过漫长(二十五分钟以上:sob:),所以有了打包优化的想法(其实想法早就有了,但是因为平时工作计划比较充实,所以一直没有去完成这个工作),这次正好有时间,所以去重新考虑了这个问题! webpack是react项目标配的打包工具,和NPM搭配起来使用管理模块实在非常方便.   webapck 把所有的静态资源都看做是一个

  • 详解基于vue-cli优化的webpack配置

    最近的项目度过了开始忙碌的基建期,也慢慢轻松下来,准备记录一下自己最近webpack优化的措施,希望有温故知新的效果. 项目采用的是vue全家桶,构建配置都是基于vue-cli去改进的.关于原始webpack配置大家可以看下这篇文章vue-cli#2.0 webpack配置分析,文章基本对于文件每行代码都做了详细的解释,有助于更好的理解webpack. 仔细总结了一下,自己的优化基本还是网上流传的那几点 通过 externals 配置来提取常用库,引用cdn 合理配置CommonsChunkPl

  • vue-cli webpack2项目打包优化分享

    减小文件搜索范围 配置 resolve.modules Webpack的resolve.modules配置模块库(即 node_modules)所在的位置,在 js 里出现 import 'vue' 这样不是相对.也不是绝对路径的写法时,会去 node_modules 目录下找.但是默认的配置,会采用向上递归搜索的方式去寻找,但通常项目目录里只有一个node_modules,且是在项目根目录,为了减少搜索范围,可以直接写明 node_modules 的全路径:同样,对于别名(`alias)的配置

  • 浅谈Webpack打包优化技巧

    前端的打包工具从之前的browserify.grunt.gulp到现如今的rollup.webpack,涌现出了很多优秀的打包工具,而目前最火的无疑是webpack,无论是当前热门的框架还是工具库很多都选择了它作为打包工具,因此在开发中webpack作为打包工具是一个很好的选择.在最近的项目开发中我也用到了webpack,其中也碰到了不少优化方面的问题,这里总结一下webpack打包优化的一些细节和方法. 首先,这次项目用到的是vue的全家桶,在webpack的配置方面直接用的是 vue-cli

随机推荐