1

I am currently starting to use webpack for my website and I have a question.

I currently have a html page that includes my javascript bundle and has some onclick functions in buttons embedded in the html. I would like to keep the functionality of these buttons and the onclick, but currently I have not found a way to do this. Obviously, if I try to minify the javascript functions, the name of the function would change and it won't work.

Here's an example, where the bundle produced by webpack is included in the html file:

<button onclick="foo("bar")">test</button> and currently foo is undefined.

I have tried using html webpack plugin without success.

Is there any way to do this?

dan123123
  • 67
  • 1
  • 10

1 Answers1

2

Yes you can get to the function but you will still have to modify the code slightly - onClick.

webpack

const path = require('path');
const HtmlWebPackPlugin = require('html-webpack-plugin');
const {
  CleanWebpackPlugin
} = require('clean-webpack-plugin');

module.exports = (env, argv) => {
  return {
    devtool: argv.mode === 'production' ? 'none' : 'source-map',
    mode: argv.mode === 'production' ? 'production' : 'development',
    entry: {
      MYSCRIPT: './sources/script.js'
    },
    output: {
      path: path.resolve(__dirname, './dist'),
      filename: './[name].js',
      library: '[name]',
      libraryTarget: 'var',
    },
    module: {
      rules: [{
        test: /\.js$/,
        exclude: /node_modules/,
        use: {
          loader: 'babel-loader'
        }
      }, ]
    },
    plugins: [
      new CleanWebpackPlugin({
        verbose: true
      }),
      new HtmlWebPackPlugin({
        filename: 'index.html',
        template: './sources/index.html'
      })
    ]
  }
}

The most important part is the name entry and outputs. You must also export each function.

JS

export function test(type) {
  alert(type);
}

And we can get to the function this way.

HTML

<a onClick="MYSCRIPT.test('bar')">click</a>

You can find the whole devising example here.

Grzegorz T.
  • 3,903
  • 2
  • 11
  • 24
  • Thanks so much for this! One quick question - What does the `library` and `library target` do and how does the js get included in the html? Thanks so much. – dan123123 Nov 10 '19 at 13:23
  • You can find the exact description here [outputlibrarytarget](https://webpack.js.org/configuration/output/#outputlibrarytarget). You can check how the file is added at ```github/docs/index.html```, there is the resulting file. Remember if your library is large and fails to load and someone clicks onClick then an error will occur. This inline js solution in html is not and has never been a good solution;) – Grzegorz T. Nov 10 '19 at 13:54
  • Ah thanks for that - Out of interest, what would the "correct" way to do it be? On the page there are many buttons and I don't want to be adding 15+ event listeners.. is there another way to do this? Furthermore, what about dynamic lists which all have buttons that have different parameters? Sorry for so many questions :P – dan123123 Nov 10 '19 at 14:04
  • You're welcome. You can build one global function that will fire other functions. Maybe something like this in html ```data-click="{'function': 'foo', 'data': 'bar'}";``` Of course, it's all relative and depends on what features you have and how it looks with you. Good luck;) – Grzegorz T. Nov 10 '19 at 14:46
  • Ah I see. What are the benefits of doing this though? – dan123123 Nov 10 '19 at 15:03
  • The fact that you will not have errors in the console, the function will be performed after clicking only when the js file loads. – Grzegorz T. Nov 10 '19 at 15:06
  • Sorry to bother you again, I've just tried to add what you suggested - I have the function that I would like to run imported into `user.js` which is what gets bundled. The function is imported and I have tried this `onclick="user.Scripts.test()"` but it says that `user is undefined`. Is there anything that I can do? – dan123123 Nov 10 '19 at 15:30
  • Put on github if I have a moment to look. I don't know how your functions are built so I can't help without the code. – Grzegorz T. Nov 10 '19 at 15:33
  • I managed to fix it by adding the function to the global scope. I'm going to do what you said to, as that is a much better way of doing it :) Thanks for the help! – dan123123 Nov 10 '19 at 15:36