成人国产在线小视频_日韩寡妇人妻调教在线播放_色成人www永久在线观看_2018国产精品久久_亚洲欧美高清在线30p_亚洲少妇综合一区_黄色在线播放国产_亚洲另类技巧小说校园_国产主播xx日韩_a级毛片在线免费

資訊專欄INFORMATION COLUMN

webpack4.x升級(jí)摘要

levinit / 2363人閱讀

摘要:以為例,編寫來幫助我們完成重復(fù)的工作編譯壓縮我只要執(zhí)行一下就可以檢測(cè)到文件的變化,然后為你執(zhí)行一系列的自動(dòng)化操作,同樣的操作也發(fā)生在這些的預(yù)處理器上。的使用是針對(duì)第三方類庫使用各種模塊化寫法以及語法。

一:前端工程化的發(fā)展

很久以前,互聯(lián)網(wǎng)行業(yè)有個(gè)職位叫做 “軟件開發(fā)工程師” 在那個(gè)時(shí)代,大家可能會(huì)蒙,放在現(xiàn)今社會(huì),大家會(huì)覺得這個(gè)職位太過籠統(tǒng),所以在此提一下那個(gè)時(shí)候的互聯(lián)網(wǎng)行業(yè)狀態(tài)。

那個(gè)時(shí)候的APP還不是ios/安卓 多數(shù)是嵌入式應(yīng)用(和網(wǎng)頁沒關(guān)系 使用c++或java開發(fā))后續(xù)到了Symbian時(shí)代出現(xiàn)了可移植的sis[x]類型應(yīng)用,曾經(jīng)一統(tǒng)移動(dòng)APP市場(chǎng)。

那個(gè)時(shí)候css百分之90還是用來做布局

那個(gè)時(shí)候js僅僅是為了類似彈出提示的功能而存在的

那個(gè)時(shí)候從服務(wù)器 - 數(shù)據(jù)庫 - 業(yè)務(wù)邏輯 - 頁面 全都由所謂的 “軟件開發(fā)工程師” 來完成

所以大家不必問軟件開發(fā)工程師具體是干啥的,我只能說 啥都干

1:個(gè)人對(duì)前端開發(fā)的體驗(yàn)過程

第一個(gè)階段就是開始對(duì)著W3C的文檔,拿著txt文本文件一個(gè)字母字母的敲著代碼,那個(gè)年代,真的單純舒服,上來就是一個(gè)項(xiàng)目的文件夾,然后就開始img、js、css三個(gè)完美的文件夾,再接上一個(gè)index.html,就開始到網(wǎng)上各種下載類庫jquery、underscore.js,然后手動(dòng)的引入各種類庫,當(dāng)然過程也伴隨著痛苦。

每次來一個(gè)項(xiàng)目就開始建立各種繁瑣的文件夾,和拷貝復(fù)制類庫

引入完類庫的時(shí)候發(fā)現(xiàn)控制臺(tái)報(bào)錯(cuò),$ is not defined,依賴關(guān)系出錯(cuò),部分類庫需要把jquery作為依賴

新寫一個(gè)頁面就需要去重新復(fù)制其他頁面的header資源,維護(hù)變的困難(完全沒有組件化的想法)

部分css3屬性需要自己不斷的手動(dòng)添加樣式前綴

最大的問題再維護(hù)的時(shí)候,不敢輕易的去動(dòng)一些類庫的引入,不清楚各個(gè)庫之前的依賴關(guān)系

第二個(gè)階段就是在接觸到Vue的時(shí)候直接上vue-cli的時(shí)候,幾行腳本就可以啟動(dòng)本地開發(fā)服務(wù)和打包線上資源,初次嘗試了webpack這個(gè)打包工具,好像對(duì)其他問題不需要做過多的考慮,直接開始業(yè)務(wù)開發(fā),其他的事情cli都幫助處理好了。vue init webpack helloWorld, cd helloWorld && cnpm install && npm run dev,真香警告,對(duì)工程化一知半解,但是好用,方便

前端需要一些工具來處理重復(fù)的大量繁瑣的事 (資源壓縮 代碼混淆 css前綴 ),以前會(huì)用Gulp等Task處理任務(wù)

前端需要一些需要用一些預(yù)處理器來處理樣式文件,less以前用第三方工具去編譯 -> less提供的命令行去編譯-> 配置到webpack中自動(dòng)化實(shí)時(shí)編譯

前端需要更加細(xì)粒度的配置一下代碼體積的優(yōu)化,代碼混淆壓縮的操作

