Introduction
Recently, I used the html-webapck-plugin plug-in for the first time in a react project. The plug-in has two main functions:
For external resources introduced in the html file, such as Script and link dynamically add the hash after each compile to prevent the problem of referencing cached external files.
You can generate and create html entry files. For example, a single page can generate an html file entry and configure N html-webpack-plugins. Can generate N page entrances
With this plug-in, problems similar to the above can be easily solved in the project.
I use html-webpack-plugin in my project. Since I am not familiar with this plug-in, I encountered one or other problems during the development process. Let’s talk about this plug-in.
html-webpack-plugin
The basic function of the plug-in is to generate html files. The principle is very simple:
Insert the relevant entry thunk of the `entry` configuration in webpack and the css style extracted by `extract-text-webpack-plugin` into the `template` or `templateContent` configuration item provided by the plug-in Generate an html file based on the specified content. The specific insertion method is to insert the style `link` into the `head` element and `script` into `head` or `body`.
You can instantiate the plug-in without configuring any parameters, such as the following:
var HtmlWebpackPlugin = require('html-webpack-plugin') webpackconfig = { ... plugins: [ new HtmlWebpackPlugin() ]}
If the html-webpack-plugin plug-in does not configure any options, it will default to the html-webpack-plugin in webpack. Entry configuration All entry thunks and css styles extracted by extract-text-webpack-plugin are inserted into the location specified in the file. For example, the content of the html file generated above is as follows:
Webpack App
Of course, you can use specific configuration items to customize some special needs. So what are the configuration items of the plug-in?
html-webpack-plugin configuration items
The plug-in provides many configuration items. The specific configuration items can be seen from the source code as follows:
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);
title: Generated html The title of the document. Configure this item, it will not replace the content of the title element in the specified template file, unless the template engine syntax is used in the html template file to obtain the configuration item value, as follows ejs template syntax form:
{%= o.htmlWebpackPlugin.options.title %}
filename : The file name of the output file. The default is index.html. If not configured, it will be the file name. In addition, you can also specify the directory location for the output file (such as 'html/index.html')
Two additional comments about filename Points:
1. The html file directory configured by filename is relative to the webpackConfig.output.path path, not relative to the current project directory structure.
2. Specify that the link and script paths in the generated HTML file content are relative to the generation directory. When writing the path, please write the relative path to the generation directory.
template: The location of the local template file, supports loaders (such as handlebars, ejs, undersore, html, etc.), such as handlebars!src/index.hbs;
A few additional points about template :
1. When the template configuration item uses file-loader in the html file, the specified location cannot be found, causing the content of the generated html file to be not the expected content.
2. If the template file specified for template does not specify any loader, ejs-loader will be used by default. For example, template: './index.html', if no loader is specified for .html, use ejs-loader
templateContent: string|function, which can specify the content of the template and cannot coexist with template. When the configuration value is function, you can directly return an html string, or you can call it asynchronously to return an html string.
inject: Inject all static resources into template or templateContent. Different configuration values are injected at different locations.
1. true or body: All JavaScript resources are inserted at the bottom of the body element
2. head: All JavaScript resources are inserted into the head element
3. False: All static resources css and JavaScript are Will not be injected into the template file
favicon: Add a specific favicon path to the output html document. This is the same as the title configuration item, and its path value needs to be dynamically obtained in the template
hash: true |false, whether to add the unique hash value generated by webpack for each injected static resource. The hash form is as follows:
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样式,代码可以这样:
<%= htmlWebpackPlugin.options.title %> <% for (var css in htmlWebpackPlugin.files.css) { %> <% } %> <% for (var chunk in htmlWebpackPlugin.files.chunks) { %>