中文字幕av专区_日韩电影在线播放_精品国产精品久久一区免费式_av在线免费观看网站

溫馨提示×

溫馨提示×

您好,登錄后才能下訂單哦!

密碼登錄×
登錄注冊×
其他方式登錄
點擊 登錄注冊 即表示同意《億速云用戶服務條款》

webpack中多頁面/入口支持與公共組件單獨打包的示例分析

發布時間:2021-08-17 10:34:45 來源:億速云 閱讀:135 作者:小新 欄目:web開發

這篇文章將為大家詳細講解有關webpack中多頁面/入口支持與公共組件單獨打包的示例分析,小編覺得挺實用的,因此分享給大家做個參考,希望大家閱讀完這篇文章后可以有所收獲。

基礎結構和準備工作

以下示例基于上一篇進行改進,上一篇項目源碼

目錄結構說明

.
├── package.json    # 項目配置
├── src      # 源碼目錄
│ ├── pageA.html    # 入口文件a
│ ├── pageB.html    # 入口文件b
│ ├── css/     # css資源
│ ├── img/     # 圖片資源
│ ├── js     # js&jsx資源
│ │ ├── pageA.js    # a頁面入口
│ │ ├── pageB.js    # b頁面入口
│ │ ├── lib/    # 沒有存放在npm的第三方庫或者下載存放到本地的基礎庫,如jQuery、Zepto、avalon
│ ├── pathmap.json   # 手動配置某些模塊的路徑,可以加快webpack的編譯速度
├── webpack.config.js   # webpack配置入口

一:自動構建入口

官方多入口示例

webpack默認支持多入口,官方也有多入口的示例。配件文件webpack.config.js如下

//已簡化
var path = require("path");
module.exports = {
 entry: {
  pageA: "./pageA",
  pageB: "./pageB"
 },
 output: {
  path: path.join(__dirname, "js"),
  filename: "[name].bundle.js",
  chunkFilename: "[id].chunk.js"
 }
}

每新增一個頁面就需要在webpack.config.js的entry 中增加一個 pageC:"./pageC",頁面少還好,頁面一多,就有點麻煩了,而且配置文件,盡可能不改動。那么如何支持不修改配置呢?

自動構建入口函數

entry實際上是一個map對象,結構如下{filename:filepath},那么我們可以根據文件名匹配,很容易構造自動掃描器:
npm 中有一個用于文件名匹配的 glob模塊,通過glob很容易遍歷出src/js目錄下的所有js文件:

安裝glob模塊

$ npm install glob --save-dev

修改webpack.config.js 配置,新增entries函數,修改entry:entries(),修改output的filename為"[name].js"