前端部分業(yè)務(wù)越多,代碼量越多(文件體積越大)需要做文件合并,壓縮以及按需加載等

開發(fā)階段依然在本地開發(fā),但同時(shí)保持和線上API的同步,為此我們需要本地服務(wù)器(可以是靜態(tài)服務(wù)器)代理轉(zhuǎn)發(fā)(Nginx webpack-dev-server node-server等方式)

第三個(gè)階段就是給公司項(xiàng)目升級(jí)webpack過程中體驗(yàn)到了更細(xì)粒度的控制工程,體驗(yàn)工程化的過程,實(shí)際的體驗(yàn)到了工程化為我們做的事情

模塊化開發(fā),不用在擔(dān)心以往開發(fā)方式帶來的全局作用域的污染問題,當(dāng)然以往也可以通過閉包來實(shí)現(xiàn)私有變量的概念

組件化開發(fā),代碼重用度高,便于維護(hù)

多了構(gòu)建,編譯過程,可以在適當(dāng)?shù)臅r(shí)間去做一些提高工程質(zhì)量的任務(wù),比如代碼規(guī)范的檢測(cè),常用的是Eslint (Airbnb, Prettier 規(guī)范等)

提高開發(fā)效率,比如css瀏覽器前綴的自動(dòng)添加,使用postCss甚至可以提前使用一些好用的東西,比如css變量的概念

通過chunkHash,contentHash 等實(shí)現(xiàn)資源的緩存

根據(jù)工程代碼通過合理的代碼分割提升用戶體驗(yàn),做到按需加載,甚至可以在未來做一些用戶使用的習(xí)慣,做一些提前的預(yù)加載

二:webpack的基本使用 1:webpack和Grunt / Gulp的區(qū)別

這兩類是不同的東西,一個(gè)可以理解為是任務(wù)執(zhí)行器而另外一個(gè)是模塊打包器,任務(wù)執(zhí)行器是可以自動(dòng)化的執(zhí)行一些以前你需要手動(dòng)操作的過程,見下面簡(jiǎn)單的代碼

// coffee 源碼
console.log "Hello World"
  
//coffee轉(zhuǎn) js coffee -c a.coffee
  
(function(){
  console.log("Hello World");
}).call(this);
  
//執(zhí)行編譯壓縮 uglify -s a.js -o a.min.js
(function(){console.log("Hello World")}).call(this);

coffee需要編譯成瀏覽器支持的js,你需要手動(dòng)的去執(zhí)行上面的幾個(gè)命令,如果現(xiàn)在需要去修改源碼,在Hello World 后面加上一個(gè)!,加完你需要手動(dòng)的去執(zhí)行兩條命令重復(fù)的去編譯操作。以 gulp 為例,編寫 gulpfile.js來幫助我們完成重復(fù)的工作

gulp   = require("gulp")
coffee = require("gulp-coffee")
uglify = require("gulp-uglify")
rename = require("gulp-rename")
  
file = "./src/js/a.coffee"
  
