javascript 使用 HtmlWebackPlugin 时如何在 <head> 和 <body> 标签中添加某些脚本标签

声明:本页面是StackOverFlow热门问题的中英对照翻译,遵循CC BY-SA 4.0协议,如果您需要使用它,必须同样遵循CC BY-SA许可,注明原文地址和作者信息,同时你必须将它归于原作者(不是我):StackOverFlow 原文地址: http://stackoverflow.com/questions/51285711/
Warning: these are provided under cc-by-sa 4.0 license. You are free to use/share it, But you must attribute it to the original authors (not me): StackOverFlow

提示:将鼠标放在中文语句上可以显示对应的英文。显示中英文
时间:2020-10-29 09:29:31  来源:igfitidea点击:

How do I add certain script tags inside <head> and <body> tags when using HtmlWebackPlugin

javascriptwebpackhtml-webpack-plugin

提问by Greeen Apple

I'm using HtmlWebpackPlugin to generate HTML files with javascript.

我正在使用 HtmlWebpackPlugin 用 javascript 生成 HTML 文件。

Now I would like to add custom script at different parts of <head>and <body>tags

现在,我想在不同的部位添加自定义脚本<head><body>标签

Example:

例子:

How do I,

我如何,

  1. Add <script> alert('in head tag') </script>inside the <head>tag as the first child
  2. Add <script> alert('in body tag') </script>inside the <body>tag as the first child
  1. 添加<script> alert('in head tag') </script>内部<head>标签的第一个孩子
  2. 添加<script> alert('in body tag') </script>内部<body>标签的第一个孩子

Here is the snippet in my Webpack config

这是我的 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
        }
    })

回答by theOneWhoKnocks

Your question is a bit confusing. It implies you want to add static script tags to your template. If that's the case you just need to go into your src/pages/app.page.htmlfile and add those two script tags in the headand body.

你的问题有点混乱。这意味着您要向模板添加静态脚本标签。如果这是你只需要进入你的情况src/pages/app.page.html文件,并在添加这两个脚本标记headbody

What I'm guessing that you're asking is "How do I insert generated bundles in two different areas of my template?". If that's the case there's a sectionin the docs that mentions what data is passed to the template file:

我猜您要问的是“如何在模板的两个不同区域插入生成的包?” . 如果是这种情况,文档中有一个部分提到了传递给模板文件的数据:

"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": []
      },
    }
  }
}

So if your entrylooked like

所以如果你entry看起来像

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

and your plugin was set to

你的插件被设置为

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

then app.page.ejsshould be able to access the data from the plugin and you can place those entries where ever you'd like. There's a large ejs example filein their repo. A simpler example, and one more specific to your use case would be:

然后app.page.ejs应该能够从插件访问数据,您可以将这些条目放在您想要的任何位置。他们的 repo 中有一个很大的ejs 示例文件。一个更简单的例子,更具体到你的用例是:

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

Note that I'm not using files.jsbut rather files.chunkssince you can access single files by entry name instead.

请注意,我不是在使用files.js而是files.chunks因为您可以通过条目名称访问单个文件。



Multi-Page Set-Up

多页设置

For a multi-page set-up your WP config could look like

对于多页设置,您的 WP 配置可能如下所示

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;

The template would look something like

模板看起来像

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

回答by IVO GELOV

You can use template parameters like shown in the official example

您可以使用官方示例中所示的模板参数

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

回答by Archit Garg

I came across the same problem that's why I created a plugin.

我遇到了同样的问题,这就是我创建插件的原因。

  • HtmlWebpackInjector- A HtmlWebpackPluginhelper to inject some chunks to head

  • It works with HtmlWebpackPluginand by just adding _headin the name of chunk, it automaticlly injects the chunk in the head.

  • 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()
  ]
}

This automatically injects indexchunk to the body and index_headto the head of the html document. Final html looks like:

这会自动将index块注入正文和index_headhtml 文档的头部。最终的 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>

回答by smackjax

I apologize for necro-ing your question, but I had the same problem and was brought here.

我很抱歉让你的问题变得毫无意义,但我遇到了同样的问题并被带到了这里。

So...I made a plugin. And it seems to work.

所以...我做了一个插件。它似乎有效。

This(as of 2019-11-20) might require you to uninstall html-webpack-plugin(current stable), then install html-webpack-plugin@next.

这(截至 2019 年 11 月 20 日)可能需要您卸载 html-webpack-plugin(当前稳定版),然后安装 html-webpack-plugin@next。

TL;DR:

特尔;博士:

I made a plugin that replaces or inserts text in the htmlWebpackPluginoutput. That means any text, anywhere, as long as what you're searching for is unique on the page(like a </body>tag).

我制作了一个插件,可以在htmlWebpackPlugin输出中替换或插入文本。这意味着任何文本,任何地方,只要您搜索的内容在页面上是唯一的(如</body>标签)。

Here's how

就是这样

html-webpack-plugin gives hooks for it's compilation process. I made a plugin that searches the output string(after it's been compiled) and adds a custom string either before, after, or replacing the one that was searched.

html-webpack-plugin 为其编译过程提供了钩子。我制作了一个插件来搜索输出字符串(在它被编译之后)并在之前、之后或替换被搜索的字符串之前添加一个自定义字符串。

Here's why

这就是为什么

My problem was creating a minimal-pain Wordpress theme framework with Webpack that automates the more tedious parts. (I know it's a mouthful)

我的问题是使用 Webpack 创建一个最小痛苦的 Wordpress 主题框架,它可以自动化更乏味的部分。(我知道这是一口)

I needed to inject an async script tag for browser-sync to connect with the page. But(like you) I couldn't find a way to universally attach a script to the page without a bit of boilerplate.

我需要为浏览器同步注入一个异步脚本标签以与页面连接。但是(像您一样)我找不到一种方法可以在没有一点样板的情况下将脚本普遍附加到页面上。

So I made a plugin that put the string I needed into each file that contained the string </body>, because that would mean it was a full-page template and I wanted each full page template to automatically refresh when I updated the source file.

所以我做了一个插件,将我需要的字符串放入每个包含字符串的文件中</body>,因为这意味着它是一个整页模板,我希望每个整页模板在我更新源文件时自动刷新。

It works!

有用!

The only issue I've found is having to escape an already escaped backslash, because the output is run through a compiler before actually being html in the browser.

我发现的唯一问题是必须转义已经转义的反斜杠,因为输出在浏览器中实际成为 html 之前通过编译器运行。

So just be warned you might have to fudge it a bit, and there are no doubt more problems like that someone will run into.

所以请注意,您可能需要稍微捏造一下,毫无疑问,有人会遇到更多类似的问题。

But I'll go out on a limb and say this looks like the solution to what you were originally asking.

但是我会冒昧地说这看起来像是您最初要求的解决方案。

Again, the plugin:

再次,插件:

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

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

If it's not what you're looking for or you have problems, let me know!

如果这不是您要查找的内容或遇到问题,请告诉我!

回答by las vega

use this settings.

使用此设置。

template: root to your html file

模板:根到您的 html 文件

new HtmlWebpackPlugin({
    title: "chucknorris-app",
    template: "./src/template.html",
}),