//引入glob
var glob = require('glob')
//entries函數
var entries= function () {
 var jsDir = path.resolve(srcDir, 'js')
 var entryFiles = glob.sync(jsDir + '/*.{js,jsx}')
 var map = {};

 for (var i = 0; i < entryFiles.length; i++) {
  var filePath = entryFiles[i];
  var filename = filePath.substring(filePath.lastIndexOf('\/') + 1, filePath.lastIndexOf('.'));
  map[filename] = filePath;
 }
 return map;
}
//修改入口,已經修改outp的filename
module.exports = {
 //entry: "./src/js/index.js",
 entry: entries(),
 output: {
  path: path.join(__dirname, "dist"),
  filename: "[name].js"
 },
 ......
 //以下省略,可以見下文詳細配置

測試

1.在src/js目錄中新增pageA.js

//js只有兩行代碼,在body中加一句話
var $ = require("jquery")
$("<div>這是jquery生成的多頁面示例</div>").appendTo("body")

2.新增pageA.html,也順便修改原來的index.html 對于js文件名的更改

<!DOCTYPE html>
<html lang="en">
<head>
<meta charset="UTF-8">
<title></title>
</head>
<body>
<script src="../dist/index.js"></script>
</body>
</html>

3.執行webpack,啟動dev-server

$ webpack
$ webpack-dev-server

webpack中多頁面/入口支持與公共組件單獨打包的示例分析

OK,成功打包生成pageA.js,成功運行

二:公共庫單獨打包

先來分析下,上個步驟打包的日志:

webpack中多頁面/入口支持與公共組件單獨打包的示例分析

index.js 依賴了avalon 和 jquery,然后打包后的index.js 有480kb

pageA.js 只用了jquery,然后打包后的js 有294kb

那么如果引用的lib庫多一點,又被很多頁面引用,那么lib庫就會被重復打包到page.js中去,模塊越多重復加載的情況越嚴重。

如果把公共代碼提取出來作為單獨的js,那么就到處可以復用,瀏覽器也就可以進行緩存,這時候就需要用到webpack內置插件WebPack.optimize.CommonsChunkPlugin

CommonsChunkPlugin 介紹

使用

new webpack.optimize.CommonsChunkPlugin(options)

Options
翻譯得比較簡單,詳見官方說明:

  1. options.name or options.names(string|string[]): 公共模塊的名稱

  2. options.filename (string): 公開模塊的文件名(生成的文件名)

  3. options.minChunks (number|Infinity|function(module,count) - boolean): 為number表示需要被多少個entries依賴才會被打包到公共代碼庫;為Infinity 僅僅創建公共組件塊,不會把任何modules打包進去。并且提供function,以便于自定義邏輯。

  4. options.chunks(string[]):只對該chunks中的代碼進行提取。

  5. options.children(boolean):如果為true,那么公共組件的所有子依賴都將被選擇進來

  6. options.async(boolean|string):如果為true,將創建一個 option.name的子chunks(options.chunks的同級chunks) 異步common chunk

  7. options.minSize(number):所有公共module的size 要大于number,才會創建common chunk

2個常用的例子,更多例子見官方說明:

1.Commons chunk for entries:針對入口文件提取公共代碼

new CommonsChunkPlugin({
 name: "commons",
 // (the commons chunk name)

 filename: "commons.js",
 // (the filename of the commons chunk)

 // minChunks: 3,
 // (Modules must be shared between 3 entries)

 // chunks: ["pageA", "pageB"],
 // (Only use these entries)
})

2.Explicit vendor chunk:直接指定第三方依賴庫,打包成公共組件

entry: {
 vendor: ["jquery", "other-lib"],
 app: "./entry"
}
new CommonsChunkPlugin({
 name: "vendor",

 // filename: "vendor.js"
 // (Give the chunk a different name)

 minChunks: Infinity,
 // (with more entries, this ensures that no other module
 // goes into the vendor chunk)
})

CommonsChunkPlugin使用

基于上篇的項目,參考上面的第二個例子,我們將jquery 和 avalon 提取出來打包成vendor.js

完整的webpack.config.js 如下:

```js 
var webpack = require("webpack");
 var path = require("path");
 var srcDir = path.resolve(process.cwd(), 'src');
 var nodeModPath = path.resolve(__dirname, './node_modules');
 var pathMap = require('./src/pathmap.json');
 var glob = require('glob')
 var CommonsChunkPlugin = webpack.optimize.CommonsChunkPlugin;
 var entries= function () {
 var jsDir = path.resolve(srcDir, 'js')
 var entryFiles = glob.sync(jsDir + '/*.{js,jsx}')
 var map = {};
 for (var i = 0; i < entryFiles.length; i++) {
  var filePath = entryFiles[i];
  var filename = filePath.substring(filePath.lastIndexOf('\/') + 1, filePath.lastIndexOf('.'));
  map[filename] = filePath;
 }
 return map;
}

module.exports = {
 //entry: "./src/js/index.js",
 //entry: entries(),
 entry: Object.assign(entries(), {
  // 用到什么公共lib(例如jquery.js),就把它加進vendor去,目的是將公用庫單獨提取打包
  'vendor': ['jquery', 'avalon']
 }),
 output: {
  path: path.join(__dirname, "dist"),
  filename: "[name].js"
 },
 module: {
  loaders: [
   {test: /\.css$/, loader: 'style-loader!css-loader'}
  ]
 },
 resolve: {
  extensions: ['.js', "", ".css"],
  root: [srcDir,nodeModPath],
  alias: pathMap,
  publicPath: '/'
 },
 plugins: [
  new CommonsChunkPlugin({
   name: 'vendor',
   minChunks: Infinity
  })
 ]
}
```

測試、驗證

1.修改入口(Object.assign 是html5.js里面的....)

//entry: entries(),
entry: Object.assign(entries(), {
 // 用到什么公共lib(例如jquery.js),就把它加進vendor去,目的是將公用庫單獨提取打包
 'vendor': ['jquery', 'avalon']
}),

2.加入插件CommonsChunkPlugin

var CommonsChunkPlugin = webpack.optimize.CommonsChunkPlugin;
config 中增加 plugins
 plugins: [
  new CommonsChunkPlugin({
   name: 'vendor',
   minChunks: Infinity
  })
 ]

3.修改index.html 和 pageA.html,增加對verdor.js的引用

<script src="../dist/vendor.js"></script>
<script src="../dist/index.js"></script>
//<script src="../dist/pageA.js"></script>

4.執行webpack

$ webpack

webpack中多頁面/入口支持與公共組件單獨打包的示例分析

結果分析

可以看到index.js 就只有457 bytes了,pageA.js 227bytes。vendor.js 是集成了jquery+avalon,所以有488kb。

這樣vendor.js 就可以重復利用了,也方便瀏覽器進行緩存。

調試過程中發現

Uncaught ReferenceError: webpackJsonp is not defined

這個是因為當時把vendor.js引入 放到了page.js 后面,導致page.js執行異常,所以,請一定把vendor.js 放在前面。

生成后的index.js就很輕便了,第三方庫都被打包到vendor中了,代碼如下:

webpackJsonp([0],[
/* 0 */
/***/ function(module, exports, __webpack_require__) {

 /**
  * Created by sloong on 2016/6/1.
  */
 //avalon 測試
 var avalon = __webpack_require__(1);
 avalon.define({
  $id: "avalonCtrl",
  name: "Hello Avalon!"
 });

 /*
 //zepto 測試
 require("zepto")

 $("<div>這是zepto生成的</div>").appendTo("body")*/

 //jquery 測試
 var $ = __webpack_require__(2)
 $("<div>這是jquery生成的</div>").appendTo("body")

/***/ }
]);

頁面測試均正常

webpack中多頁面/入口支持與公共組件單獨打包的示例分析

關于“webpack中多頁面/入口支持與公共組件單獨打包的示例分析”這篇文章就分享到這里了,希望以上內容可以對大家有一定的幫助,使各位可以學到更多知識,如果覺得文章不錯,請把它分享出去讓更多的人看到。

向AI問一下細節

免責聲明:本站發布的內容(圖片、視頻和文字)以原創、轉載和分享為主,文章觀點不代表本網站立場,如果涉及侵權請聯系站長郵箱:is@yisu.com進行舉報,并提供相關證據,一經查實,將立刻刪除涉嫌侵權內容。

AI

西华县| 宽城| 博白县| 鸡泽县| 虞城县| 潼南县| 北海市| 延川县| 莱芜市| 平舆县| 阿拉尔市| 乐昌市| 五常市| 南宁市| 海林市| 江门市| 桃园县| 郓城县| 南岸区| 凤城市| 绥宁县| 台山市| 昂仁县| 镇雄县| 景泰县| 潍坊市| 芜湖市| 淳安县| 汪清县| 浙江省| 金平| 平远县| 常州市| 天津市| 巴林右旗| 肥乡县| 都兰县| 河池市| 建昌县| 通渭县| 扎鲁特旗|