gulp.task("coffee", function(){
    gulp.src(file)
        .pipe(coffee())  // 編譯
        .pipe(uglify())  // 壓縮
        .pipe(rename({
            extname: ".min.js"
        }))
        .pipe(gulp.dest("./build/js"))
  
gulp.task("watch", function(){
    gulp.watch(file, ["coffee"])
})
  
gulp.task("default", ["coffee"])

我只要執(zhí)行一下 gulp watch 就可以檢測(cè)到coffee文件的變化,然后為你執(zhí)行一系列的自動(dòng)化操作,同樣的操作也發(fā)生在less, scss, 這些css的預(yù)處理器上。在修改到源文件的情況下的編譯,壓縮這些重復(fù)操作都交由它來完成,在我看來Grunt / Gulp 算是一個(gè)能夠自動(dòng)化執(zhí)行一些繁瑣重復(fù)的操作,提高生產(chǎn)效率,算是一個(gè)任務(wù)執(zhí)行器。

這些操作同樣也可以由webpack完成,接下來我們看一下官網(wǎng)給出的webpack的定義。

webpack is a module bundler

官方給出的解釋是,webpack是一個(gè)模塊打包器,不是一個(gè)任務(wù)執(zhí)行器,它是可以配合Grunt / Gulp 使用的,相關(guān)鏈接webpack集成 。webpack打包器(bundler)幫助你生成準(zhǔn)備用于部署的 JavaScript 和樣式表,將它們轉(zhuǎn)換為適合瀏覽器的可用格式。例如,JavaScript的壓縮、chunk split和懶加載,以提高性能。所以webpack和Gulp/Grunt之間是有一定功能的重疊,但是處理合適,是可以一起配合工作的,不存在所謂的誰替代誰,只是在某些場(chǎng)景下webpack的能夠獨(dú)當(dāng)一面,完成了Grunt/ Gulp的功能。

2:webpack3.x 和 webpack4.x 的對(duì)比

rollup以及Parcel的出現(xiàn),號(hào)稱零配置,足以讓一個(gè)配置成本比較高的webpack出現(xiàn)了4.0版本,當(dāng)然也號(hào)稱零配置使用,開箱即用,現(xiàn)在來一起看看webpack4.x和3.x比較大的區(qū)別,先給出一個(gè)Release鏈接webpack Release v4.0.0下面簡(jiǎn)要的介紹一些大的改動(dòng)

Node環(huán)境的升級(jí),不在支持node 4.0的版本,最低支持6.11.5

配置增加了mode:"production", "development", "none" ,所謂的開箱即用的支持點(diǎn),在不同的mode下開啟了一些默認(rèn)的優(yōu)化手段

生產(chǎn)模式開啟了各種優(yōu)化去生成bundle文件、默認(rèn)開啟作用域提升、process.env.NODE_ENV設(shè)置為production

開發(fā)模式優(yōu)化內(nèi)部rebuild流程,提升開發(fā)效率和體驗(yàn)

刪除了和添加了一些配置項(xiàng),NoEmitOnErrorsPlugin、ModuleConcatenationPlugin(default in production mode)、NamedModulesPlugin(default in development mode) ---> 轉(zhuǎn)到optimization.*的配置項(xiàng)

原生支持處理JSON文件格式,不需要json-loader

內(nèi)置的插件 uglifyjs-webpack-plugin 升級(jí)到了 V1, 而V1是可以支持并行處理壓縮混淆JS的,webpack3之前的內(nèi)置依賴的版本0.4.6 不支持并行處理。常用手段使用webpack-uglify-parallel插件并行處理,利用多核CPU的優(yōu)勢(shì),升級(jí)到webapck4可以不需要了,使用默認(rèn)也可以

一個(gè)算是比較大的改動(dòng),webpack3.x的ComoonsChunkPlugin廢棄,代替的是optimization.splitChunks 和 optimization.runtimeChunk (會(huì)在下文著重介紹)

3:webpack4.x 的一些基本概念

首先先看下圖整體了解一下webpack的一些常用配置項(xiàng)

接下來簡(jiǎn)單的了解一下webpack的一些基本概念

mode:三種模式,production、development、none。設(shè)置mode,webpack會(huì)根據(jù)mode做相應(yīng)的優(yōu)化

entry:入口,webpack會(huì)從入口遞歸尋找所有的依賴,形成依賴關(guān)系圖(dependency graph)。目前應(yīng)用主要分為單入口和多入口,直觀上表現(xiàn)為經(jīng)過webpack處理之后是一個(gè)JS文件還是多個(gè)JS文件(在沒有代碼分割以及懶加載的前提下)

output:輸出,主要通過filename來定義生成chunk的命名,可以通過標(biāo)識(shí)符[name]、[contenthash]、[chunkhash]來實(shí)現(xiàn)資源的緩存,chunkFileName針對(duì)async chunk

loader:loader用于對(duì)模塊的源代碼進(jìn)行轉(zhuǎn)換。既然是模塊打包器,那么就會(huì)出現(xiàn)依賴各種各樣的文件和內(nèi)容,圖片,字體,它們需要經(jīng)過編譯才能被瀏覽器識(shí)別(less、sass,、stylus、ES2015、ts等module) ,都需要通過對(duì)應(yīng)的loader轉(zhuǎn)換成現(xiàn)代瀏覽器支持的東西。loader支持鏈?zhǔn)絺鬟f,loader運(yùn)行在Node.js中,并且能夠執(zhí)行任何可能的操作,比如存在一些不是用來轉(zhuǎn)換文件的loader,thread-loder(多個(gè)node進(jìn)程處理loader轉(zhuǎn)碼文件,提高編譯速度)

plugin:插件和loader不同的地方在于,loader是針對(duì)模塊,比如import以及require的module文件進(jìn)行轉(zhuǎn)碼。plugin是在webapck的complier整個(gè)生命周期中起作用,在這個(gè)編譯階段你可以在提供的hook中執(zhí)行你需要的任何操作。比如htmlWebpackPligun插件,可以在webpack編譯emit文件的鉤子中,生成html去使用這些webpack生成的JS Chunk

module:module的概念可以理解為一個(gè)個(gè)需要加載的文件,Js也好,Css文件也好,都需要經(jīng)過loader處理,module里面的rules去就是配置module需要什么loader去處理

chunks:兩種,init chunks(這些chunks文件是會(huì)以script標(biāo)簽添加到htmlWebpackPlugin生成的html文件中,當(dāng)然也可以通過插件內(nèi)置到html文件中,比如mainifest文件)和async chunks。初始化chunks是從提供給webapck的entries中開始遞歸的尋找依賴的module,生成的一個(gè)chunks。異步的chunks可以理解為是需要按需加載的,主要可以分為以下3個(gè)來源:第一、從初始化的chunk中抽出去的代碼,形成的chunk文件(這個(gè)就是webapck的splitChunk和runtimeChunk的配置)。第二、可以通過webpack識(shí)別的特定語法require.ensure (vue-router中懶加載的寫法)。第三、ES6的動(dòng)態(tài)導(dǎo)入import(/chunkname/)

optimization:這是webpack4.x出現(xiàn)的一個(gè)優(yōu)化類的配置項(xiàng),常用配置項(xiàng):splitChunk、runtimeChunk(下文介紹)、minimize、noEmitOnErrors、namedModules、sideEffects(配合tree shaking使用)等等


resolve:如上圖,這個(gè)配置會(huì)增量的告知webpack如何的去尋找依賴,alias(避免一些深層次引用module代碼的別名)、modules(從哪些目錄尋找依賴)、extensions(module的擴(kuò)展名)、mainFields(第三方類庫存在多個(gè)版本的時(shí)候,優(yōu)先使用哪個(gè)版本)。alias可以手動(dòng)指定第三方庫的使用,比如當(dāng)Vue沒有用CDN的時(shí)候,如果從node_modules引用,引入的代碼是runtime運(yùn)行時(shí)的代碼,是沒有包含解析單文件.vue的template部分的功能,這個(gè)時(shí)候需要依賴它的其他版本,手動(dòng)指定,常見于用Vue-cli去生成項(xiàng)目架構(gòu)的時(shí)候,發(fā)現(xiàn)alias默認(rèn)有一項(xiàng),告知webpack引入Vue的時(shí)候module的位置是vue/dist/vue.esm.js(包含了解析template的代碼)。mainFields的使用是針對(duì)第三方類庫使用各種模塊化寫法以及語法。有ES6的mport、export的,也有CommonJs的模塊導(dǎo)出。有壓縮的min.js也有Ts版本的,這些會(huì)在package.json中看到,至于引入第三方模塊的引入那個(gè)版本,對(duì)于一些成熟的類庫比如Vue,Vue-router等有多個(gè)版本,可以通過設(shè)置mainFields告知webpack從package.json中的那個(gè)字段導(dǎo)入類庫。ES6的improt、export存在靜態(tài)分析,配合tree shaking使用,這也是webpack號(hào)稱能提速98%的原因,但是目前的狀況是第三方庫參差不齊,很多都沒有提供ES6模塊導(dǎo)出的版本,所有目前效果還不是很理想

externals:指定外部擴(kuò)展。從bundle中排除依賴,比如項(xiàng)目一些基本不會(huì)變更版本的第三方類庫,通過引用CDN資源,常見Vue、VueRouter、element-ui、echart等等類庫

devServer:開發(fā)模式的配置。在webpack4.x之前的版本通過node的express框架搭建的本地服務(wù)器,配合webpack-dev-middleware和webpack-hot-middleware搭建的開發(fā)環(huán)境?,F(xiàn)在可以通過webapck-dev-server類庫結(jié)合devServer配置項(xiàng)去開啟本地開發(fā)環(huán)境,這個(gè)類庫封裝了express的操作,同時(shí)內(nèi)部使用了webpack-dev-middleware。給出配置鏈接:devServer配置項(xiàng)

三:項(xiàng)目webpack升級(jí)流程

先簡(jiǎn)短的介紹一下項(xiàng)目,升級(jí)的項(xiàng)目為多入口項(xiàng)目,每個(gè)module模塊代碼一個(gè)入口,然后共用很多業(yè)務(wù)組件

*/build
    webpack.base.conf.js   // dev和prod共用部分
    webpack.dev.conf.js     // dev模式下特有配置
    webapck.prod.conf.js   // prod模式下特有配置
*/common
    components // 多個(gè)模塊共用的組件
    assets // 靜態(tài)資源    
*/src
    module1  // 模塊1的代碼
        index.js  // 模塊1代碼的入口
    module2  // 模塊2的代碼
    module3  // 模塊3的代碼
*/mock
    mock-xxx.js  // mock api的接口
*/config // 配置文件
    index.js
    dev.js
    prod.js 
1:package.json依賴的管理

升級(jí)webpack,安裝webpack-cli。全局安裝npm-check-updates,查看package.json中可升級(jí)的依賴的版本。

cnpm install -g npm-check-updates  //全局安裝
  
// 在項(xiàng)目根目錄下執(zhí)行ncu
ncu
  
// 可升級(jí)的依賴,列舉部分依賴情況
axios 0.17.1 --> 0.18.0
webpack  3.5.5 --> 4.16.5
webpack-merge 4.1.0 --> 4.1.4
  
// 升級(jí)webpack 安裝webpack-cli
cnpm install webpack webpack-cli --save-dev
  
// 升級(jí)相應(yīng)的loader和plugin
cnpm install url-loader file-loader vue-loader sass-loader css-loader babel-loader html-webpack-plugin --save-dev
2:修改webpack配置

公司使用的vue-cli2.0的腳手架生成的項(xiàng)目,簡(jiǎn)單的列舉關(guān)于webpack的目錄,針對(duì)需要可進(jìn)行自行調(diào)整

*/build
    webpack.base.conf.js   // dev和prod共用部分
    webpack.dev.conf.js     // dev模式下特有配置
    webapck.prod.conf.js   // prod模式下特有配置

// 通過webpack-merge合并配置輸出最后的webpack配置

1:增加mode模式

// webpack.dev.conf.js 開發(fā)模式的配置 開啟webpack默認(rèn)的配置優(yōu)化
mode: "development"
  
// webpack.prod.conf.js 生產(chǎn)模式的配置
mode: "production"

2:升級(jí)vue-loader,vue-loaderv.15版本和之前的有所區(qū)別,vue-loader不在使用自身的配置,而是解析.vue文件之后使用webpack里配置的loader,詳細(xì)文檔見Vue-loader的使用,補(bǔ)充一點(diǎn):在.vue 文件中style提供的scoped標(biāo)記,就是通過vue-loader去實(shí)現(xiàn)在template中加入了適當(dāng)?shù)膆ash,配合樣式去做到組件內(nèi)樣式的獨(dú)立

