-1

say i have a public/index.html file

and then a separate html file called otherScript which is just a file containing <script> tags with a script in

how would I inject this scripts into my public/index.html file?

I want to use new HtmlWebpackPlugin

but in the example it just says:

new HtmlWebpackPlugin({
  template: 'public/index.html'
  inject: true
})

I can't see anywhere that I should link to the other html file?

the venom
  • 661
  • 3
  • 9
  • 17
  • 3
    Why don't you create a JavaScript file instead? – Karan Dhir Aug 20 '18 at 14:07
  • because it's a script inside the tags.. – the venom Aug 20 '18 at 14:10
  • There is no way to do that using webpack, specially with html-webpack-plugin. The property inject refeers to injecting all the scripts created by webpack into that html you refeered on the template property. – PlayMa256 Aug 20 '18 at 14:25
  • *"because it's in script tags"* is not relevant. It shouldn't be. Fix the actual problem and you'll be able to include the script with no issues. – Reinstate Monica Cellio Aug 20 '18 at 14:29
  • @Archer what do you mean? It's in script tags because it's a newrelic script that needs injecting into my html file but i don't want to put it in the initial html. so how do I do this? – the venom Aug 20 '18 at 14:37
  • You remove the script tags, change the file extension to `.js` and include it with a script tag in the html file. – Reinstate Monica Cellio Aug 20 '18 at 14:38
  • so I don't use webpack at all? I need to though coz the script may sometimes not be needed – the venom Aug 20 '18 at 14:39
  • This really sounds like an [XY Problem](http://xyproblem.info/). I suggest you take a few steps back and start at the beginning. If you're having to try and force files with script tags into html files then you're doing something wrong. – Reinstate Monica Cellio Aug 20 '18 at 14:41
  • @Archer ok but if you don't think webpack can inject scripts in then I think you've not come across that part before because it can totally do that. I'm just not sure how, hence why I came here – the venom Aug 20 '18 at 14:44
  • https://github.com/petehunt/webpack-howto/issues/46 as people have mentioned here, very much possible. but solution is hard to find – the venom Aug 20 '18 at 14:46
  • I'm not saying it can't. You're saying you want to inject a html file with script tags and javascript in it. That is wrong. Fix that and your problem goes away. – Reinstate Monica Cellio Aug 20 '18 at 14:46
  • ok sure. lets say it's a JS file. and I import it in a script tag, that's leaving webpack out...I need it to be in webpack so I can conditionally include it or not – the venom Aug 20 '18 at 14:47
  • also importing it as a script seemed to fail and when I view the file in the browser it seems to think it's a html file even when I remove all the js? – the venom Aug 20 '18 at 14:57
  • @Archer when I import the file as a JS file into my html script tag I get this error: `Unexpected token <` and it's pointing to the first line: ` ` but that doctype syntax doesn't appear anywhere in my js file that I'm importing? – the venom Aug 21 '18 at 06:41

4 Answers4

2

If it's an HTML file, you can load it using a Webpack loader called raw-loader or you could use html-loader.

And use it like this:

Webpack.config

{
  test: /\.html$/,
  use: 'raw-loader'
}

Module

// import file

import htmlFile from 'myfile.html';

// insert the contents of file at end of body

var body = document.getElementsByTagName('body')[0];
body.insertAdjacentHTML('beforeEnd', htmlFile);

However, an HTML file full of script tags sounds like bad practice IMO.

If you want to inject the scripts to the page, I would suggest using a different method entirely.

One way would be to import the scripts as normal using import or require, or you could have an array of dependencies to load and load them all like this:

var dependencies = [
    'path/to/script/1.js',
    'path/to/script/2.js'
]

for(var i = 0; i < dependencies.length; i++) {
    let script = document.createElement('script');
     script.type = 'text/javascript';
     script.src = dependencies[i];
     document.getElementsByTagName('head')[0].appendChild(script);
}
Martin Geldart
  • 407
  • 2
  • 8
1

You can use the html-webpack-tags-plugin plugin.

This is helpful if you want to enable cache busting on the script, which was the main reason I didn't want to just use the copy-webpack-plugin and a static script element.

webpack.dev.config.js

new HtmlWebpackTagsPlugin({
  // this script must be loaded before all other scripts
  append: false,
  tags: ['src/myScript.js'],
}),

webpack.prod.config.js

new HtmlWebpackTagsPlugin({
  // this script must be loaded before all other scripts
  append: false,
  tags: ['src/myScript.js'],
  useHash: true,
  addHash: (assetPath, hash) => {
    const parts = assetPath.split('.');
    parts[parts.length - 1] = `${hash}.${parts[parts.length - 1]}`;
    return parts.join('.');
  },  
}),
Jens Bodal
  • 1,707
  • 1
  • 22
  • 32
0

There is no way to do that using webpack, specially with html-webpack-plugin. The property inject refeers to injecting all the scripts created by webpack into that html you refeered on the template property.

PlayMa256
  • 6,603
  • 2
  • 34
  • 54
  • im sure you can inject scripts in. you're saying there is absolutely no way to inject code into the html file? – the venom Aug 20 '18 at 15:14
  • Using pure webpack, without manually touching the html, no you cant. – PlayMa256 Aug 20 '18 at 15:49
  • You could do what martin has answered, which is a valid way. But i guess it is not how you want to do – PlayMa256 Aug 20 '18 at 15:50
  • when I import the file as a JS file into my html script tag I get this error: `Unexpected token <` and it's pointing to the first line: ` ` but that doctype syntax doesn't appear anywhere in my js file that importing? – the venom Aug 21 '18 at 06:40
  • show us an example on how your js file looks like and how you are importing on html. – PlayMa256 Aug 21 '18 at 11:26
0

Yes, we can do this. I made some example, hope it will help you.

In webpack js:

const path = require('path');
const webpack = require('webpack');
const TerserPluign = require('terser-webpack-plugin');
const MiniCssExtractPlugin = require('mini-css-extract-plugin');
const { CleanWebpackPlugin } = require('clean-webpack-plugin');
const HtmlWebpackPlugin = require('html-webpack-plugin');

module.exports = {
  entry: {
    index: './src/assets/js/index.js',
    about: './src/assets/js/about.js'
  },
  output: {
    filename: '[name].[contenthash].js',
    path: path.resolve(__dirname, './build'),
    // publicPath: 'my-domain/'
  },
  mode: 'none',
  module: {
    rules: [
      {
        test: /\.(jpg|png)$/,
        type: 'asset',
        parser: {
          dataUrlCondition: {
            maxSize: 60 * 1024 // max size 60 kilobytes.
          }
        }
      },
      {
        test: /\.txt/,
        type: 'asset/source',
      },
      {
        test: /\.(scss|css)$/,
        use: [
          MiniCssExtractPlugin.loader, 'css-loader', 'sass-loader'
        ]
      },
      {
        test: /\.(less)$/,
        use: [
          // 'style-loader', 'css-loader', 'less-loader'
          MiniCssExtractPlugin.loader, 'css-loader', 'less-loader'
        ]
      },
      {
        test: /\.js$/,
        exclude: /node_modules/,
        use: {
          loader: 'babel-loader',
          options: {
            presets: [ '@babel/env'],
            plugins: [ '@babel/plugin-proposal-class-properties']
          }
        }
      },
      {
        test: /\.hbs$/,
        use: [
          'handlebars-loader'
        ]
      },
    ]
  },
  plugins: [
    new webpack.DefinePlugin({
        'process.env.NODE_ENV': JSON.stringify('development'),
        'global': {},
    }),
    new TerserPluign(), // To use reduce size of bundle files,
    new MiniCssExtractPlugin({
      filename: "[name].[contenthash].css"
    }),
    new CleanWebpackPlugin({
      cleanOnceBeforeBuildPatterns: [
        '**/*',
        path.join(process.cwd(), 'dummyBuildFolder/**/*')
      ]
    }),
    new HtmlWebpackPlugin({
      title: 'Default HTML',
      filename: 'index.html',
      template: 'src/templates/index.hbs',
      description: 'this is meta description for index page',
      chunks: ['index']
    }),
    new HtmlWebpackPlugin({
      title: 'About Us HTML',
      filename: 'about.html',
      template: 'src/templates/about.hbs',
      description: 'this is meta description for about us page',
      chunks: ['about']
    })
  ]
}

Above will generate two files, index.html and about.html

In index.html:

<!DOCTYPE html>
<html>
  <head>
    <meta charset="utf-8">
    <title>Default HTML</title>
    <meta name="description" content="this is meta description for index page" />
    <meta name="viewport" content="width=device-width, initial-scale=1">
    <script defer src="index.22a0682faed73cf496ac.js"></script>
    <link href="index.2ab526c55a3c67e01bfb.css" rel="stylesheet">
  </head>
  <body>
    <div id="my_root" />
    <div id="initialMessage"></div>
    <div id="lipsumTxtId"></div>
  </body>
</html>

In about.html

<!DOCTYPE html>
<html>
  <head>
    <meta charset="utf-8">
    <title>About Us HTML</title>
    <meta name="description" content="this is meta description for about us page" />
    <meta name="viewport" content="width=device-width, initial-scale=1">
    <script defer src="about.0d3ba2ce20763dbd16dc.js"></script>
    <link href="about.352d245e3219b89be11d.css" rel="stylesheet"></head>
  <body />
</html>