html-webpack-plugin詳解

来源:https://www.cnblogs.com/angelasp/archive/2019/03/31/10632826.html
-Advertisement-
Play Games

引言 我們來看看主要作用: 為html文件中引入的外部資源如script、link動態添加每次compile後的hash,防止引用緩存的外部文件問題 可以生成創建html入口文件,比如單頁面可以生成一個html文件入口,配置N個html-webpack-plugin可以生成N個頁面入口 html-w ...


引言

我們來看看主要作用:

為html文件中引入的外部資源如scriptlink動態添加每次compile後的hash,防止引用緩存的外部文件問題

可以生成創建html入口文件,比如單頁面可以生成一個html文件入口,配置Nhtml-webpack-plugin可以生成N個頁面入口

html-webpack-plugin

插件的基本作用就是生成html文件。原理很簡單:

將 webpack中`entry`配置的相關入口chunk  和  `extract-text-webpack-plugin`抽取的css樣式   插入到該插件提供的`template`或者`templateContent`配置項指定的內容基礎上生成一個html文件,具體插入方式是將樣式`link`插入到`head`元素中,`script`插入到`head`或者`body`中。

實例化該插件時可以不配置任何參數,例如下麵這樣:

var HtmlWebpackPlugin = require('html-webpack-plugin')
webpackconfig = {
    plugins: [
        new HtmlWebpackPlugin()
    ]
}

  

不配置任何選項的html-webpack-plugin插件,他會預設將webpack中的entry配置所有入口thunk和extract-text-webpack-plugin抽取的css樣式都插入到文件指定的位置。例如上面生成的html文件內容如下:

<!DOCTYPE html>
<html>
  <head>
    <meta charset="UTF-8">
    <title>Webpack App</title>
  <link href="index-af150e90583a89775c77.css" rel="stylesheet"></head>
  <body>
  <script type="text/javascript" src="common-26a14e7d42a7c7bbc4c2.js"></script>
  <script type="text/javascript" src="index-af150e90583a89775c77.js"></script></body>
</html>

  

當然可以使用具體的配置項來定製化一些特殊的需求,那麼插件有哪些配置項呢?

html-webpack-plugin配置項

插件提供的配置項比較多,通過源碼可以看出具體的配置項如下:

 1 this.options = _.extend({
 2   template: path.join(__dirname, 'default_index.ejs'),
 3   templateParameters: templateParametersGenerator,
 4   filename: 'index.html',
 5   hash: false,
 6   inject: true,
 7   compile: true,
 8   favicon: false,
 9   minify: false,
10   cache: true,
11   showErrors: true,
12   chunks: 'all',
13   excludeChunks: [],
14   chunksSortMode: 'auto',
15   meta: {},
16   title: 'Webpack App',
17   xhtml: false
18 }, options);
title: 生成的html文檔的標題。配置該項,它並不會替換指定模板文件中的title元素的內容,除非html模板文件中使用了模板引擎語法來獲取該配置項值,如下ejs模板語法形式:
<title>{%= o.htmlWebpackPlugin.options.title %}</title>

filename:輸出文件的文件名稱,預設為index.html,不配置就是該文件名;此外,還可以為輸出文件指定目錄位置(例如'html/index.html')

關於filename補充兩點:

1、filename配置的html文件目錄是相對於webpackConfig.output.path路徑而言的,不是相對於當前項目目錄結構的。
2、指定生成的html文件內容中的linkscript路徑是相對於生成目錄下的,寫路徑的時候請寫生成目錄下的相對路徑。

template: 本地模板文件的位置,支持載入器(如handlebars、ejs、undersore、html等),如比如 handlebars!src/index.hbs

關於template補充幾點:

1、template配置項在html文件使用file-loader時,其所指定的位置找不到,導致生成的html文件內容不是期望的內容。
2、為template指定的模板文件沒有指定任何loader的話,預設使用ejs-loader。如template: './index.html',若沒有為.html指定任何loader就使用ejs-loader

templateContent: string|function,可以指定模板的內容,不能與template共存。配置值為function時,可以直接返回html字元串,也可以非同步調用返回html字元串。

inject:向template或者templateContent中註入所有靜態資源,不同的配置值註入的位置不經相同。

1、true或者body:所有JavaScript資源插入到body元素的底部
2、head: 所有JavaScript資源插入到head元素中
3、false: 所有靜態資源css和JavaScript都不會註入到模板文件中

 

favicon: 添加特定favicon路徑到輸出的html文檔中,這個同title配置項,需要在模板中動態獲取其路徑值

hash:true|false,是否為所有註入的靜態資源添加webpack每次編譯產生的唯一hash值,添加hash形式如下所示:
html <script type="text/javascript" src="common.js?a3e1396b501cdd9041be"></script>