// webpack.config.js
const VueLoaderPlugin = require("vue-loader/lib/plugin")  // 插件解析.vue文件把template script style 分別交給webpack配置的loader去處理
 
module.exports = {
  // ...
  plugins: [
    new VueLoaderPlugin()
  ]
}

3:部分webpack的插件已經(jīng)配置停用。如有的話,按照提示刪除掉,比如module里的loaders,webpack4不再支持。然后部分插件轉(zhuǎn)化為通過optimazation 進(jìn)行配置,主要配置點(diǎn)在于code split以及mainifest文件的提取,同樣見下文splitChunks和runtimeChunks的分析

4:開發(fā)模式加入devServer。項(xiàng)目是否需要通過手動(dòng)node搭建本地服務(wù)器,取決于是否需要node層面去處理其他東西,在公司項(xiàng)目中啟動(dòng)服務(wù)前有兩個(gè)操作,編譯scss文件(皮膚文件),以及mock文件夾(mock接口),所以還是保留了手動(dòng)檔搭建node層面啟動(dòng)服務(wù),其實(shí)完全可以有webpck-dev-server的before,after配置項(xiàng)完成

// 下面代碼塊針對(duì)devServer的部分配置項(xiàng)做說明,結(jié)合相關(guān)知識(shí)進(jìn)行分析
devServer: {
   contentBase: path.join(__dirname, "../static"),   // 靜態(tài)資源提供,不是webpack生成的bundle,生成的bundle在內(nèi)存中見注釋1
   host: host || "localhost",  // 主機(jī)名,如果你希望服務(wù)器外部可訪問,需要設(shè)置為0.0.0.0,默認(rèn)localhost
   port: process.env.PORT || port, // 端口號(hào)
   historyApiFallback: true,      // handle fallback for HTML5 history API 了解一下這個(gè)東西見注釋2
   proxy: proxyTable,    // 后端接口轉(zhuǎn)發(fā)見注釋3
   hot: true,   // 熱更新見注釋4
   quiet: true,  // webpack打包信息省略
   publicPath: assetsPublicPath,  // bundle 的位置 outpath: publicPath 類似
   clientLogLevel: "none"  // HRM WDS 在瀏覽器控制臺(tái)的輸出
}
  
