編譯es6:
基礎(chǔ):babel-loader --save-dev babel-core --save-dev;要配置babel以什么規(guī)范打包(針對語法)要用到babel-preset-env --save-dev,如es2015/es2016/es2017/env(2015-2017及最近),rules.use.options.presets:['env',{targets:{browsers: ['> 1%', 'last 2 versions']}}]鞠值。
babel-polyfill --save(在代碼開始就要import進(jìn)來)和babel-runtime --save赁濒、babel-plugin-transform-runtime --save-dev,(es的函數(shù)方法一些低版本瀏覽器還不具有,需要用到polyfill和runtime這兩個babel插件)泳赋。(比如Generator Set Map Array.form Array.prototype.include都不會被babel處理),babel-polyfill為全局墊片(全局可以使用新函數(shù)方法)為應(yīng)用準(zhǔn)備(為自己所用),babel-runtime為局部墊片為框架(開發(fā)給別人用)準(zhǔn)備川无。我們可以在根目錄下.babelrc中配置babel。
提取公共代碼:
主要針對多頁面應(yīng)用虑乖,減少代碼冗余懦趋,提高加載速度(spa公共代碼提前加載出來,非spa公共代碼緩存起來)疹味。
CommonsChunkPlugin
場景:單頁應(yīng)用掏呼、單頁應(yīng)用+第三發(fā)依賴、多頁應(yīng)用+第三發(fā)依賴+webpack生成代碼
? ??????單頁應(yīng)用铅檩,commonsChunk是針對entry中多個入口文件(多頁面應(yīng)用)進(jìn)行公共代碼打包的憎夷,單入口(單頁面應(yīng)用)是無效的。
? ??????多頁面應(yīng)用昧旨,a1和a2都依賴b拾给。在entry中把a(bǔ)1和a2都作為入口,就能把b單獨打包出來成公共模塊兔沃。
? ??????多頁面應(yīng)用+第三方依賴蒋得,
new webpack.optimize.SplitChunksPlugin({}) 或者optimization.splitChunk{()}
每個頁面都要的公共代碼提取出來后直接以script形式插入代碼中而不進(jìn)行http請求,html-webpack-inline-chunk-plugin粘拾,new HtmlInlinkChunkPlugin({ inlineChunks(指定要插入代碼的模塊名): ['mainifest'] })
代碼分割和懶加載:
使用場景:分離業(yè)務(wù)代碼和第三方依賴窄锅、分離業(yè)務(wù)代碼和業(yè)務(wù)公共代碼和第三方依賴、分離首次加載和訪問后加載的代碼缰雇。
實現(xiàn)方式一入偷,webpack內(nèi)置方法。
? ??????require.ensure(對原生promise有依賴,需要引入babel-polyfill)動態(tài)加載一個模塊械哟,參數(shù):[],dependencies(依賴疏之,加載進(jìn)來并不會執(zhí)行,其callback內(nèi)還要通過require執(zhí)行代碼暇咆。當(dāng)不指定依賴時锋爪,只在callback內(nèi)require會變成異步);callback,回調(diào)函數(shù)里才會執(zhí)行代碼;chunkName(打包生產(chǎn)的模塊名)丙曙。
? ??????require.include是針對兩個子模塊都引用了相同模塊,當(dāng)兩個自模塊都依賴了一個第三方模塊其骄,可以提前把第三個模塊放到父模塊中(比如page依賴pageA和pageB亏镰,而pageA/pageB依賴module,那么module不會被打包進(jìn)pageA/pageB拯爽,直接打包進(jìn)page)索抓。
實現(xiàn)方式二,ES2015 Loader spec毯炮。
? ??????important替代require.ensure逼肯,important進(jìn)來就已經(jīng)執(zhí)行,這點和require.ensure不同。important(/*webpackChunkName: async-chunk-name*/? /*webpackMode: lazy*/? modulename).then(...)(需要引入babel-polyfill),既符合es6語法桃煎,又實現(xiàn)代碼分割懶加載功能篮幢。若兩個important寫了相同的webpackChunkName則打包文件會合并到這個chunk里。
? ? 注意:使用import報錯的話为迈。npm?install?--save-dev?babel-plugin-syntax-dynamic-import三椿。.babelrc 中加上插件"plugins":?["syntax-dynamic-import"]。
處理css:
如何通過loader引入css文件曲尸?
如何做到css模塊化赋续,不再是全局的?
如何通過loader去處理sass和less另患?
如何提取css代碼纽乱?把css提取出一個單獨文件,他會有自己的緩存昆箕,用到這個樣式的多個文件鸦列,在第一個文件就已經(jīng)緩存住了,接下來文件速度更快鹏倘。
如何提取公共css代碼薯嗤?
? ? ? ? 1、style-loader是用來創(chuàng)建style標(biāo)簽纤泵,把提取出來的css放入html的style標(biāo)簽中,options:?insertAt(插入位置)骆姐、insertInto(插入到dom,如:'#app')捏题、singleton(是否只使用一個style標(biāo)簽玻褪,true就進(jìn)行合并到一個style中,因為像ie有style個數(shù)標(biāo)簽限制)、transform(路徑.js公荧,瀏覽器環(huán)境下在把css插入html前運行带射,比如在此時我們可以根據(jù)瀏覽器不同類型做不同操作,會在每一個css文件插入前都執(zhí)行一遍)循狰。
? ? ? ? 另外:style-loader/url(在頁面中創(chuàng)建link標(biāo)簽窟社,一般不用)券勺。style-loader/useable(import a from 'xx.css'后,可以通過在js中寫a.use(),a.unues()來改變這段css引入或去掉)。
? ? ? ?2灿里、css-loader是解決在js中可以import css 進(jìn)來关炼。options:alias(解析的別名,當(dāng)你匹配到的路徑下的css里面你要import另外一個css時,alias在import的路徑中可以生效)。importLoader(@import钠四,是否生效,取決于css-loader后面是否還有其他loader)盗扒。Minimize(boolean,是否壓縮css)。modules(boolean,是否啟用css模塊化)缀去。
????????css模塊化的語法,':local':局部樣式甸祭;':global':全局樣式缕碎;'compose':繼承樣式;'compose....from path':從某個文件引入樣式池户。
? ? ? ? 3咏雌、配置Sass/Less。Less: npm install less-loader less --save-dev校焦。Sass: npm install sass-loader node-sass --save-dev赊抖。
sass-loader、 node-sass寨典,css預(yù)編譯. 執(zhí)行順序是 sass-loader 》postcss-loader 》css-loader 》 style-loader氛雪,loaders是從下往上執(zhí)行的,
? ? ? ? 4耸成、提取css报亩。extract-text-webpack-plugin 或者?extract-loader,我們用前者井氢。1弦追、匹配sass時用ExtractTextPlugin.extract({fallbak(提取出來之后):{loader:'style-loader'},use:[提取之前處理 ..]}) 花竞。2劲件、plugins中new ExtractTextWebpackPlugin({ filename:(提取出的css叫什么[name].min.css) ,allChunks: false (異步加載的JS模塊中引入的css/sass/lss最終都會被打包進(jìn)js模塊中约急,并且能參與公共代碼分割等)})零远。
? ? ? ? 5、postCss烤宙。postcss遍烦、postcss-loader、autoprefixer躺枕、cssnano(優(yōu)化壓縮css,css-loader已經(jīng)集成了這個功能,minmize:true即可)服猪、postcss-cssnext(可以使用css新語法如css 變量(variable), 自定義選擇器(custom selectors)供填,動態(tài)計算calc() )。autoprefixer使用:{loader: 'postcss-loader', options: {ident: 'postcss'(表明接下來插件是給postcss用的), plugins: [ require('autoprefixer')() ]}}
? ? ? ? 另外罢猪,postcss-import(幫助我們把通過@import引入的文件內(nèi)容取到我們的css中近她,取過來時相對路徑會變化,要配合postcss-url幫忙轉(zhuǎn)換膳帕。另外還有postcss-assets粘捎。)
想要所有插件都共用一份瀏覽器適配配置,1危彩、可以在package.json中配置攒磨。2、可以在項目根目錄建一個.browserslistrc文件進(jìn)行配置汤徽。
Tree Shaking:
對用不到的代碼娩缰,打包時進(jìn)行刪除。使用場景:1谒府、常規(guī)優(yōu)化自己代碼拼坎。2、引入第三方庫代碼完疫。包括 js tree shaking和 css tree shaking泰鸡。
js tree shaking: webpack打包時會把沒有用到的方法標(biāo)識出來,通過插件?uglifyjs-webpack-plugin 或者 webpack.optimize.uglifyJs(不支持es6)來刪除它們壳鹤。但有些第三方庫比如Lodash不是以export方式輸出代碼塊的盛龄,我們不能進(jìn)行刪減,我們需要借助一些插件器虾,比如lodash需要下載一個? babel-plugin-lodash 讯嫂,在babel-loader的options中配置{present: ['env'], plugins: ['lodash']。
問題:Babel默認(rèn)將ES6模塊通過commonJs模塊轉(zhuǎn)換輸出兆沙,此時利用ES6模塊的tree-shaking就不靈了欧芽。
方法:babel-preset-env有個modules的配置項就是控制這個的,把它設(shè)置成false就不會把ES6模塊轉(zhuǎn)換成commonJs了葛圃。
css tree shaking:需要用到 purifycss-webpack? glob-all(其中有g(shù)lob.sync可以用來多路徑同時加載)千扔。該插件必須放在css提取插件extractTextWebpackPlugin插件后面。new PurifyCss({ path:?glob.sync([ path.join(_dirname, 'app/html/*.html'), path.join(_dirname, 'app/js/*.js') ]) })?
文件處理:
1库正、如何引入圖片曲楚,引入圖片后webpack如何處理圖片。2褥符、合成雪碧圖龙誊。2、壓縮圖片喷楣。3趟大、小圖片不需要壓縮鹤树,進(jìn)行base64編碼。
url-loader/file-loader +img-loader +postcss-sprites
處理圖片:file-loader(我們css中寫的路徑是相對于css的逊朽,而打包后文件路徑是相對于入口html文件的罕伯,file-loader主要處理文件路徑問題)?options: {publicPath(處理過圖片路徑前一起加一段路徑):'',outputPath(圖片打包輸出文件路徑):' '叽讳,useRelativePath(打包出文件路徑是否使用相對與此配置文件的相對路徑): true追他,name(打包后輸出文件名name): '[name].min.[ext]'}
?圖片base64編碼:對小圖片進(jìn)行base64編碼減少http請求:url-loader(和file-loader功能差不多就多了個base64編碼,打包出的圖片文件名可以在url-loader/file-loader中配置name:[name]-[hsah:5].[ext])岛蚤,options:{ limit(對小于這個值大小圖片進(jìn)行base64編碼): 10000邑狸,其他同file-loader一樣,可以替代file-loader?}
壓縮圖片:img-loader ,options: {pngquant: { quality(圖片質(zhì)量控制): 80 }}
合成雪碧圖:postcss-sprites?在postcss-loader中 options: { ident: 'post', plugins: [ require('postcss-sprites')( { spritePath(雪碧圖輸出路徑): ' dist/.. ' 灭美,retina: true} ) ] }推溃。設(shè)計師提供2倍大小圖片高清適配,那么2倍大小圖片如何做雪碧圖届腐?1、設(shè)置retina:true蜂奸,2犁苏、告訴postcss-sprites哪些屏幕是retina圖片,即在圖片名后面加上@2x
處理字體文件:先把字體文件下載放到項目中扩所,css中@font-face{font-family(自定義字體名): '..' src: url('字體文件路徑') }注冊, 最后在css中使用 它就好了围详。url-loader
處理第三方庫:webpack.ProvidePlugin 、imports-loader 祖屏、 window 命名空間助赞。需要在每個模塊中都引入一段代碼,1袁勺、若遠(yuǎn)程cdn上的第三方庫雹食,直接在頁面<script src="..">(針對單頁面入口文件,多頁面還得每個頁面添加)期丰。2群叶、代碼在自己項目目錄下,webpack.ProvidePlugin或者imports-loader钝荡。若npm下載的第三方庫街立,new webpack.ProvidePlugin({ $(自定義可以使用的變量名): 'jquery'(模塊的名稱) }) 或者 { test: path.resolve(_dirname, 'src/app.js'), use: [ { loader: 'imports-loader', options: { $: jquery } } ] }。 若不是npm下載埠通,是自己項目目錄下的js赎离,需要先配置別名,resolve: { alias: { jquery$(這里的$符為確定接下來路徑是準(zhǔn)確文件端辱,不是目錄) : path.resolve(_dirname, 'src/libs/jquery.min.js') } }梁剔,接下來同上虽画。
生成html:
生成html并在html中注入css和js。HtmWebpackPlugin憾朴,new HTMLWebpackPlugin({?filename(生成的 HTML 文件名): '..', template(生成 HTML 文件使用的模板): path.resolve(__dirname, '...'), chunks(要注入的js模塊狸捕,默認(rèn)全注入):['..'],minify(是否壓縮生成的html: collapseWhitespace: true(進(jìn)行壓縮))众雷,inject(是否把js,css插入你生成的html文件中): 默認(rèn)true})?
html中引入圖片灸拍、路徑:兩種方法。1砾省、html-loader, { option: { attrs: [ 'img:src', 'img(html標(biāo)簽): data-src(標(biāo)簽屬性)' ] } } 鸡岗。有一個問題,如果我們css中圖片路徑是用(../a.png)相對路徑(相對打包出的css文件),html中也用(../b.png)相對路徑(相對打包出的html文件)编兄,url-loader中處理時uesRelativePath: true,這樣 打包生成的img圖片會出現(xiàn)在兩個位置轩性。我們這樣的話,只能把路徑改成絕對路徑(url-loader中處理時outputPath: 'assets/imgs/',把output中 publicPath: '/')狠鸳,因為url-loader不能分別定義相對路徑揣苏,我們css中url和html中的url相對的不是同一個地方。2件舵、直接在html中img src="${require('src/assets...')}"
搭建本地開發(fā)環(huán)境:
1卸察、webpack watch mode?(輸入命令webpack -watch),webpack會去監(jiān)聽文件變化實時打包铅祸,但并不會起一個web服務(wù)器坑质。
2、webpack-dev-server临梗,clean-webpack-plugin(打包之前先刪除之前打包的文件夾,new CleanWebpackPlugin(path.resolve(__dirname, '../dist')指定要清除目錄涡扼,和根路徑(得在清除目錄的上級));devServer{ inline(true:在控制臺顯示打包情況,否則在瀏覽器頂部顯示), port(端口號)盟庞,historyApiFallback(主要對單頁應(yīng)應(yīng)用,跳頁時候不會刷新瀏覽器)吃沪,contentBase(提供內(nèi)容的路徑,默認(rèn)為當(dāng)前工作目錄),https(指定生成證書)茫经,proxy(集成了http-proxy-middleware指定遠(yuǎn)程接口代理)巷波,hot(模塊熱更新),lazy(剛啟動服務(wù)器時不打包任何東西卸伞,打開相應(yīng)頁面加載打包相應(yīng)模塊)}抹镊,overlay(在頁面中打開一個遮罩顯示錯誤提示)
Proxy: { '/api'(匹配請求中以‘/ap’i開頭的路徑) : { target(指定請求路徑): 'https://..',changeOrigin(一般為true): true荤傲,pathRewrite(把請求中/a替換為/a/b,請求時少寫點代碼): { '^/a' : '/a/b'}垮耳,headers(設(shè)置請求頭): {'cookie': '...'} }}
hot(模塊熱更新):當(dāng)我們修改代碼時,1、應(yīng)用之前請求的數(shù)據(jù)狀態(tài)都能保存下來,2终佛、不用刷新頁面可以節(jié)省調(diào)試時間滑蚯,3达址、樣式調(diào)試更快癣防⌒剑可以通過devServer.hot來開啟模塊熱更新。webpack.HotModuleReplacementPlugin + webpack.NamedModulesPlugin牙捉。css模塊熱更新會由style-loader進(jìn)行處理竹揍,我們只需開啟hot即可。js模塊熱更新我們需要手動寫一些代碼邪铲,需要熱更新時候我們會用到API:module.hot.accept接受兩個參數(shù)芬位,1、依賴带到。2昧碉、依賴更新后回調(diào)函數(shù),回調(diào)里需要對你需要更新的依賴進(jìn)行重載(先移除,再加載進(jìn)來)揽惹。
3被饿、express + webpack-dev-middleware(比2更加靈活自由,需要自己寫的配置項更多)?
express/koa(第三方node服務(wù))? ?webpack-dev-middleware(中間件) webpack-hot-middle(模塊熱更新)??http-proxy-middle(服務(wù)器代理)? connect-history-api-fallbak(地址reback)? opn(打開瀏覽器)
設(shè)置Eslint檢查代碼格式:
eslint eslint-loader eslint-plugin-html(對html中script標(biāo)簽中代碼進(jìn)行檢查) eslint-friendly-formatter(報錯報告格式)? eslint-plugin-import ,?eslint-config-standard? eslint-plugin-node? eslint-plugin-promise? eslint-plugin-standard(遵從Javascript Standard Style規(guī)則來驗證我們需要的代碼 所需要下載的配置搪搏,或者去github上搜eslint-config-xxx開頭的eslint配置)? ?锹漱。 給js加一個eslint-loader,得在babel-loader之前去處理他,也就是寫在babel-loader之后慕嚷,options: { formatter: require('eslint-friendly-formatter') },可以在根目錄創(chuàng)建.eslintrc.js進(jìn)行eslint配置 { root(是否在根目錄): true毕泌,extends(標(biāo)準(zhǔn)版): 'standard'喝检,plugins: [ ' html' ], env(在哪些環(huán)境開啟檢查): { browser: true, node: true },rules:[...] } 。 在devServer中開啟overlay: true,可以在瀏覽器頁面直接看到錯誤撼泛。
代碼調(diào)試sourceMap
devtool(sourceMap): 源代碼和打包后代碼不同挠说,我們要調(diào)試代碼的話,需要用到它愿题。css使用sourceMap 出了在dev-server中開啟它损俭,css-loader sass-loader中也要開啟sourceMap,js中UglifyJsPlugin的sourceMap也要打開潘酗。開發(fā)環(huán)境推薦 cheap-module-source-map杆兵,生產(chǎn)環(huán)境的話直接source-map。
長緩存優(yōu)化:
用戶請求網(wǎng)頁數(shù)據(jù)時仔夺,服務(wù)器返回請求時可以通過控制http協(xié)議的響應(yīng)頭告訴瀏覽器某些資源是在某一段時間內(nèi)是長緩存不用更新琐脏,這些資源有自己版本號,當(dāng)這些版本號不發(fā)生改變,瀏覽器不會去發(fā)請求或者發(fā)請求瀏覽器也會從本地加載資源日裙,可以減少用戶訪問網(wǎng)頁的時間吹艇。
場景:改變app代碼,vendor變化昂拂。
1受神、我們需要單獨提取vendor進(jìn)行打包。把vendor有一個獨立的enter就行格侯。
2鼻听、單獨打包出webpack runtime(打包時候webpack自己會產(chǎn)生的代碼,每個打包文件都會有养交,內(nèi)容每次打包都不一樣精算,會影響chunkhash值變化)。
3碎连、控制版本號的hash(每一次打包的hash,內(nèi)容相同,兩次打包hash值不同)值改為chunkhash(代碼的hash,內(nèi)容相同,兩次打包chunkhash值相同)灰羽,內(nèi)容不發(fā)生變化時,讓打出的版本號也不變鱼辙。
場景:當(dāng)引入新模塊廉嚼,模塊順序變化, vendor?chunkhash也會變化(原因:webpack在打包時候會給每個chunk一個id,id發(fā)生變化也會導(dǎo)致chunkhash發(fā)生變化)倒戏。這時候我們需要用到兩個插件
?1怠噪、new webpack.NamedChunksPlugin() 把打包文件的chunksId由原來的序號(會變)轉(zhuǎn)為文件名(不變)。new webpack.NamedModulesPlugin() 把打包文件里的模塊的id也由原來的序號(會變)轉(zhuǎn)為文件名(不變)杜跷,因為它也會影響chunkhash傍念。
場景:若模塊是動態(tài)引入的,他的chunksId由還會是的序號(會變)葛闷,高版本webpack已經(jīng)解決這個問題憋槐。低版本可以異步important時候/* webpackChunkName: '..' */? 指定webpackChunkName就可以了。
開發(fā)環(huán)境和生產(chǎn)環(huán)境區(qū)分淑趾。
不同點:開發(fā)環(huán)境阳仔,1、模塊熱更新扣泊。2近范、sourceMap調(diào)試代碼。3延蟹、接口代理评矩。4、代碼規(guī)范檢查等孵。生產(chǎn)環(huán)境稚照,1、提取公用代碼。2果录、壓縮混淆上枕。3、文件壓縮或者base64編碼弱恒。4辨萍、去除無用的代碼。共同點:1返弹、同樣的入口锈玉。2、同樣的代碼處理(loader處理)义起、3拉背、同樣的解析配置。
打包分析默终、優(yōu)化
優(yōu)化打包速度:
1椅棺、分開第三方代碼(vendor)和業(yè)務(wù)代碼(app)。使用DllPlugin插件和DllReferencePlugin插件將兩者分開打包齐蔽。
2两疚、UglifyJsPlugin壓縮混淆是非常耗時的工作,parallel參數(shù)(串連處理->并行處理):true含滴。cache參數(shù)開啟
3诱渤、HappyPack針對loader,串行處理->并行處理谈况。
4勺美、babel-loader打包耗時,options.cacheDirectory(開啟緩存)碑韵。include励烦,exclude(限定范圍)
5、減少resolve泼诱,Devtool:去除sourcemap,cache-loader把所有l(wèi)oader處理的結(jié)果緩存下來赊锚。升級node和webpack治筒。
Webpack和Vue-cli:
初始化項目:vue init <template name>(一般webpack) <project name>
項目結(jié)構(gòu):
????static:文件夾下文件不會進(jìn)行解析,打包直接移過去舷蒲。一般用來放沒有被npm管理起來的第三方包耸袜。
? ? src/assets:業(yè)務(wù)相關(guān)圖片字體。
? ? test:測試用例相關(guān)牲平。
基本命令:
開發(fā)配置:
工具配置:
幾種不同hash:
? ? ? ? hash:跟整個webpack構(gòu)建項目相關(guān)的堤框,每次項目構(gòu)建hash對應(yīng)的值都是不同的,即使項目文件沒有做“任何修改”(其實是有修改的,因為每次webpack打包編譯都會注入webpack的運行時代碼蜈抓,導(dǎo)致整個項目有變化启绰,所以每次hash值都會變化的。).該方式是無法達(dá)到緩存的沟使,因為每次hash都會變化
? ??chunkhash:它是跟webpack打包的chunk相關(guān)的委可,具體來說webpack是根據(jù)入口entry配置文件來分析其依賴項并由此來構(gòu)建該entry的chunk,并生成對應(yīng)的hash值腊嗡。不同的chunk會有不同的hash值着倾。一般在項目中把公共的依賴庫進(jìn)行單獨打包構(gòu)建,用chunkhash來生成hash值燕少,只要依賴公共庫不變卡者,那么其對應(yīng)的chunkhash就不會變,從而達(dá)到緩存的目的客们。
contenthash:contenthash表示由文件內(nèi)容產(chǎn)生的hash值崇决,內(nèi)容不同產(chǎn)生的contenthash值也不一樣。在項目中镶摘,通常做法是把項目中css都抽離出對應(yīng)的css文件來加以引用嗽桩。比方在上面a.html中依賴一個index.css文件,index.css的hash是跟著a.html的chunkhash走的凄敢,只要a.html文件變更的話碌冶,那么即使index.css文件沒有變化,它的hash值也是會跟著變化的涝缝,導(dǎo)致緩存失效扑庞,那么這時我們可以使用extra-text-webpack-plugin里的contenthash值,保證即使css文件所處的模塊里就算其他文件內(nèi)容改變拒逮,只要css文件內(nèi)容不變罐氨,它的hash值就不會變。
file-loader的hash:?對于圖片滩援、字體等靜態(tài)資源栅隐,在使用webpack構(gòu)建提取時,其實是使用了file-loader來完成的玩徊,生成對應(yīng)的文件hash值也就是由對應(yīng)的file-loader來計算的租悄。那么這些靜態(tài)文件的hash值不是webpack每次項目構(gòu)建的hash,它是由file-loader根據(jù)文件內(nèi)容計算出來的恩袱,不要誤認(rèn)為是webpack構(gòu)建的hash泣棋。
打包結(jié)果分析:
官方:Offical Analyse Tool:
?????Mac :webpack --profile --json > stats.json
?????Windows :webapck --profile --json | Out-file 'state.json' - Encoding OEM
在state.json會有打包的信息,帶著json文件去 http://webpack.github.io/analyse/?
社區(qū):webpack-bundle-analyzer:
使用方式:
? ? 插件:BundleAnalyzerPlugin
? ? 命令行:webpack-bundle-analyzer state.json
vue-cli2腳手架優(yōu)化
1畔塔、圖片相關(guān)
生產(chǎn)環(huán)境圖片壓縮潭辈。
合成雪碧圖:我們一般按模塊進(jìn)行開發(fā)鸯屿,為了方便管理,模塊相關(guān)非共用資源獨立和模塊放在一起把敢。
出現(xiàn)情況分析:
? ? 1冰肴、模塊a中同時引用自己的雪碧圖和公共的雪碧圖,打包會把 兩者合成1張圖榔组。
? ? 2熙尉、模塊a和b中同時引用自己的雪碧圖和公共的雪碧圖,三者打包會 合成1張圖搓扯。
2检痰、css全局樣式相關(guān)
我們可能需要引入全局樣式(比如sass的mixin,variable)。
????如果你想在main.js中import xx.scss锨推,那是無效的铅歼,因為vue-loader的loader不支持對.scss文件的處理(你可以自己去配loader)。
? ? 你可以在每個vue模塊中去@import xxx.scss换可,如果是全局樣式椎椰,那太繁瑣。
????更方便的方法是 使用sass-resources-loader插件,來實現(xiàn)sass全局變量及方法注入沾鳄。
3慨飘、TreeShaking相關(guān)
????js-shaking是ok的,我們主要針對.vue文件進(jìn)行css treeshaking
? ??我想對.vue文件進(jìn)行css treeshaking译荞,我用了purgecss-webpack-plugin或者purifycss-webpack插件瓤的,他們對于指定的js文件或者h(yuǎn)tml文件是可以正常進(jìn)行 treeshaking的,但是對于指定的.vue文件吞歼,并不起效圈膏。
4、代碼分割和長緩存優(yōu)化相關(guān)
? ? webpack-runtime提取和vendor(凡是引用了node_modules中文件的資源都被歸為vendor)提取和異步代碼塊中的公共代碼提取(require.include和CommonsChunkPlugin的async都可以做到)篙骡,vue-cli2都幫我們做到了稽坤。
? ? 單入口同步公共代碼塊貌似現(xiàn)在不支持單獨提取出來打包。
? ? 我們可以優(yōu)化的點:生產(chǎn)環(huán)境使用new webpack.NamedChunksPlugin()插件糯俗,把打包文件的chunksId由原來的序號(當(dāng)有新獨立文件產(chǎn)生,同時會影響其他文件chunkId)轉(zhuǎn)為文件名(不變)慎皱,因為id會影響chunkName,為了保持其他文件的長緩存。另外動態(tài)獨立打包的文件和第三方依賴的chankName叶骨,vue-cli2都給我們指定好了。
? ??