web-dev-qa-db-ja.com

Html Webpackプラグインを使用しているときに<head>および<body>タグ内に特定のスクリプトタグを追加する方法

HtmlWebpackPluginを使用して、javascriptでHTMLファイルを生成しています。

ここで、_<head>_および_<body>_タグの異なる部分にカスタムスクリプトを追加したいと思います。

例:

どうすれば

  1. 最初の子として_<head>_タグ内に<script> alert('in head tag') </script>を追加します
  2. 最初の子として_<body>_タグ内に<script> alert('in body tag') </script>を追加します

ここに私のWebpack設定のスニペットがあります

_        new HtmlWebpackPlugin({
        hash: true,
        chunks: ["app"],
        filename: path.resolve(__dirname, "./public/pages/app.html"),
        title: "Title of webpage",
        template: path.resolve(__dirname, "./src/pages/app.page.html"),
        minify: {
            collapseWhitespace: true
        }
    })
_
6
Greeen Apple

あなたの質問は少しわかりにくいです。テンプレートに静的スクリプトタグを追加することを意味します。その場合は、src/pages/app.page.htmlファイルに移動して、これら2つのスクリプトタグをheadbodyに追加するだけです。

あなたが尋ねていると思うのは、「テンプレートの2つの異なる領域に生成されたバンドルを挿入するにはどうすればよいですか?」です。その場合は、ドキュメントに section があり、どのデータがテンプレートファイルに渡されるかが記載されています。

"htmlWebpackPlugin": {
  "files": {
    "css": [ "main.css" ],
    "js": [ "assets/head_bundle.js", "assets/main_bundle.js"],
    "chunks": {
      "head": {
        "entry": "assets/head_bundle.js",
        "css": [ "main.css" ]
      },
      "main": {
        "entry": "assets/main_bundle.js",
        "css": []
      },
    }
  }
}

あなたのentry

entry: {
  head: './src/file1.js',
  body: './src/file2.js',
}

プラグインは

new HtmlWebpackPlugin({
  template: './src/pages/app.page.ejs' // note the .ejs extension
})

app.page.ejsはプラグインのデータにアクセスできるはずです。これらのエントリを好きな場所に配置できます。リポジトリには大きな ejsサンプルファイル があります。より簡単な例と、ユースケースに固有のもう1つの例を次に示します。

<!DOCTYPE html>
<head>
  <% if(htmlWebpackPlugin.files.chunks.head) { %>
  <script src="<%= htmlWebpackPlugin.files.chunks.head.entry %>"></script>
  <% } %>
</head>
<body>
  <% if(htmlWebpackPlugin.files.chunks.body) { %>
  <script src="<%= htmlWebpackPlugin.files.chunks.body.entry %>"></script>
  <% } %>
</body>
</html>

代わりにエントリ名で単一のファイルにアクセスできるため、files.jsではなくfiles.chunksを使用していることに注意してください。


マルチページ設定

複数ページのセットアップの場合、WP configは次のようになります

const pages = [
  'home',
  'about',
];

const conf = {
  entry: {
    // other entries here
  }
  output: {
    path: `${ __dirname }/dist`,
    filename: 'scripts/[name].js'
  },
  plugins: [
    // other plugins here
  ]
};

// dynamically add entries and `HtmlWebpackPlugin`'s for every page
pages.forEach((page) => {
  conf.entry[page] = `./src/pages/${ page }.js`;
  conf.plugins.Push(new HtmlWebpackPlugin({
    chunks: [page],
    // named per-page output
    filename: `${ __dirname }/dist/pages/${ page }.html`,
    googleAnalytics: { /* your props */ },
    // shared head scripts
    headScripts: [
      {
        src: 'scripts/jQuery.js'
      },
      {
        content: `
          console.log('hello world');
          alert('huzah!');
        `
      }
    ],
    // per-page html content
    pageContent: fs.readFileSync(`./src/pages/${ page }.html`, 'utf8'),
    // one template for all pages
    template: './src/pages/Shell.ejs',
  }));
});

module.exports = conf;

テンプレートは次のようになります

<!DOCTYPE html>
<head>
  <%
    for (var i=0; i<htmlWebpackPlugin.options.headScripts.length; i++) {
      var script = htmlWebpackPlugin.options.headScripts[i];
  %>
  <script
    <% if(script.src){ %>src="<%= script.src %>"<% } %>
  >
    <% if(script.content){ %><%= script.content %><% } %>
  </script>
  <% } %>