// 注釋1:寫過express的就知道有一個(gè)指定static中間件用來指定資源目錄的
const express = require("express")
const app = express()
  
app.use(staticPath, express.static(xxx))  // xxx/js/vendor.js,就可以通過localhost:prot/staticPath/js/vendor.js訪問相關(guān)靜態(tài)資源。所以contentBase就是利用express靜態(tài)中間價(jià)提供個(gè)一種訪問靜態(tài)資源文件的能力
  
// 注釋2:vue-router的history模式充分利用 history.pushState API 來完成 URL 跳轉(zhuǎn)而無須重新加載頁面 example: history.pushState({a:1}, "測(cè)試", "/attendance/index") ,然后內(nèi)部去處理相應(yīng)的router對(duì)象的展示Vue頁面和邏輯,所以這就是你順著程序點(diǎn)路由可以進(jìn)去,但是刷新的時(shí)候,就顯示404的原因,因?yàn)樵撀酚稍诜?wù)器上不是真實(shí)存在的,而是在index.html中通過JS去解析模擬的,這就需要我們生產(chǎn)模式下生產(chǎn)的dist文件所有的請(qǐng)求都轉(zhuǎn)發(fā)到index.html。處理方式:在服務(wù)器上通過nignx 代理,或者起一個(gè)express服務(wù),通過第三方類庫 connect-history-api-fallback,當(dāng)然也可以原生Node去寫,此時(shí)Node只是一個(gè)文件服務(wù)器
  