chunks:允許插入到模板中的一些chunk,不配置此項預設會將entry中所有的thunk註入到模板中。在配置多個頁面時,每個頁面註入的thunk應該是不相同的,需要通過該配置為不同頁面註入不同的thunk;

excludeChunks: 這個與chunks配置項正好相反,用來配置不允許註入的thunk。

chunksSortMode: none | auto| function,預設auto; 允許指定的thunk在插入到html文檔前進行排序。
>function值可以指定具體排序規則;auto基於thunk的id進行排序; none就是不排序

xhtml: true|fasle, 預設false;是否渲染link為自閉合的標簽,true則為自閉合標簽

cache: true|fasle, 預設true; 如果為true表示在對應的thunk文件修改後就會emit文件

showErrors: true|false,預設true;是否將錯誤信息輸出到html頁面中。這個很有用,在生成html文件的過程中有錯誤信息,輸出到頁面就能看到錯誤相關信息便於調試。

minify: {....}|false;傳遞 html-minifier 選項給 minify 輸出,false就是不使用html壓縮,minify具體配置參數請點擊html-minifier

下麵的是一個用於配置這些屬性的一個例子:

    new HtmlWebpackPlugin({
          title:'rd平臺',
          template: 'src/index.html', // 源模板文件
          filename: './index.html', // 輸出文件【註意:這裡的根路徑是module.exports.output.path】
          showErrors: true,
          inject: 'body',
          chunks: ["common",'index']
      })

  

配置多個html頁面

html-webpack-plugin的一個實例生成一個html文件,如果單頁應用中需要多個頁面入口,或者多頁應用時配置多個html時,那麼就需要實例化該插件多次;

即有幾個頁面就需要在webpack的plugins數組中配置幾個該插件實例:

……
    plugins: [
        new HtmlWebpackPlugin({
             template: 'src/html/index.html',
              excludeChunks: ['list', 'detail']
        }),
        new HtmlWebpackPlugin({
            filename: 'list.html',
            template: 'src/html/list.html',
            thunks: ['common', 'list']
        }), 
        new HtmlWebpackPlugin({
          filename: 'detail.html',
          template: 'src/html/detail.html',
           thunks: ['common', 'detail']
        })
    ]
    ...

  

如上例應用中配置了三個入口頁面:index.html、list.html、detail.html;並且每個頁面註入的thunk不盡相同;類似如果多頁面應用,就需要為每個頁面配置一個;

配置自定義的模板

不帶參數的html-webpack-plugin預設生成的html文件只是將thunk和css樣式插入到文檔中,可能不能滿足我們的需求;

另外,如上面所述,三個頁面指定了三個不同html模板文件;在項目中,可能所有頁面的模板文件可以共用一個,因為html-webpack-plugin插件支持不同的模板loader,所以結合模板引擎來共用一個模板文件有了可能。

所以,配置自定義模板就派上用場了。具體的做法,藉助於模板引擎來實現,例如插件沒有配置loader時預設支持的ejs模板引擎,下麵就以ejs模板引擎為例來說明;

例如項目中有2個入口html頁面,它們可以共用一個模板文件,利用ejs模板的語法來動態插入各自頁面的thunk和css樣式,代碼可以這樣:

<!DOCTYPE html>
<html style="font-size:20px">
<head>
    <meta charset="utf-8">
    <title><%= htmlWebpackPlugin.options.title %></title>
    <% for (var css in htmlWebpackPlugin.files.css) { %>
    <link href="<%=htmlWebpackPlugin.files.css[css] %>" rel="stylesheet">
    <% } %>
</head>
<body>
<div id="app"></div>
<% for (var chunk in htmlWebpackPlugin.files.chunks) { %>
<script type="text/javascript" src="<%=htmlWebpackPlugin.files.chunks[chunk].entry %>"></script>
<% } %>
</body>
</html>

  

你可能會對代碼中的上下文htmlWebpackPlugin數據感到迷惑,這是啥東東?其實這是html-webpack-plugin插件在生成html文件過程中產生的數據,這些數據對html模板文件是可用的,並且我們看<%%>是不是給java裡面的jsp差不多了。

自定義模板上下文數據

html-webpack-plugin在生成html文件的過程中,插件會根據配置生成一個對當前模板可用的特定數據,模板語法可以根據這些數據來動態生成html文件的內容。

那麼,插件生成的特殊數據格式是什麼,生成的哪些數據呢?從源碼或者其官網都給出了答案。從源碼中可以看出模板引擎具體可以訪問的數據如下:

var templateParams = {
        compilation: compilation,
        webpack: compilation.getStats().toJson(),
        webpackConfig: compilation.options,
        htmlWebpackPlugin: 
          files: assets,
          options: self.options
        }
      };

  

