59

I have a basic HTML page with a button:

<!DOCTYPE html>
<html lang="en">
<head>
  ...
</head>
<body>
    <button id="button" onclick="uclicked()">Click me</button>
    <script src="./bundle.js"></script>
</body>
</html>

and an app.js:

//(function(){
    console.log('started up')
    function uclicked(){
        console.log('You clicked');
    }
//})();

webpack is installed and webpack --watch succeeds. The webpack.config.js is:

module.exports={
    entry: './app.js',
    output: {
        path: __dirname,
        filename: 'bundle.js'
    }
}

When I load the page console.log is working but when I push the button I get Uncaught ReferenceError: uclicked is not defined.

If I replace <script src="./bundle.js"></script> with <script src="./app.js"></script> and bypass webpack the button clicks fine. Why doesn't this basic webpack setup work?

Dan Dascalescu
  • 143,271
  • 52
  • 317
  • 404
mcktimo
  • 1,440
  • 4
  • 19
  • 35
  • 7
    `uclicked` references a global function, but webpack by default will encase your `bundle` in an iife, protecting the global scope. Use `addEventListener` in your code, or expose your app as a public object using the `expose-loader` https://github.com/webpack/expose-loader – Daniel Lizik Mar 03 '16 at 19:51

1 Answers1

139

When you run the file over webpack, webpack will try not to litter the global scope and so the function will not be made available globally by default.

If you want the function to be accessible outside the scope of he JS file, you should put it in the global scope.

function uclicked() {
  // do something
}
window.uclicked = uclicked;

Or just:

window.uclicked = function() {
  // do something
}
vidstige
  • 12,492
  • 9
  • 66
  • 110
Shiva Nandan
  • 1,835
  • 1
  • 13
  • 11
  • 5
    how do I access the function without making it global? – vidstige Apr 10 '17 at 14:21
  • 8
    @vidstige You would then have to manually set the event handler on the button like this: document.getElementByID('buttonID').onClick = function() { /* do somethiing */} You need to make sure that this script is called **after** the html has been loaded (you can do that by calling your script tag at the end of ). – Shiva Nandan Aug 17 '17 at 09:07
  • Thanks mate, this sorted my issue. – Josh Bonnick Oct 22 '20 at 22:54
  • Old answer but this is the best solution for this problem! – Mohamed Mar 09 '22 at 06:56
  • one tiny thing: it's not `document.getElementByID` but `document.getElementById` – luckyluke Nov 19 '22 at 19:26