const http = require("http")
const fs = require("fs")
const httpPort = 80
 
http.createServer((req, res) => {
  fs.readFile("index.htm", "utf-8", (err, content) => {
    if (err) {
      console.log("We cannot open "index.htm" file.")
    }
 
    res.writeHead(200, {
      "Content-Type": "text/html; charset=utf-8"
    })
 
    res.end(content)
  })
}).listen(httpPort, () => {
  console.log("Server listening on: http://localhost:%s", httpPort)
})
  
// 注釋3:請(qǐng)求代理,常常被問起跨域請(qǐng)求有哪些方案,jsonp、CORS(后端配合)、window iframe等方式,還有一個(gè)就是通過node代碼轉(zhuǎn)發(fā)請(qǐng)求,服務(wù)端請(qǐng)求不存在跨域的概念,webpack中可以node自己使用http-proxy-middleware 去進(jìn)行代理,本次更新使用的wbepack-dev-server模塊同時(shí)也依賴了http-proxy-middleware的庫,目前Node不作為純后端,而是作為中間代碼,連接純后端(java php)和前端。
  
// 注釋4:熱更新,它允許在運(yùn)行時(shí)更新各種模塊,而無需進(jìn)行完全刷新,目前的公司項(xiàng)目都是純刷新的方式,熱更新HRM,這個(gè)是需要你是用的loader或插件幫助你完成,他們能監(jiān)聽webpck complier期間得鉤子,然后給出相應(yīng)源碼更新后需要patch,推送到前端,打補(bǔ)丁,然后實(shí)現(xiàn)熱更新,而不是刷新整個(gè)頁面去重新加載頁面。好處自然提高開發(fā)效率,在修改.vue文件的tempalte和style以及script中不是vue生命周期函數(shù)時(shí),是能夠保留到當(dāng)時(shí)的vue的各種狀態(tài)

5:針對(duì)生產(chǎn)模式的優(yōu)化配置,廢棄生產(chǎn)模式中使用的優(yōu)化插件,轉(zhuǎn)為webpack4的optimization.* 配置

NoEmitOnErrorsPlugin // 編譯錯(cuò)誤跳過編譯階段,不生成文件 (default in production)

ModuleConcatenationPlugin // 作用域提升,加快代碼執(zhí)行 (default in production)

NamedModulesPlugin // 默認(rèn)的module在打包進(jìn)入chunks的時(shí)候都會(huì)以module.id 為標(biāo)識(shí)(這個(gè)是隨著依賴遞增的),這會(huì)影響到緩存,使用這個(gè)插件將會(huì)使用文件的路徑作為標(biāo)識(shí),詳細(xì)見splitChunks and runtimeChunk分析

CommonsChunkPlugin // 最為晦澀難懂的webpack插件,作用代碼分割,被splitChunks && runtimeChunks代替

下面為升級(jí)之前的配置

// 依賴module(require, import 導(dǎo)入的文件)來自node_modules且以.js 結(jié)尾的文件將會(huì)被打包到名為vendor的bundle中
new webpack.optimize.CommonsChunkPlugin({
    name: "vendor",
    minChunks: function (module, count) {
        // any required modules inside node_modules are extracted to vendor
        return (
            module.resource &&
            /.js$/.test(module.resource) &&
            module.resource.indexOf(
                path.join(__dirname, "../node_modules")
            ) === 0
        )
    }
}),
 
