web-dev-qa-db-fra.com

Comment puis-je ajouter certaines balises de script à l'intérieur des balises <head> et <body> lors de l'utilisation du plug-in Html Webpack

J'utilise HtmlWebpackPlugin pour générer des fichiers HTML avec javascript.

Maintenant, je voudrais ajouter un script personnalisé à différentes parties des balises <head> Et <body>

Exemple:

Comment puis-je,

  1. Ajoutez <script> alert('in head tag') </script> à l'intérieur de la balise <head> En tant que premier enfant
  2. Ajoutez <script> alert('in body tag') </script> à l'intérieur de la balise <body> En tant que premier enfant

Voici l'extrait de ma configuration 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

Votre question est un peu déroutante. Cela implique que vous souhaitez ajouter des balises de script statiques à votre modèle. Si tel est le cas, il vous suffit d'entrer dans votre src/pages/app.page.html et ajoutez ces deux balises de script dans head et body.

Ce que je suppose que vous demandez est "Comment puis-je insérer des bundles générés dans deux zones différentes de mon modèle?" . Si c'est le cas, il y a un section dans les documents qui mentionne quelles données sont passées au fichier modèle:

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

Donc, si votre entry ressemblait à

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

et votre plugin a été défini sur

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

puis app.page.ejs devrait pouvoir accéder aux données du plugin et vous pouvez placer ces entrées où vous le souhaitez. Il y a un gros fichier d'exemple ejs dans leur dépôt. Un exemple plus simple et plus spécifique à votre cas d'utilisation serait:

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

Notez que je n'utilise pas files.js mais plutôt files.chunks puisque vous pouvez accéder à des fichiers uniques par nom d'entrée à la place.


Configuration multi-page

Pour une configuration de plusieurs pages, votre configuration WP pourrait ressembler à

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;

Le modèle ressemblerait à quelque chose

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

Je suis tombé sur le même problème, c'est pourquoi j'ai créé un plugin.

  • HtmlWebpackInjector - Un assistant HtmlWebpackPlugin pour injecter quelques morceaux à la tête

  • Cela fonctionne avec HtmlWebpackPlugin et en ajoutant simplement _head au nom du morceau, il injecte automatiquement le morceau dans la tête.

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

Cela injecte automatiquement index morceau dans le corps et index_head en tête du document html. Le html final ressemble à:

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

Je m'excuse d'avoir nécrété votre question, mais j'ai eu le même problème et j'ai été amené ici.

Alors ... j'ai fait un plugin. Et cela semble fonctionner.

Cela (à compter du 2019-11-20) pourrait vous obliger à désinstaller html-webpack-plugin (stable actuelle), puis à installer html-webpack-plugin @ next.

TL; DR:

J'ai créé un plugin qui remplace ou insère du texte dans la sortie htmlWebpackPlugin. Cela signifie que n'importe quel texte, n'importe où, tant que ce que vous recherchez est unique sur la page (comme un </body> tag).

Voici comment

html-webpack-plugin donne des crochets pour son processus de compilation. J'ai créé un plugin qui recherche la chaîne de sortie (après sa compilation) et ajoute une chaîne personnalisée avant, après ou en remplaçant celle qui a été recherchée.

Voici pourquoi

Mon problème était de créer un cadre de thème Wordpress avec Webpack qui automatise les parties les plus fastidieuses. (Je sais que c'est une bouchée)

J'avais besoin d'injecter une balise de script asynchrone pour que la synchronisation du navigateur se connecte à la page. Mais (comme vous), je ne pouvais pas trouver un moyen d'attacher universellement un script à la page sans un peu de passe-partout.

J'ai donc fait un plugin qui a mis la chaîne dont j'avais besoin dans chaque fichier qui contenait la chaîne </body>, car cela signifierait qu'il s'agit d'un modèle pleine page et que je souhaite que chaque modèle de page entière soit actualisé automatiquement lorsque je mets à jour le fichier source.

Ça marche!

Le seul problème que j'ai trouvé est d'avoir à échapper une barre oblique inverse déjà échappée, car la sortie est exécutée via un compilateur avant d'être réellement html dans le navigateur.

Alors soyez averti que vous devrez peut-être le tromper un peu, et il y a sans aucun doute plus de problèmes comme celui que quelqu'un rencontrera.

Mais je vais sortir sur un membre et dire que cela ressemble à la solution à ce que vous demandiez à l'origine.

Encore une fois, le plugin:

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

Si ce n'est pas ce que vous cherchez ou si vous avez des problèmes, faites le moi savoir!

1
smackjax

Vous pouvez utiliser des paramètres de modèle comme indiqué dans l'officiel exemple

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