因爲前端的快速發展,相關工具的發展速度也是至關迅猛,各大框架例如vue,react都有本身優秀的腳手架工具來幫助咱們快速啓動一個新項目,也正式由於這個緣由,咱們對於腳手架中最關鍵的一環webpack相關的優化知之甚少,腳手架基本上已經爲咱們作好了相關的開發準備,可是當咱們想要作一些定製化的優化操做時,對webpack的優化也須要有必定的瞭解,不然無從下手,接下來就讓咱們進入webpack的優化世界javascript
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'] } }] }
externals提升構建速度的方法就是在構建時不會將指定的依賴包打包到bundle中,而是在運行時再從外部獲取依賴,具體是怎麼用的呢?來看個例子:vue
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又能夠作緩存,提升訪問速度,美滋滋java
DllPlugin是用來幹什麼的呢?DllPlugin會將第三方包到一個單獨文件,而且生成一個映射的json文件,打包的生成的文件就是一個依賴庫,這個依賴不會隨着你的業務代碼改變而被從新打包,只有當它自身依賴的包發生變化時纔會須要從新打包依賴庫,接下來來看具體配置吧:node
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配置文件中對進行配置:react
plugins: [ new webpack.DllReferencePlugin({ context: __dirname, manifest: require('./dist/vendor-manifest.json') }) ]
這樣就完成配置了,是否是很簡單呢?趕忙動手試試吧webpack
happypack這是個什麼呢?咱們都知道webpack是個單線程處理任務的,當又多個任務須要處理的時候,須要排隊,那happypack就是用多線程來處理任務,經過併發處理來提升任務處理速度,那麼這個須要怎麼配置呢?來看具體例子:web
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'] }) ],
這個相信你們都很熟悉,就是一個可視化工具,用來查看各個包的大小以及相互之間的依賴關係,配置方法也很簡單,就和插件的配置同樣,來看具體例子:vue-router
const bundleAnalyzerPlugin = require('webpack-bundle-analyzer').BundleAnalyzerPlugin plugins: [ new bundleAnalyzerPlugin() ],
tree shaking指的是什麼呢?一般指的是JavaScript上下文中未引用的代碼,怎麼理解呢?好比你引用了lodash包,裏面有許多和JavaScript相關的便利方法,但你實際只用了其中的一兩個,此時打包時若是把全部的方法都打進去了,是否是很浪費呢?tree shaking的概念就是去除多餘代碼。來看一個簡單的例子:vuex
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就能夠在構建的過程當中對冗餘的代碼進行刪除,在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是指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優化相關的方法,但願你們都能本身動手去寫一寫,畢竟只有實踐出真知,更況且是編程。這篇文章若是有錯誤或不嚴謹的地方,歡迎批評指正,若是喜歡,歡迎點贊收藏