I can't connect js script to my html file using handlebars engine (I use webpack)

95 Views Asked by At

When I paste script tag to html file which collected with html-buldler-webpack-plugin I getting error:

"TypeError: Found non-callable @@iterator".

This my webpack.config:

const path = require('path')
const HtmlBundlerPlugin = require('html-bundler-webpack-plugin')

module.exports = {
    mode: 'development',
    entry: './src/js/main.js',
    output: {
        filename: 'main.js',
        path: path.resolve(__dirname, 'build'),
        clean: true,
    },
    module: {
        rules: [
            {
                test: /\.js$/,
                exclude: /node_modules/,
                use: {
                    loader: 'babel-loader',
                    options: {
                        presets: ['@babel/preset-env'],
                    },
                },
            },
            {
                test: /\.scss$/,
                use: [
                    'style-loader',
                    'css-loader',
                    'sass-loader'
                ]
            },
            {
                test: /\.css$/,
                use: [
                    'style-loader',
                    'css-loader'
                ]
            },
        ],
    },
    plugins: [
        new HtmlBundlerPlugin({
            entry: {
                index: {
                    import: path.resolve(__dirname, 'src', 'index.html'),
                    // in data.js file I stored some data for handlebars template
                    data: path.resolve(__dirname, 'src', 'js', 'data.js'),
                },
            },
            preprocessor: 'handlebars',
            preprocessorOptions: {
                partials: ['src/partials'],
                helpers: {
                    arraySize: (array) => array.length,
                },
            },
        }),
    ],
    devServer: {
        static: {
            directory: path.join(__dirname, 'build')
        },
        compress: true,
        port: 3000,
        hot: true,
    },
}

My file structure

I expecting Html file with connected javascipt in bundle directory after start webpack build. Now I have just html file without connected js and bundled js file which don't connected to anywere.

2

There are 2 best solutions below

1
Aditya Jaiman On

You can try HtmlWebpackPlugin for that. Do,

npm install -D html-webpack-plugin

Then in your webpack.config.js file, set it up as a plugin

const HtmlWebpackPlugin = require('html-webpack-plugin');
module.exports = {
  mode: 'development',
  entry: './src/js/main.js',
  output: {
    filename: 'main.js',
    path: path.resolve(__dirname, 'build'),
    clean: true,
},
  plugins: [new HtmlWebpackPlugin({
    template: "src/index.html", //path to your HTML file
  })],
};

It will use your html file as a template to generate the build html file and will inject main.js automatically in it.

Use this link for HtmlWebpackPlugin documentation - https://github.com/jantimon/html-webpack-plugin

0
biodiscus On

the correct webpack config:

const path = require('path')
const HtmlBundlerPlugin = require('html-bundler-webpack-plugin')

module.exports = {
  mode: 'development',
  output: {
    path: path.resolve(__dirname, 'build'),
    clean: true,
  },
  module: {
    rules: [
      {
        test: /\.js$/,
        exclude: /node_modules/,
        use: {
          loader: 'babel-loader',
          options: {
            presets: ['@babel/preset-env'],
          },
        },
      },
      {
        test: /\.scss$/,
        use: [
          'css-loader',
          'sass-loader'
        ]
      },
      {
        test: /\.css$/,
        use: [
          'css-loader'
        ]
      },
    ],
  },
  plugins: [
    new HtmlBundlerPlugin({
      entry: {
        index: {
          import: path.resolve(__dirname, 'src', 'index.html'),
          // in data.js file I stored some data for handlebars template
          data: path.resolve(__dirname, 'src', 'js', 'data.js'),
        },
      },
      js: {
        // output filename of compiled JavaScript
        filename: 'js/[name].[contenthash:8].js',
      },
      css: {
        // output filename of extracted CSS, used if `inline` option is false (defaults)
        filename: 'css/[name].[contenthash:8].css',
        //inline: true, // inlines CSS into HTML
      },
      preprocessor: 'handlebars',
      preprocessorOptions: {
        partials: ['src/partials'],
        helpers: {
          arraySize: (array) => array.length,
        },
      },
    }),
  ],
  devServer: {
    static: {
      directory: path.join(__dirname, 'build')
    },
    compress: true,
    port: 3000,
    hot: true,
  },
}

Are you sure what the helper is correct?

helpers: {
  arraySize: (array) => array.length,
},

check what is the argument of the helper:

helpers: {
  arraySize: (options) => {
    console.log('=> arraySize: ', {options});
  },
},

the ./src/js/main.js and ./scss/main.scss source files must be specified directly in the ./src/index.html, not in Webpack.entry:

<!DOCTYPE html>
<html>
<head>
  <title>{{ title }}</title>
  {{! references to source style and script }}
  <link href="./scss/main.scss" rel="stylesheet">
  <script src="./js/main.js" defer="defer"></script>
</head>
<body>
  <h1>Hello World!</h1>
</body>
</html>

P.S. if that doesn't help, create a small repository with a reproducible error and create a new issue on GitHub, then I can help you.