日韩性视频-久久久蜜桃-www中文字幕-在线中文字幕av-亚洲欧美一区二区三区四区-撸久久-香蕉视频一区-久久无码精品丰满人妻-国产高潮av-激情福利社-日韩av网址大全-国产精品久久999-日本五十路在线-性欧美在线-久久99精品波多结衣一区-男女午夜免费视频-黑人极品ⅴideos精品欧美棵-人人妻人人澡人人爽精品欧美一区-日韩一区在线看-欧美a级在线免费观看

歡迎訪問 生活随笔!

生活随笔

當(dāng)前位置: 首頁 > 编程资源 > 编程问答 >内容正文

编程问答

html公共模块提取出去,webpack 填坑之路--提取独立文件(模块)

發(fā)布時間:2025/3/13 编程问答 31 豆豆
生活随笔 收集整理的這篇文章主要介紹了 html公共模块提取出去,webpack 填坑之路--提取独立文件(模块) 小編覺得挺不錯的,現(xiàn)在分享給大家,幫大家做個參考.

前言

最近重新看了一遍 webpack 提取公共文件的配置。原來覺得這東西是個玄學(xué),都是 “憑感覺” 配置。這篇文章將以解決實(shí)際開發(fā)遇到的問題為核心,悉數(shù)利用 webpack 提取獨(dú)立文件(模塊)的應(yīng)用。

獨(dú)立文件在實(shí)際開發(fā)中一般有兩種:

第三方模塊 如 Vue React jQuery 等

項(xiàng)目開發(fā)編寫的獨(dú)立模塊(模塊),對于 MPA 多頁面開發(fā)來說是封裝出的一些方法庫比如 utils.getQueryString() 或者是每個頁面的共同操作;對于SPA 應(yīng)用來說沒有特別的需要分離出模塊,但是針對首屏渲染速度的提升,可以將 某些獨(dú)立模塊分離出來實(shí)現(xiàn)按需加載。

分離出獨(dú)立文件的目的:

獨(dú)立文件一般很少更改或者不會更改,webpack 沒必要每次打包進(jìn)一個文件中,獨(dú)立文件提取出可以長期緩存。

提升 webpack 打包速度

提取第三方模塊

配置externals

Webpack 可以配置 externals 來將依賴的庫指向全局變量,從而不再打包這個庫。

// webpack.config.js 中

module.exports = {

entry: {

app: __direname +'/app/index.js'

}

externals: {

jquery: 'window.jQuery'

}

...

}

// 模板 html 中

...

...

// 入口文件 index.js

import $ from 'jquery'

其實(shí)就是 script 標(biāo)簽引入的jquery 掛載在window下 其他類型 externals 的配置可以去官網(wǎng)查看,這種方法不算是打包提取第三方模塊,只是一個變量引入,不是本文討論的重點(diǎn)。

利用CommonsChunkPlugin

CommonsChunkPlugin 插件是專門用來提取獨(dú)立文件的,它主要是提取多個入口 chunk 的公共模塊。他的配置介紹如下:

配置屬性

配置介紹

name 或者 names

chunk 的名稱 如果是names數(shù)組 相當(dāng)于對每個name進(jìn)行插件實(shí)例化

filename

這個common chunk 的文件輸出名

minChunks

通常情況為一個整數(shù),至少有minChunks個chunk使用了該模塊,該模塊才會被移入[common chunk]里 minChunks 還可以是Infinity意思為沒有任何模塊被移入,只是創(chuàng)建當(dāng)前這個 chunk,這通常用來生成 jquery 等第三方代碼庫。minChunks還可以是一個返回布爾值的函數(shù),返回 true 該模塊會被移入 common chunk,否則不會。默認(rèn)值是 chunks 的長度。

chunks

元素為chunk名稱的數(shù)組,插件將從該數(shù)組中提取common chunk 可見 minChunks 應(yīng)該小予chunks的長度,且大于1。如果沒有 所有的入口chunks 會被選中

children

默認(rèn)為false 如果為true 相當(dāng)于為上一項(xiàng)chunks配置為chunk的子chunk 用于代碼分割code split

async

默認(rèn)為false 如果為true 生成的common chunk 為異步加載,這個異步的 common chunk 是 name 這個 chunk 的子 chunk,而且跟 chunks 一起并行加載

minSize

如果有指定大小,那么 common chunk 的文件大小至少有 minSize 才會被創(chuàng)建。非必填項(xiàng)。

創(chuàng)建一個如下圖的目錄

package.json 如下