從中可以看出,有四個主要的對像數據。其中compilation為所有webpack插件提供的都可以訪問的一個編譯對象,此處就不太做介紹,具體可以自己查資料。下麵就對剩下的三個對象數據進行說明。

webpack

webpack的stats對象;註意一點:

這個可以訪問的stats對象是htm文件生成時所對應的stats對象,而不是webpack運行完成後所對應的整個stats對象。

webpackConfig

webpack的配置項;通過這個屬性可以獲取webpack的相關配置項,如通過webpackConfig.output.publicPath來獲取publicPath配置。當然還可以獲取其他配置內容。

htmlWebpackPlugin

html-webpack-plugin插件對應的數據。它包括兩部分:

htmlWebpackPlugin.files: 此次html-webpack-plugin插件配置的chunk和抽取的css樣式該files值其實是webpack的stats對象的assetsByChunkName屬性代表的值,該值是插件配置的chunk塊對應的按照webpackConfig.output.filename映射的值。例如對應上面配置插件各個屬性配置項例子中生成的數據格式如下:

"htmlWebpackPlugin": {
  "files": {
    "css": [ "inex.css" ],
    "js": [ "common.js", "index.js"],
    "chunks": {
      "common": {
        "entry": "common.js",
        "css": [ "index.css" ]
      },
      "index": {
        "entry": "index.js",
        "css": ["index.css"]
      }
    }
  }
}

 

這樣,就可以是用如下模板引擎來動態輸出script腳本

<% for (var chunk in htmlWebpackPlugin.files.chunks) { %>
<script type="text/javascript" src="<%=htmlWebpackPlugin.files.chunks[chunk].entry %>"></script>
<% } %>

  

htmlWebpackPlugin.options: 傳遞給插件的配置項,具體的配置項如上面插件配置項小節所描述的。

插件事件

不知道你發現沒有,html-webpack-plugin插件在插入靜態資源時存在一些問題:

  • 在插入js資源只能插入head或者body元素中,不能一些插入head中,另一些插入body
  • 不支持在html中文件內聯*,例如在文件的某個地方用<script src="xxx.js?__inline"></script>來內聯外部腳本

為此,有人專門給插件作者提問了這個問題;對此插件作者提供了插件事件,允許其他插件來改變html文件內容。具體的事件如下:

Async(非同步事件):

    * html-webpack-plugin-before-html-generation
    * html-webpack-plugin-before-html-processing
    * html-webpack-plugin-alter-asset-tags
    * html-webpack-plugin-after-html-processing
    * html-webpack-plugin-after-emit

Sync(同步事件):

    * html-webpack-plugin-alter-chunks

這些事件是提供給其他插件使用的,用於改變html的內容。因此,要用這些事件需要提供一個webpack插件。例如下麵定義的MyPlugin插件。

function MyPlugin(options) {
  // Configure your plugin with options...
}
 
MyPlugin.prototype.apply = function(compiler) {
  // ...
  compiler.plugin('compilation', function(compilation) {
    console.log('The compiler is starting a new compilation...');
 
    compilation.plugin('html-webpack-plugin-before-html-processing', function(htmlPluginData, callback) {
      htmlPluginData.html += 'The magic footer';
      callback(null, htmlPluginData);
    });
  });
 
};

module.exports = MyPlugin;

  

 

然後,在webpack.config.js文件中配置Myplugin信息:

plugins: [
  new MyPlugin({options: ''})
]

  

 


您的分享是我們最大的動力!

-Advertisement-
Play Games
更多相關文章
  • 一、系統整體性能監測工具:uptime uptime命令用於查看伺服器運行了多長時間以及有多少個用戶登錄,快速獲知伺服器運行的負載情況。 load average,顯示了最近1,5,15分鐘的負荷情況。 它的值代表等待CPU處理的進程數,如果CPU沒有時間處理這些進程,load average值會升 ...
  • 在面試中被問到這樣的題目,當時被問蒙了,後來查閱了一下相關資料搞懂了一些,記錄一下。 題目:有一堆的用戶消費數據,欄位為id、城市、性別、消費總額等,要求選取每個城市消費總額的Top N。面試官提示,可以用python,也可以用任何sql語言。 這裡記錄的是Oracle的做法。查看表的信息: sel ...
  • 主界面代碼 主活動代碼: ...
  • Android開發中有三種主要的方式用於設置View的點擊事件,1、創建內部類;2、主類中實現OnClickListener介面;3、使用匿名內部類。這三種方式都用到了OnClickListener介面,只是不同形式而已。其中OnClickListener是監聽View點擊事件的介面,介面中定義控制項 ...
  • 前言 最近筆者在複習以前基礎知識,發現很多細的知識點還是需要重新再總結一番。本文對flex佈局進行圖解說明,以後忘了的同學可以隨時過來查看,歡迎轉載,煩請註明出處。 主體 萬丈高樓平地起,熟悉flex,先來瞭解下以下7種css屬性 1. 2. 3. 4. 5. 6. 7. 下麵我們就對每個屬性進行詳 ...
  • 一.介紹 在前端項目頁面開發中,尤其是H5頁面開發,我們常常要適配各種解析度的屏幕,才能讓用戶獲得最好的體驗效果.pc也是如此,很多頁面是一屏,也是要適配各種尺寸的解析度.這時候我們就需要對各種解析度的手機電腦進行適配.那麼用什麼適配方案比較好呢?下麵給大家介紹一種我覺得比較好的適配方案. 二、分辨 ...
  • 本文轉載自:https://blog.csdn.net/xiaogeldx/article/details/85455011 JavaScript的math對象 math方法 sqrt:開方 abs:絕對值 PI:π pow:x的y次方 round:取整 floor:向下 ceil:向上 max:最 ...
  • 一、jQuery簡介 1.0 JavaScript編程比較噁心的地方 噁心1:選擇元素麻煩,全線相容的方法只有getElementById()和getElementsByTagName()兩個。其他的方法是不都相容的。getElementsByClassName()通過類名選擇元素,IE9開始相容。 ...
