>  기사  >  웹 프론트엔드  >  html-webpack-plugin에 대한 자세한 소개

html-webpack-plugin에 대한 자세한 소개

黄舟
黄舟원래의
2017-05-26 16:02:522676검색

소개

최근에 React 프로젝트에서 처음으로 html-webapck-plugin 플러그인을 사용했습니다. 이 플러그인의 두 가지 주요 기능은 다음과 같습니다.

스크립트 및 링크와 같은 html 파일에 도입된 외부 리소스는 캐시된 외부 파일을 참조하는 문제를 방지하기 위해 각 컴파일 후에 해시를 동적으로 추가합니다.

는 html 항목 파일을 생성하고 생성할 수 있습니다. html 파일 항목을 생성하고 N html-webpack-plugins를 구성합니다. N개의 페이지 입구를 생성할 수 있습니다

이 플러그인을 사용하면 프로젝트에서 위와 유사한 문제를 쉽게 해결할 수 있습니다.

저는 프로젝트에서 html-webpack-plugin을 사용하고 있습니다. 저는 이 플러그인에 익숙하지 않기 때문에 개발 과정에서 하나 이상의 문제에 직면했습니다.

html-webpack-plugin

플러그인의 기본 기능은 html 파일을 생성하는 것입니다. 원리는 매우 간단합니다.

webpack의 `entry` 구성의 관련 항목 썽크와 `extract-text-webpack-plugin`으로 추출된 CSS 스타일을 `template` 또는 `templateContent` 구성에 삽입합니다. 플러그인에서 제공하는 항목 지정된 내용을 기반으로 html 파일을 생성합니다. 구체적인 삽입 방법은 `head` 요소에 `link` 스타일을 삽입하고 `head` 또는 `body`에 `script` 스타일을 삽입하는 것입니다.

다음과 같은 매개변수를 구성하지 않고 플러그인을 인스턴스화할 수 있습니다.

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

html-webpack-plugin 플러그인이 옵션으로 구성되지 않은 경우, 기본적으로 webpack의 html-webpack-plugin이 설정됩니다. 항목 구성 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 구성 항목

플러그인은 다양한 구성 항목을 제공하며, 구체적인 구성 항목은 다음과 같이 소스 코드에서 확인할 수 있습니다.

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);

title : 생성된 html 문서의 제목입니다. 이 항목을 구성합니다. ejs 템플릿 구문 형식과 같이 HTML 템플릿 파일에서 템플릿 엔진 구문을 사용하여 구성 항목 값을 가져오지 않는 한 지정된 템플릿 파일의 제목 요소 내용을 바꾸지 않습니다.

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

filename : 출력 파일의 파일 이름입니다. 기본값은 index.html입니다. 구성하지 않으면 파일 이름이 됩니다. 또한 출력 파일의 디렉터리 위치를 지정할 수도 있습니다(예: 'html). /index.html')

파일 이름에 대한 두 가지 추가 참고 사항:

1. filename으로 구성된 html 파일 디렉터리는 현재 webpackConfig.output.path 경로에 상대적입니다. 프로젝트 디렉토리 구조.
2. 생성된 HTML 파일 내용의 링크 및 스크립트 경로가 생성 디렉터리를 기준으로 하도록 지정하세요. 경로 작성 시 생성 디렉터리에 대한 상대 경로를 적어주세요.

템플릿: 로컬 템플릿 파일의 위치로, 로더(예: 핸들바, ejs, 언더소어, html 등)를 지원합니다(예: handlerbars!src/index.hbs).

A; 템플릿 관련 몇 가지 추가 사항:

1. 템플릿 구성 항목이 html 파일에서 file-loader를 사용하는 경우 지정된 위치를 찾을 수 없어 생성된 html 파일의 내용이 예상한 내용과 다릅니다.
2. 템플릿에 지정된 템플릿 파일에 로더가 지정되어 있지 않으면 기본적으로 ejs-loader가 사용됩니다. 예를 들어 template: './index.html', .html에 대해 로더가 지정되지 않은 경우 ejs-loader

templateContent: string|function을 사용하세요. 이는 템플릿의 콘텐츠를 지정할 수 있지만 템플릿과 공존할 수 없습니다. 주형. 구성 값이 function인 경우 html 문자열을 직접 반환하거나 비동기적으로 호출하여 html 문자열을 반환할 수 있습니다.

inject: 모든 정적 리소스를 template 또는 templateContent에 주입합니다. 구성 값마다 주입 위치가 다릅니다.

1. true 또는 body: 모든 JavaScript 리소스가 body 요소의 하단에 삽입됩니다.
2. head: 모든 JavaScript 리소스가 head 요소에 삽입됩니다.
3. css 및 JavaScript는 템플릿 파일에 삽입되지 않습니다.

파비콘: 출력 html 문서에 특정 파비콘 경로를 추가합니다. 이는 제목 구성 항목과 동일하며 해당 경로 값을 동적으로 가져와야 합니다. 템플릿

hash: true |false, 주입된 각 정적 리소스에 대해 webpack에서 생성된 고유한 해시 값을 추가할지 여부. 해시 형식은 다음과 같습니다.
html ad3c65f1ed035c8461dcfdb0fbc0f45c2cacc6d41bbb37262a98f745aa00fbf0

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;})
]

위 내용은 html-webpack-plugin에 대한 자세한 소개의 상세 내용입니다. 자세한 내용은 PHP 중국어 웹사이트의 기타 관련 기사를 참조하세요!

성명:
본 글의 내용은 네티즌들의 자발적인 기여로 작성되었으며, 저작권은 원저작자에게 있습니다. 본 사이트는 이에 상응하는 법적 책임을 지지 않습니다. 표절이나 침해가 의심되는 콘텐츠를 발견한 경우 admin@php.cn으로 문의하세요.