{

"name": "webpacktest",

"version": "1.0.0",

"description": "",

"directories": {

"doc": "doc"

},

"scripts": {

"start": "webpack"

},

"author": "abzerolee",

"license": "ISC",

"devDependencies": {

"html-webpack-plugin": "^2.30.1",

"webpack": "^3.8.1"

},

"dependencies": {

"underscore": "^1.8.3",

}

}

a.js 引入了 underscore 需要進(jìn)行了數(shù)組去重操作,現(xiàn)在需要將underscore分離為獨(dú)立文件。

// webpack.config.js

entry: {

a: __dirname +'/app/a.js',

vendor: ['underscore']

},

output: {

path: __dirname +'/dist',

filename: '[name].[chunkhash:6].js',

chunkFilename: '[name].[id].[chunkhash:6].js'

},

plugins: [

new webpack.optimize.CommonsChunkPlugin({

name: 'vendor',

}),

new HtmlWebpackPlugin({

template: __dirname +'/app/index.html'

})

]

// a.js

let _ = require('underscore');

let arr = _.filter([1,2,3,2,3,3,5,5], (v, i, self) => self.indexOf(v) === i);

console.log('unique:' +arr);

這樣underscore就分離進(jìn)了 vendor 塊,注意的是需要在入口定義 要輸出的 [ 獨(dú)立文件名 ]: [ 需要分離的模塊數(shù)組 ], 然后在CommonsChunkPlugin中配置 name : [獨(dú)立文件名]。

當(dāng)然也可以不用在入口定義,如vue-cli 就是在 在CommonsChunk中配置了minChunks。我們的第三方模塊都是通過npm 安裝在node_modules 目錄下,我們可以通過minChunks 判斷模塊路徑是否含有node_module 來返回true 或 false,前文有介紹minChunks的含義。配置如下:

entry: {

a: __dirname +'/app/a.js', // **注意** 入口沒定義vendor

},

output: {

path: __dirname +'/dist',

filename: '[name].[chunkhash:6].js',

chunkFilename: '[name].[id].[chunkhash:6].js'

},

plugins: [

new webpack.optimize.CommonsChunkPlugin({

name: 'vendor',

minChunks: function(module) {

let flag = module.context && module.context.indexOf('node_modules') !== -1;

console.log(module.context, flag);

return flag;

}

}),

new HtmlWebpackPlugin({

template: __dirname +'/app/index.html'

})

]

上述兩種方式,對于多頁面還是單頁面都是可應(yīng)用的。但是現(xiàn)在的問題是每次入口文件 a.js 修改之后都會造成 vendor重新打包。那么如何解決這個問題呢。

manifest 處理第三方模塊應(yīng)用

我們將 a.js 做一個簡單修改:

// 原來

- console.log('unique:' +arr);

// 修改后

+ console.log(arr);

重新打包發(fā)現(xiàn)vendor的hash變化了相當(dāng)于重新打包了underscore,解決的方法是利用一個 manifest 來記錄 vendor 的 id ,如果vendor沒改變,則不需要重新打包。這就有兩種解決方式 :

1. 利用manifest.js

利用CommonsChunkPlugin的chunks特性,提取出 webpack定義的異步加載代碼,配置如下:

entry: {

a: __dirname +'/app/a.js',

},

output: {

path: __dirname +'/dist',

filename: '[name].[chunkhash:6].js',

chunkFilename: '[name].[id].[chunkhash:6].js'

},

plugins: [

new webpack.optimize.CommonsChunkPlugin({

name: 'vendor',

minChunks: function(module) {

let flag = module.context && module.context.indexOf('node_modules') !== -1;

console.log(module.context, flag);

return flag;

}

}),

new webpack.optimize.CommonsChunkPlugin({

name: 'manifest',

chunks: ['vendor'],

}),

new HtmlWebpackPlugin({

template: __dirname +'/app/index.html'

})

]

還是修改了 a.js 之后發(fā)現(xiàn) vendor的 hash 值沒有變化,如下圖:

這里要注意的是chunks: [ 獨(dú)立文件名 ]。但是,又有但是,要是這么就配置沒問題了,就不能叫做玄學(xué)了,修改 a.js 的內(nèi)部代碼沒問題,如果修改了 require 的模塊引入,vendor的hash又有變化了,當(dāng)然我們可以盡量避免修改文件的依賴引入,但是終歸不是最完美的方式。那么終極解決方法是什么呢?DllReferencePlugin,DllPlugin。

2. 利用DllReferencePlugin,DllPlugin

既然動態(tài)打包的時候建立 manifest 不行,那么能不能直接把他打包成一個純凈的依賴庫,本身無法運(yùn)行,只是讓我們的app 來引入。