</head>
<body>
  <% if(htmlWebpackPlugin.options.pageContent) { %>
  <%= htmlWebpackPlugin.options.pageContent %>
  <% } %>

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

  <% if (htmlWebpackPlugin.options.googleAnalytics) { %>
  <script>
    (function(i,s,o,g,r,a,m){i['GoogleAnalyticsObject']=r;i[r]=i[r]||function(){
      (i[r].q=i[r].q||[]).Push(arguments)},i[r].l=1*new Date();a=s.createElement(o),
      m=s.getElementsByTagName(o)[0];a.async=1;a.src=g;m.parentNode.insertBefore(a,m)
    })(window,document,'script','//www.google-analytics.com/analytics.js','ga');
    <% if (htmlWebpackPlugin.options.googleAnalytics.trackingId) { %>
      ga('create', '<%= htmlWebpackPlugin.options.googleAnalytics.trackingId%>', 'auto');
      <% } else { throw new Error("html-webpack-template requires googleAnalytics.trackingId config"); }%>
    <% if (htmlWebpackPlugin.options.googleAnalytics.pageViewOnLoad) { %>
      ga('send', 'pageview');
    <% } %>
  </script>
  <% } %>
</body>
</html>
11
theOneWhoKnocks

プラグインを作成したのは同じ問題に出くわしたためです。

  • HtmlWebpackInjector -いくつかのチャンクを先頭に挿入するHtmlWebpackPluginヘルパー

  • HtmlWebpackPluginで動作し、_headをチャンクの名前に追加するだけで、自動的にヘッドにチャンクを挿入します。

const HtmlWebpackPlugin = require('html-webpack-plugin');
const HtmlWebpackInjector = require('html-webpack-injector');

module.exports = {
  entry: {
    index: "./index.ts",
    index_head: "./index.css" // add "_head" at the end to inject in head.
  },
  output: {
    path: "./dist",
    filename: "[name].bundle.js"
  },
  plugins: [
    new HtmlWebpackPlugin({
      template: "./index.html",
      filename: "./dist/index.html",
      chunks: ["index", "index_head"]
    }),
    new HtmlWebpackInjector()
  ]
}

これにより、indexチャンクがhtmlドキュメントの本体に、index_headが自動的に挿入されます。最終的なhtmlは次のようになります。

<!DOCTYPE html>
<html>
  <head>
    <meta charset="utf-8">
    <title>Archit's App</title>
    <script type="text/javascript" src="index_head.bundle.js"></script> <--injected in head
  </head>
  </head>
  <body>
    <script src="index_bundle.js"></script> <--injected in body
  </body>
</html>
1
Archit Garg

あなたの質問を壊したことをおpoびしますが、私は同じ問題を抱えており、ここに連れて来られました。

だから...私はプラグインを作りました。そして、それはうまくいくようです。

これ(2019-11-20現在)では、html-webpack-plugin(現在の安定版)をアンインストールしてから、html-webpack-plugin @ nextをインストールする必要があります。

TL; DR:

htmlWebpackPlugin出力のテキストを置換または挿入するプラグインを作成しました。これは、検索対象がページ上で一意である限り、任意のテキストをどこでも意味します(</body>タグなど)。

方法は次のとおりです

html-webpack-pluginは、コンパイルプロセスのフックを提供します。出力文字列を(コンパイル後に)検索し、検索された文字列の前、後、または置換のいずれかにカスタム文字列を追加するプラグインを作成しました。

理由は次のとおりです

私の問題は、最小限の痛みを作成することでしたWordpressテーマフレームワークは、より退屈な部分を自動化するWebpackを使用します。

Browser-syncがページに接続するための非同期スクリプトタグを挿入する必要がありました。しかし、(あなたのように)ちょっとした決まり文句なしに普遍的にスクリプトをページに添付する方法を見つけることができませんでした。

そこで、文字列</body>を含む各ファイルに必要な文字列を挿入するプラグインを作成しました。これは、それがフルページテンプレートであり、ソースを更新したときに各フルページテンプレートが自動的に更新されるようにするためですファイル。

できます!

私が見つけた唯一の問題は、すでにエスケープされているバックスラッシュをエスケープする必要があることです。これは、ブラウザで実際にhtmlになる前に出力がコンパイラーで実行されるためです。

ですので、少し間違えなければならないかもしれませんが、誰かが出くわすような問題は間違いなくあります。

しかし、私は手足に出て、これがあなたが元々求めていたものに対する解決策のように見えると言います。

繰り返しますが、プラグイン:

https://github.com/smackjax/html-webpack-inject-string-plugin

探しているものではない場合や問題がある場合は、お知らせください!

1
smackjax

公式の に示されているようなテンプレートパラメータを使用できます。

var path = require('path');
var HtmlWebpackPlugin = require('../..');
var webpackMajorVersion = require('webpack/package.json').version.split('.')[0];
module.exports = {
  context: __dirname,
  entry: './example.js',
  output: {
    path: path.join(__dirname, 'dist/webpack-' + webpackMajorVersion),
    publicPath: '',
    filename: 'bundle.js'
  },
  plugins: [
    new HtmlWebpackPlugin({
      templateParameters: {
        'foo': 'bar'
      },
      template: 'index.ejs'
    })
  ]
};
1
IVO GELOV