使用HtmlWebackPlugin时如何在标签和标签中添加某些脚本标签

时间:2018-07-11 12:39:52

标签: javascript webpack html-webpack-plugin

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

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

示例:

我如何

  1. 在其中添加<script> alert('in head tag') </script> <head>标签为第一个孩子
  2. 在其中添加<script> alert('in body tag') </script> <body>标签为第一个孩子

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

8 个答案:

答案 0 :(得分:3)

您的问题有点令人困惑。这意味着您要向模板添加静态脚本标签。如果是这种情况,您只需要进入src/pages/app.page.html文件并在headbody中添加这两个脚本标签即可。

我猜您要问的是“如何在模板的两个不同区域中插入生成的包?” 。如果是这种情况,则文档中会有一个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 example file。一个更简单的示例,以及一个针对您的用例的更具体示例:

<!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配置看起来像

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>

答案 1 :(得分:2)

我知道我迟到了,但这是我的解决方法。我可能会帮助别人。

  1. 我使用 inject:false 禁用了资产的自动注入。
new HtmlWebpackPlugin({
  hash: true, // hash for cache bursting
  template: "index.html", // source template
  minify: true, // should html file be minified?
  inject: false,
}) 
  1. 在模板文件中手动渲染资产。

头部的css

<% for (var css in htmlWebpackPlugin.files.css) { %>
<link href="<%= htmlWebpackPlugin.files.css[css] %>" rel="stylesheet">
<% } %>

主体中的js

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

您可以在这里进行任何类型的过滤/排序。

您可以在此处查看可用选项以及如何使用它们。

https://github.com/jaketrent/html-webpack-template/blob/master/index.ejs

答案 2 :(得分:1)

很抱歉给您的问题打个电话,但我遇到了同样的问题,因此被带到这里。

所以...我做了一个插件。似乎可行。

此操作(自2019年11月20日起)可能要求您卸载html-webpack-plugin(当前稳定版),然后安装html-webpack-plugin @ next。

TL; DR:

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

这是方法

html-webpack-plugin为其编译过程提供了挂钩。 我做了一个插件,可以搜索输出字符串(在编译后),并在搜索之前,之后或替换搜索字符串时添加自定义字符串。

这就是为什么

我的问题是使用Webpack创建一个痛苦最小的Wordpress主题框架,该框架可以自动完成较为繁琐的部分。 (我知道这是一口)

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

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

有效!

我发现的唯一问题是必须转义一个已经转义的反斜杠,因为输出实际上是通过编译器运行的,然后才在浏览器中显示为html。

因此请注意,您可能需要稍加捏造,毫无疑问,还会有更多问题出现,例如有人会遇到。

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

同样,插件:

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

如果不是您要找的东西或遇到问题,请告诉我!

答案 3 :(得分:1)

也许您可以使用 html-webpack-plugin/template-optionraw-loader

顺便说一句,如果你得到 default 结果,你需要使用 [object Module] 属性。

<!DOCTYPE html>
<html lang="en">
<head>
    <meta charset="UTF-8">
    <%= require('!!raw-loader!./common/file1').default %>
    <title>Document</title>
</head>
<body>
    <%= require('!!raw-loader!./common/file2').default %>
</body>
</html>

答案 4 :(得分:0)

您可以使用模板参数,如官方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'
    })
  ]
};

答案 5 :(得分:0)

使用此设置。

模板:root到您的html文件

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

答案 6 :(得分:0)

对我来说最简单的方法是:

// webpüack.config.js
new HtmlWebpackPlugin({
    template: 'index.html',
    templateParameters: {
        foo: process.env.BAR,
    },
}),
<!-- index.html -->
<% if (foo) { %>
    <script src="bar.min.js"></script>
<% } %>

像魅力一样工作

答案 7 :(得分:-1)

我遇到了同样的问题,这就是为什么我创建了一个插件。

  • 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文档的开头。最终的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>