那么我們需要完成兩步,先webpack.DllPlugin打包dll(純凈的第三方獨(dú)立文件),然后用DllReferencePlugin 在我們的應(yīng)用中引用,這樣的好處是如果下一個項(xiàng)目還是使用一樣的依賴比如react react-dom react-router,可以直接引入這個dll。

配置文件如下:

entry: {

vendor: ['underscore']

},

output: {

path: __dirname +'/dist',

filename: '[name].js',

library: '[name]',

},

plugins: [

new webpack.DllPlugin({

path: __dirname +'/dist/manifest.json',

name: '[name]',

context: __dirname,

}),

],

根據(jù)上述配置打包結(jié)果如上圖,dist目錄下現(xiàn)在有一個vender.js 和 manifest.json 注意這里輸出的路徑配置。DllPlugin配置介紹如下:

配置項(xiàng)

介紹

path

path 是 manifest.json 文件的輸出路徑,這個文件會用于后續(xù)的業(yè)務(wù)代碼打包;

name

name 是 dll 暴露的對象名,要跟 output.library 保持一致;

context

context 是解析包路徑的上下文,這個要跟接下來配置的 webpack.config.js 一致。

之后在我們的應(yīng)用中引入中,配置如下:

entry: {

a: __dirname +'/app/a.js',

},

output: {

path: __dirname +'/dist',

filename: '[name].[chunkhash:6].js',

chunkFilename: '[name].[id].[chunkhash:6].js'

},

plugins: [

new webpack.DllReferencePlugin({

context: __dirname,

manifest: require('./dist/manifest.json'),

}),

new HtmlWebpackPlugin({

template: __dirname +'/app/index.html'

})

]

根據(jù)上述配置打包得到a.3e6285.js index.html 如上圖,瀏覽器中打開index.html會顯示

Uncaught ReferenceError: vendor is not defined

這里需要在 index.html 中 a.3e6285.js 插入 script 標(biāo)簽

再打開index.html 可以控制臺打印出了數(shù)組去重的結(jié)果。插入標(biāo)簽的這一步可以在打包好獨(dú)立文件之前,就在模板html 中插入。

到了這里,提取第三方模塊的方法,避免重復(fù)打包的方法都介紹完畢了。接下來是配置提取自己編寫的公共模塊方法。

提取項(xiàng)目公共模塊

單頁面應(yīng)用的公共模塊沒有必要提取出單獨(dú)的文件,因?yàn)椴槐乜紤]復(fù)用的情況。但是對于打包生成的文件過大,我們又想分離出幾個模塊有需要的時候才加載,其實(shí)這并不是提取公共模塊,而是代碼分割,通過:

require.ensure(dependencies: String[], callback: function(require), chunkName: String)

在callback中定義的 require的模塊將會獨(dú)立打包,并且插入在 html 的head標(biāo)簽,這里就不做更多介紹了。

多頁面應(yīng)用是有必要抽取公共模塊的,比如a.js 引用了lib1, b.js 也引用了 lib1 那么lib1,那么我們肯定希望在提取出 lib1 同時還可以提取出第三方庫,配置文件如下:

// a.js

let _ = require('underscore');

let lib1 = require('./lib1');

console.log('this is entry_a import lib1');

let arr = _.filter([1,2,3,2,3,3,5,5], (v, i, self) => self.indexOf(v) === i);

console.log(arr);

// b.js

require('./lib1');

var b = 'b';

console.log('this is entry_b import lib1');

// webpack.config.js

entry: {

a: __dirname +'/app/a.js',

b: __dirname +'/app/b.js',

vendor: ['underscore'],

},

output: {

path: __dirname +'/dist',

filename: '[name].[chunkhash:6].js',

chunkFilename: '[name].[id].[chunkhash:6].js'

},

plugins: [

new webpack.optimize.CommonsChunkPlugin({

name: ['chunk', 'vendor'],

minChunks: 2,

}),

new webpack.optimize.CommonsChunkPlugin({

name: 'manifest',

chunks: ['vendor']

}),

new HtmlWebpackPlugin({

template: __dirname +'/app/index.html',

filename: __dirname +'/dist/a.html',

chunks: ['a', 'chunk', 'vendor', 'manifest'],

}),

new HtmlWebpackPlugin({

template: __dirname +'/app/index.html',

filename: __dirname +'/dist/b.html',

chunks: ['b', 'chunk', 'vendor', 'manifest'],

}),

]

}

通過打包后發(fā)現(xiàn)生成了如下文件:

可以明確看出生成了chunk.d09623.js 而且 其中就是我們的lib1.js 的庫的代碼。這里要注意的是Commons.ChunkPlugin的配置 當(dāng)name 給定數(shù)組之后從入口文件中選取 共同引用超過 minChunks 次數(shù)的模塊打包進(jìn)name 數(shù)組的第一個模塊,然后name 數(shù)組后面的塊 'vendor' 依次打包(查找entry里的key,沒有找到相關(guān)的key就生成一個空的塊),最后一個塊包含webpack生成的在瀏覽器上使用各個塊的加載代碼,所以插入到頁面中最后一個塊要最先加載,加載順序由name數(shù)組自右向左。

這里我們使用manifest 去提取了 webpackJsonp 的加載代碼,為了防止重復(fù)打包庫文件,這在前文已經(jīng)提到過。所以vendor中的加載代碼在mainfest.js 中,修改a.js 的console.log, 重新打包后的文件可以發(fā)現(xiàn)chunk.d0962e.js, vendor.98054b.js都沒有重新打包

所以總結(jié)來講就是多入口配置CommonsChunk

new webpack.optimize.CommonsChunkPlugin({

name: ['生成的項(xiàng)目公共模塊文件名', '第三方模塊文件名'],

minChunks: 2,

}),

總結(jié)

以上是生活随笔為你收集整理的html公共模块提取出去,webpack 填坑之路--提取独立文件(模块)的全部內(nèi)容,希望文章能夠幫你解決所遇到的問題。

如果覺得生活随笔網(wǎng)站內(nèi)容還不錯,歡迎將生活随笔推薦給好友。

主站蜘蛛池模板: 91精品网站 | 丝袜 亚洲 另类 国产 制服 | 日韩高清一区二区 | 爱爱视频在线免费观看 | av色片| 国产日韩欧美自拍 | 日韩欧美亚洲天堂 | 麻豆成人久久精品一区二区三区 | 男同精品| 国产东北女人做受av | 久免费一级suv好看的国产 | 影音先锋在线看片资源 | 波多野结衣一区二区三区免费视频 | 婷婷色图 | 精品国产伦一区二区三区免费 | 狠狠搞狠狠干 | 麻豆理论片 | 中文字幕乱码亚洲精品一区 | 久久精品天天中文字幕人妻 | 日韩中文字幕视频 | 亚洲成在人 | 国产精品美女久久久网av | 国产成人久久77777精品 | 在线不卡一区 | 久久精品亚洲一区二区 | 一区二区三区视频免费 | 4438国产精品一区二区 | 欧美 日韩 国产 在线观看 | 亚洲一区二区三区电影在线观看 | 夜夜操免费视频 | 美女视频毛片 | 欧美人与禽猛交乱配视频 | 日本五十路 | 久久久99精品免费观看 | 午夜精品美女久久久久av福利 | 韩国一区二区在线播放 | 凹凸国产熟女精品视频 | 岛国av动作片 | 波多野结衣50连登视频 | 精品无码一区二区三区在线 | 日美韩av | 一级片在线观看免费 | 第四色成人网 | 99国产精品久久久 | 美女扒逼 | 噜噜噜在线| 久久er99热精品一区二区介绍 | 自由成熟xxxx色视频 | 欧美成人手机视频 | 狠狠做| 黄黄的视频在线观看 | 国产欧美日韩 | 国产精品自拍第一页 | 国产精品久久99 | 999视频在线 | 人人草人| 日本免费一二三区 | 成人高清在线观看 | 国产精品福利一区二区 | 亚洲天堂avav| 国产又黄又爽又色 | 欧美日韩在线一区二区 | 男女做网站 | 色鬼综合 | 欧美亚洲天堂网 | 一级黄色a视频 | 视频三区在线 | 久婷婷 | 黄色片在线免费 | 大地资源在线观看免费高清版粤语 | 国产中文| 国产男男gay体育生网站 | 久久久久无码国产精品不卡 | 精品视频在线观看一区二区 | 四虎精品永久在线 | 蜜桃视频欧美 | 在线观看毛片av | 91精品国产99久久久久久红楼 | 18成人免费观看网站下载 | 三级黄色生活片 | 污污网站在线播放 | 自拍视频一区二区 | 国产欧美专区 | 亚洲精品久久久久久无码色欲四季 | 一个人看的www日本高清视频 | 人妻夜夜爽天天爽 | wwwxxx亚洲| 久久久免费观看视频 | 日本视频色 | 一级片黄色的 | 亚洲综人网 | 成人理论片 | 亚洲激情黄色 | 多男调教一女折磨高潮高h 国内毛片毛片毛片毛片毛片 | 少妇激情在线 | a级成人毛片 | 99热这里只有精品4 精品国产黄色 | 99久久久久久久久 | 成人1区2区 |