webdiscus / html-bundler-webpack-plugin

Alternative to html-webpack-plugin ✅ Renders Eta, EJS, Handlebars, Nunjucks, Pug, Twig templates "out of the box" ✅ Resolves source files of scripts, styles, images in HTML ✅ Uses a template as entry point
ISC License
138 stars 14 forks source link

html template inline scripts import statement fetching another script don't seem to resolve in output html files #72

Closed sam1git closed 8 months ago

sam1git commented 8 months ago

It appears that if I have inline script such as shown below in my html template file, then the output html file still has the path ../scripts/someScript.js instead of changing this to HtmlBundlerWebpackPlugin js.filename that is changing the path that would point to output asset js files.

Does HtmlBundlerWebpackPlugin support resolving these kind of import statements in html templates?

<script type="module">
    import { someMethod } from '../scripts/someScript.js';
</script>
webdiscus commented 8 months ago

@sam1git,

The code in <script>...</script> tag stay as is, w/o transformation. This is right so.

If you want use import and other non-standard JavaScript constructions, you should do it in separate JS file, that will be compiled via Webpack. If you want compile all-in-one HTML file, you can use the js.inline and css.inline options.

See please:

For example:

myLib.js

const content = 'Hello World!';
export default content;

main.js

import content from './myLib.js';

console.log(content);
document.getElementById('root').innerHTML = content;

index.html

<!DOCTYPE html>
<html>
  <head>
    <title>Home</title>
    <script src="./main.js"></script>
  </head>
  <body>
    <div id="root"></div>
  </body>
</html>

Add js.inline and css.inline options:

const HtmlBundlerPlugin = require('html-bundler-webpack-plugin');
module.exports = {
  plugins: [
    new HtmlBundlerPlugin({
      entry: {
        index: 'src/index.html',
      },
      js: {
        inline: true,  // inline compiled JS into HTML
        filename: 'js/[name].[contenthash:8].js', // JS output filename, used if inline is false
      },
      css: {
        inline: true,  // inline extracted CSS into HTML
        filename: 'css/[name].[contenthash:8].css', // CSS output filename, used if inline is false
      },
    }),
  ],
};

The generated HTML contains inlined JS code:

<html>
  <head>
    <!-- the original script tag is replaced with compiled JS code -->
    <script>
      (() => {
        'use strict';
        const a='Hello World!'
        console.log(a);
        document.getElementById('root').innerHTML=a;
      })();
    </script>
  </head>
  <body>
    <div id="root"></div>
  </body>
</html>

P.S. please use the language casting after leading 3 backticks: html, js, css, scss, etc to highlight you code snippet.

sam1git commented 8 months ago

@sam1git,

The code in <script>...</script> tag stay as is, w/o transformation. This is right so.

If you want use import and other non-standard JavaScript constructions, you should do it in separate JS file, that will be compiled via Webpack. If you want compile all-in-one HTML file, you can use the js.inline and css.inline options.

See please:

For example:

myLib.js

const content = 'Hello World!';
export default content;

main.js

import content from './myLib.js';

console.log(content);
document.getElementById('root').innerHTML = content;

index.html

<!DOCTYPE html>
<html>
  <head>
    <title>Home</title>
    <script src="./main.js"></script>
  </head>
  <body>
    <div id="root"></div>
  </body>
</html>

Add js.inline and css.inline options:

const HtmlBundlerPlugin = require('html-bundler-webpack-plugin');
module.exports = {
  plugins: [
    new HtmlBundlerPlugin({
      entry: {
        index: 'src/index.html',
      },
      js: {
        inline: true,  // inline compiled JS into HTML
        filename: 'js/[name].[contenthash:8].js', // JS output filename, used if inline is false
      },
      css: {
        inline: true,  // inline extracted CSS into HTML
        filename: 'css/[name].[contenthash:8].css', // CSS output filename, used if inline is false
      },
    }),
  ],
};

The generated HTML contains inlined JS code:

<html>
  <head>
    <!-- the original script tag is replaced with compiled JS code -->
    <script>
      (() => {
        'use strict';
        const a='Hello World!'
        console.log(a);
        document.getElementById('root').innerHTML=a;
      })();
    </script>
  </head>
  <body>
    <div id="root"></div>
  </body>
</html>

P.S. please use the language casting after leading 3 backticks: html, js, css, scss, etc to highlight you code snippet.

sounds good, appreciate the help.