// 在vendor的bundle中把manifest提取出來(mainifest算是webpack實(shí)現(xiàn)的在瀏覽器端進(jìn)行模擬加載模塊和具體加載邏輯的代碼塊,這個(gè)最好拆出來,不然沒法做緩存,具體見到長效緩存分析)
new webpack.optimize.CommonsChunkPlugin({
    name: "manifest",
    chunks: ["vendor"]
})
  
// 打包之后就會(huì)生成一個(gè)vendor.js (里面有著來自node_modules 的第三方類庫)和 mainifest.js (具體加載邏輯)

升級(jí)之后,完成原有的配置很簡(jiǎn)單,簡(jiǎn)單的照著API實(shí)現(xiàn)即可,本次升級(jí)伴隨著兩個(gè)重點(diǎn),開發(fā)模式的rebuild時(shí)間,生成環(huán)境的打包文件體積和時(shí)間,所以還需要做其他優(yōu)化

某些第三方類庫只有某個(gè)module才加載,比如只有module1中用mint-ui,這是可以多帶帶提出來一個(gè)chunk或者直接就加載到module1這個(gè)入口的init chunk中 ----> 配置層面

某些公共組件比如component下公共組件layout在基本每個(gè)系統(tǒng)模塊全部都條用了,可以考慮拉出來共用,減少重復(fù)代碼量 ----> 配置層面

利用ES的語法去動(dòng)態(tài)的引入模塊import("a.js").then(module => {})去懶加載一個(gè)模塊,比如只有在某些vue中才會(huì)用到的vue-qrcode-component的類庫,這個(gè)類庫不應(yīng)該出現(xiàn)在vendor中(來自node_modules) ----> 代碼層面

optimization: {
  splitChunks: {
    cacheGroups: {
        // module只要滿足下面就會(huì)從原來的chunks中抽取出來打包到對(duì)應(yīng)的chunks之中
        // 這個(gè)vendors是在至少同時(shí)有兩個(gè)initial Chunk中引入的來自node_modules的第三方類庫會(huì)被打包到chunks-vendors中
        vendors: {
            name: "chunk-vendors",
            test: /[/]node_modules[/]/,
            priority: -10,
            minChunks: 2,    // 至少同時(shí)有幾個(gè)chunk滿足才會(huì)有可能從這些chunks中提取一些代碼到新的chunk中,也就是至少兩個(gè)共用才會(huì)提取,不然就直接打包都所在module的init chunk中
            chunks: "initial"  // chunk的概念:代碼分割這些操作作用于那些chunk文件,initial是通過提供給webpack入口生成的chunks, async是通過之前提到的import()  路由懶加載形成的chunk, all就是所有的chunk文件
        },
        // 這個(gè)common跟上面的區(qū)別在于沒有test檢測(cè)module來源,只是只要有兩個(gè)chunk共用就是提取出來,很顯然就范圍來講,下面的大于上面,這時(shí)候到底這個(gè)來自node_modules的module進(jìn)入哪個(gè)chunk,取決于priority(優(yōu)先級(jí)),誰高進(jìn)入哪個(gè)chunk
        common: {
            name: "chunk-common",
            minChunks: 2,
            priority: -12,
            chunks: "initial",
            minSize: 0
        }
    }
  },
  runtimeChunk: {
    name: "manifest"
  }
}
 
// 比如某些第三方類庫只在某個(gè)Vue文件中使用,通過動(dòng)態(tài)引入import("vue-qrcode-component").then() 一個(gè)類庫只在一個(gè)地方用,完全沒有必要打包到vendor中(因?yàn)関ue-qrcode-component 來自node_module)
// import 就是新建一個(gè)chunk  這個(gè)chunk是沒有名字的,需要通過/* webpackChunkName: "loadsh"*/ 生成這個(gè)loadsh的chunk.name
import(/* webpackChunkName: "loadsh"*/ "loadsh").then(m => {
    const _ = m.default
    console.log(_.join(["hello", "world"]))
})