一周排行
    -Advertisement-
    Play Games
  • 移動開發(一):使用.NET MAUI開發第一個安卓APP 對於工作多年的C#程式員來說,近來想嘗試開發一款安卓APP,考慮了很久最終選擇使用.NET MAUI這個微軟官方的框架來嘗試體驗開發安卓APP,畢竟是使用Visual Studio開發工具,使用起來也比較的順手,結合微軟官方的教程進行了安卓 ...
  • 前言 QuestPDF 是一個開源 .NET 庫,用於生成 PDF 文檔。使用了C# Fluent API方式可簡化開發、減少錯誤並提高工作效率。利用它可以輕鬆生成 PDF 報告、發票、導出文件等。 項目介紹 QuestPDF 是一個革命性的開源 .NET 庫,它徹底改變了我們生成 PDF 文檔的方 ...
  • 項目地址 項目後端地址: https://github.com/ZyPLJ/ZYTteeHole 項目前端頁面地址: ZyPLJ/TreeHoleVue (github.com) https://github.com/ZyPLJ/TreeHoleVue 目前項目測試訪問地址: http://tree ...
  • 話不多說,直接開乾 一.下載 1.官方鏈接下載: https://www.microsoft.com/zh-cn/sql-server/sql-server-downloads 2.在下載目錄中找到下麵這個小的安裝包 SQL2022-SSEI-Dev.exe,運行開始下載SQL server; 二. ...
  • 前言 隨著物聯網(IoT)技術的迅猛發展,MQTT(消息隊列遙測傳輸)協議憑藉其輕量級和高效性,已成為眾多物聯網應用的首選通信標準。 MQTTnet 作為一個高性能的 .NET 開源庫,為 .NET 平臺上的 MQTT 客戶端與伺服器開發提供了強大的支持。 本文將全面介紹 MQTTnet 的核心功能 ...
  • Serilog支持多種接收器用於日誌存儲,增強器用於添加屬性,LogContext管理動態屬性,支持多種輸出格式包括純文本、JSON及ExpressionTemplate。還提供了自定義格式化選項,適用於不同需求。 ...
  • 目錄簡介獲取 HTML 文檔解析 HTML 文檔測試參考文章 簡介 動態內容網站使用 JavaScript 腳本動態檢索和渲染數據,爬取信息時需要模擬瀏覽器行為,否則獲取到的源碼基本是空的。 本文使用的爬取步驟如下: 使用 Selenium 獲取渲染後的 HTML 文檔 使用 HtmlAgility ...
  • 1.前言 什麼是熱更新 游戲或者軟體更新時,無需重新下載客戶端進行安裝,而是在應用程式啟動的情況下,在內部進行資源或者代碼更新 Unity目前常用熱更新解決方案 HybridCLR,Xlua,ILRuntime等 Unity目前常用資源管理解決方案 AssetBundles,Addressable, ...
  • 本文章主要是在C# ASP.NET Core Web API框架實現向手機發送驗證碼簡訊功能。這裡我選擇是一個互億無線簡訊驗證碼平臺,其實像阿裡雲,騰訊雲上面也可以。 首先我們先去 互億無線 https://www.ihuyi.com/api/sms.html 去註冊一個賬號 註冊完成賬號後,它會送 ...
  • 通過以下方式可以高效,並保證數據同步的可靠性 1.API設計 使用RESTful設計,確保API端點明確,並使用適當的HTTP方法(如POST用於創建,PUT用於更新)。 設計清晰的請求和響應模型,以確保客戶端能夠理解預期格式。 2.數據驗證 在伺服器端進行嚴格的數據驗證,確保接收到的數據符合預期格 ...