Heim  >  Artikel  >  Web-Frontend  >  Detaillierte Einführung in das HTML-Webpack-Plugin

Detaillierte Einführung in das HTML-Webpack-Plugin

黄舟
黄舟Original
2017-05-26 16:02:522682Durchsuche

Einführung

Vor kurzem habe ich das HTML-Webapck-Plugin-Plugin zum ersten Mal in einem Reaktionsprojekt verwendet. Die beiden Hauptfunktionen dieses Plug-Ins sind:

Für In HTML-Dateien eingeführte externe Ressourcen wie Skripte und Links fügen den Hash nach jeder Kompilierung dynamisch hinzu, um das Problem des Verweisens auf zwischengespeicherte externe Dateien zu vermeiden.

kann beispielsweise HTML-Eintragsdateien generieren und erstellen Generieren Sie einen HTML-Dateieintrag und konfigurieren Sie N HTML-Webpack-Plugins. Kann N Seiteneinträge generieren.

Mit diesem Plug-In können ähnliche Probleme wie die oben genannten problemlos im Projekt gelöst werden.

Ich verwende in meinem Projekt das HTML-Webpack-Plugin. Da ich mit diesem Plug-In nicht vertraut bin, bin ich während des Entwicklungsprozesses auf das eine oder andere Problem gestoßen.

html-webpack-plugin

Die Grundfunktion des Plug-ins besteht darin, HTML-Dateien zu generieren. Das Prinzip ist ganz einfach:

Fügen Sie den entsprechenden Eintragsthunk der „entry“-Konfiguration im Webpack und den durch „extract-text-webpack-plugin“ extrahierten CSS-Stil in die „template“- oder „templateContent“-Konfiguration ein Vom Plug-in bereitgestelltes Element Generieren Sie eine HTML-Datei basierend auf dem angegebenen Inhalt. Die spezifische Einfügemethode besteht darin, den Stil „link“ in das „head“-Element und „script“ in „head“ oder „body“ einzufügen.

Sie können das Plug-in instanziieren, ohne irgendwelche Parameter zu konfigurieren, zum Beispiel wie folgt:

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

Wenn das HTML-Webpack-Plugin-Plug-in mit keinem konfiguriert ist Optionen, es wird standardmäßig webpack verwendet. In der Eintragskonfiguration werden alle durch den Eintrag thunk und extract-text-webpack-plugin extrahierten CSS-Stile an dem in der Datei angegebenen Speicherort eingefügt. Der Inhalt der oben generierten HTML-Datei lautet beispielsweise wie folgt:

<!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>

Natürlich können bestimmte Konfigurationselemente verwendet werden, um einige spezielle Anforderungen anzupassen. Was sind also die Konfigurationselemente des Plug-Ins? ?

html-webpack-plugin-Konfigurationselemente

Das Plug-in stellt viele Konfigurationselemente bereit. Die spezifischen Konfigurationselemente sind aus dem Quellcode wie folgt ersichtlich:

this.options = _.extend({
    template: path.join(__dirname, &#39;default_index.ejs&#39;),
    filename: &#39;index.html&#39;,
    hash: false,
    inject: true,
    compile: true,
    favicon: false,
    minify: false,
    cache: true,
    showErrors: true,
    chunks: &#39;all&#39;,
    excludeChunks: [],
    title: &#39;Webpack App&#39;,
    xhtml: false
  }, options);

Titel: Generieren Sie den Titel des HTML-Dokuments. Konfigurieren Sie dieses Element. Es ersetzt nicht den Inhalt des Titelelements in der angegebenen Vorlagendatei, es sei denn, die Syntax der Vorlagen-Engine wird in der HTML-Vorlagendatei verwendet, um den Wert des Konfigurationselements zu erhalten, wie im folgenden EJS-Vorlagensyntaxformular gezeigt :

<title>{%= o.htmlWebpackPlugin.options.title %}</title>

Dateiname: Der Dateiname der Ausgabedatei. Der Standardwert ist index.html. Wenn nicht konfiguriert, können Sie auch den Verzeichnisspeicherort angeben Ausgabedatei (z. B. „html/index.html“)

Über Dateiname Zwei zusätzliche Punkte:

1. Das durch Dateiname konfigurierte HTML-Dateiverzeichnis ist relativ zum Pfad webpackConfig.output.path , nicht relativ zur aktuellen Projektverzeichnisstruktur.
2. Geben Sie an, dass die Link- und Skriptpfade im generierten HTML-Dateiinhalt relativ zum Generierungsverzeichnis sind. Geben Sie beim Schreiben des Pfads bitte den relativen Pfad zum Generierungsverzeichnis an.

template: Der Speicherort der lokalen Vorlagendatei, unterstützt Loader (z. B. handlebars, ejs, undersore, html usw.), z. B. handlebars!src/index.hbs; Einige zusätzliche Punkte zur Vorlage:

1. Wenn das Vorlagenkonfigurationselement den Dateilader in der HTML-Datei verwendet, kann der angegebene Speicherort nicht gefunden werden, was dazu führt, dass der Inhalt der generierten HTML-Datei nicht dem erwarteten Inhalt entspricht.

2. Wenn die für template angegebene Vorlagendatei keinen Loader angibt, wird standardmäßig ejs-loader verwendet. Beispiel: Vorlage: './index.html'. Wenn für .html kein Loader angegeben ist, verwenden Sie ejs-loader


templateContent: string|function, die den Inhalt der Vorlage angeben kann und nicht mit dieser koexistieren kann Vorlage. Wenn der Konfigurationswert eine Funktion ist, können Sie direkt eine HTML-Zeichenfolge zurückgeben oder sie asynchron aufrufen, um eine HTML-Zeichenfolge zurückzugeben.

inject: Alle statischen Ressourcen in Vorlage oder templateContent einfügen. Die Injektionsorte für verschiedene Konfigurationswerte sind unterschiedlich.

1. true oder body: alle JavaScript-Ressourcen werden am Ende des body-Elements eingefügt

2. false: alle statischen Ressourcen CSS und JavaScript werden nicht in die Vorlagendatei eingefügt


Favicon: Fügen Sie dem Ausgabe-HTML-Dokument einen bestimmten Favicon-Pfad hinzu. Dies ist dasselbe wie das Titelkonfigurationselement, und sein Pfadwert muss dynamisch sein in der Vorlage erhalten

Hash: true |false, ob der vom Webpack generierte eindeutige Hash-Wert für jede injizierte statische Ressource hinzugefügt werden soll. Die Hash-Form lautet wie folgt:

html c64719988f93834aca6a024b3380539c2cacc6d41bbb37262a98f745aa00fbf0

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压缩。

下面的是一个用于配置这些属性的一个例子:

 new HtmlWebpackPlugin({
          title:&#39;rd平台&#39;,
          template: &#39;entries/index.html&#39;, // 源模板文件
          filename: &#39;./index.html&#39;, // 输出文件【注意:这里的根路径是module.exports.output.path】
          showErrors: true,
          inject: &#39;body&#39;,
          chunks: ["common",&#39;index&#39;]      })

配置多个html页面

html-webpack-plugin的一个实例生成一个html文件,如果单页应用中需要多个页面入口,或者多页应用时配置多个html时,那么就需要实例化该插件多次;

即有几个页面就需要在webpack的plugins数组中配置几个该插件实例:

  ...
    plugins: [        new HtmlWebpackPlugin({
             template: &#39;src/html/index.html&#39;,
              excludeChunks: [&#39;list&#39;, &#39;detail&#39;]        }),
        new HtmlWebpackPlugin({
            filename: &#39;list.html&#39;,
            template: &#39;src/html/list.html&#39;,
            thunks: [&#39;common&#39;, &#39;list&#39;]        }), 
        new HtmlWebpackPlugin({
          filename: &#39;detail.html&#39;,
          template: &#39;src/html/detail.html&#39;,
           thunks: [&#39;common&#39;, &#39;detail&#39;]        })
    ]
    ...

如上例应用中配置了三个入口页面: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=\&#39;#\&#39;" /script><% } %></body></html>

你可能会对代码中的上下文htmlWebpackPlugin数据感到迷惑,这是啥东东?其实这是html-webpack-plugin插件在生成html文件过程中产生的数据,这些数据对html模板文件是可用的。

自定义模板上下文数据

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=\&#39;#\&#39;" /script><% } %>

htmlWebpackPlugin.options: 传递给插件的配置项,具体的配置项如上面插件配置项小节所描述的。

插件事件

不知道你发现没有,html-webpack-plugin插件在插入静态资源时存在一些问题:

在插入js资源只能插入head或者body元素中,不能一些插入head中,另一些插入body中

不支持在html中文件内联*,例如在文件的某个地方用12fb87a978cd86bc393e6dfe44ecd2cc2cacc6d41bbb37262a98f745aa00fbf0来内联外部脚本

为此,有人专门给插件作者提问了这个问题;对此插件作者提供了插件事件,允许其他插件来改变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(&#39;compilation&#39;, function(compilation) {
    console.log(&#39;The compiler is starting a new compilation...&#39;);

    compilation.plugin(&#39;html-webpack-plugin-before-html-processing&#39;, function(htmlPluginData, callback) {
      htmlPluginData.html += &#39;The magic footer&#39;;
      callback(null, htmlPluginData);
    });
  });};module.exports = MyPlugin;

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

plugins: [  new MyPlugin({options: &#39;&#39;})
]

Das obige ist der detaillierte Inhalt vonDetaillierte Einführung in das HTML-Webpack-Plugin. Für weitere Informationen folgen Sie bitte anderen verwandten Artikeln auf der PHP chinesischen Website!

Stellungnahme:
Der Inhalt dieses Artikels wird freiwillig von Internetnutzern beigesteuert und das Urheberrecht liegt beim ursprünglichen Autor. Diese Website übernimmt keine entsprechende rechtliche Verantwortung. Wenn Sie Inhalte finden, bei denen der Verdacht eines Plagiats oder einer Rechtsverletzung besteht, wenden Sie sich bitte an admin@php.cn