總結(jié):一般經(jīng)過這幾步驟就能完成一個(gè)webapck項(xiàng)目的升級(jí),對(duì)于自己項(xiàng)目的復(fù)雜的地方需要額外的處理,寫著寫著發(fā)現(xiàn)篇幅越來越長了,把上文一直出現(xiàn)的splitChunk和runtimeChunk留到下個(gè)篇幅著重介紹一下。在公司做升級(jí)之前,給的指標(biāo)不僅僅是升級(jí)框架,還需要在dev模式開發(fā)的rebuild的速度更快(修改一個(gè)地方,rebuild的時(shí)間12s左右才能看到效果,痛苦,可以通過lessModule來解決),在prod模式下打包的項(xiàng)目文件體積減小已經(jīng)打包所需要的時(shí)間更短(一次測(cè)試環(huán)境發(fā)布需要5,6分鐘)。現(xiàn)在vue-cli3.0已經(jīng)出現(xiàn)了,找時(shí)間把vue-cli3.0源碼給大家分析一下,簡(jiǎn)單的包裝了一下操作

文章版權(quán)歸作者所有,未經(jīng)允許請(qǐng)勿轉(zhuǎn)載,若此文章存在違規(guī)行為,您可以聯(lián)系管理員刪除。

轉(zhuǎn)載請(qǐng)注明本文地址:http://systransis.cn/yun/104805.html

相關(guān)文章

  • webpack4.x深入與實(shí)踐

    摘要:它將根據(jù)模塊的依賴關(guān)系進(jìn)行靜態(tài)分析,然后將這些模塊按照指定的規(guī)則生成對(duì)應(yīng)的靜態(tài)資源??梢詫⒍喾N靜態(tài)資源轉(zhuǎn)換成一個(gè)靜態(tài)文件,減少了頁面的請(qǐng)求。因此我們不再按文件文件的方式運(yùn)行指令,而是直接運(yùn)行這樣便能實(shí)現(xiàn)打包。 一、什么是webpack 是一個(gè)前端資源加載/打包工具。它將根據(jù)模塊的依賴關(guān)系進(jìn)行靜態(tài)分析,然后將這些模塊按照指定的規(guī)則生成對(duì)應(yīng)的靜態(tài)資源。它做的事情是,分析你的項(xiàng)目結(jié)構(gòu),找到J...

    Lsnsh 評(píng)論0 收藏0
  • 基于webpack4.x, babel7.x 搭建的多頁面腳手架, 簡(jiǎn)化前端開發(fā)環(huán)境配置,開箱即用,

    摘要:開箱即用的多頁面腳手架基于模塊化開發(fā)可復(fù)用的現(xiàn)代化網(wǎng)站感興趣的朋友,請(qǐng)點(diǎn)個(gè)及時(shí)關(guān)注項(xiàng)目更新請(qǐng)點(diǎn)個(gè)項(xiàng)目請(qǐng)?zhí)崽匦灾С智昂蠖朔蛛x開發(fā)配置完整的打包方案支持本地開發(fā)熱更新集成代碼風(fēng)格校驗(yàn)支持編寫源碼,編譯生成生產(chǎn)代碼內(nèi)置開發(fā)環(huán)境,自動(dòng)加樣式前綴自 Webpack-seed 開箱即用的多頁面腳手架, 基于webpack4.2x babel7.1x模塊化開發(fā)可復(fù)用的現(xiàn)代化網(wǎng)站(Without Vu...

    junfeng777 評(píng)論0 收藏0
  • webpack4.x 模塊化淺析-CommonJS

    摘要:先看下官方文檔中對(duì)模塊的描述在模塊化編程中,開發(fā)者將程序分解成離散功能塊,并稱之為模塊。每個(gè)模塊具有比完整程序更小的接觸面,使得校驗(yàn)調(diào)試測(cè)試輕而易舉。 先看下webpack官方文檔中對(duì)模塊的描述: 在模塊化編程中,開發(fā)者將程序分解成離散功能塊(discrete chunks of functionality),并稱之為模塊。每個(gè)模塊具有比完整程序更小的接觸面,使得校驗(yàn)、調(diào)試、測(cè)試輕而易...

    alphahans 評(píng)論0 收藏0
  • 借騰訊開源 VasDolly,談?wù)?Android 簽名和多渠道打包的原理!

    摘要:前幾天,企鵝電競(jìng)團(tuán)隊(duì)開源了自己的多渠道打包工具,比美團(tuán)的更全面一些。四可商用的多渠道打包方案在開源之前,市面上支持簽名的多渠道打包方案,就屬美團(tuán)的了,下面簡(jiǎn)單比對(duì)一下它們的優(yōu)缺點(diǎn)。 showImg(https://segmentfault.com/img/remote/1460000013436224?w=900&h=500); 一、前言 Hi,大家好,我是承香墨影! 當(dāng)我們需要發(fā)布一...

    LMou 評(píng)論0 收藏0

發(fā)表評(píng)論

0條評(píng)論

最新活動(dòng)
閱讀需要支付1元查看
<