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, 'default_index.ejs'), filename: 'index.html', hash: false, inject: true, compile: true, favicon: false, minify: false, cache: true, showErrors: true, chunks: 'all', excludeChunks: [], title: 'Webpack App', 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
html
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:'rd平台', template: 'entries/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=\'#\'" /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=\'#\'" /script><% } %>
htmlWebpackPlugin.options: 传递给插件的配置项,具体的配置项如上面插件配置项小节所描述的。
插件事件
不知道你发现没有,html-webpack-plugin插件在插入静态资源时存在一些问题:
在插入js资源只能插入head或者body元素中,不能一些插入head中,另一些插入body中
不支持在html中文件内联*,例如在文件的某个地方用来内联外部脚本
为此,有人专门给插件作者提问了这个问题;对此插件作者提供了插件事件,允许其他插件来改变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: ''}) ]
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!