I'm currently developing a web application and am in the process of refactoring my code so it's bundled by WebPack.
In my HTML I have a button that calls the sendMessage()
function when clicked,
<button type="button" class="btn btn-default" onclick="sendMessage(document.getElementById('claim').value)">Submit</button>
In the first version of my code, the sendMessage()
function was defined in a .js
file that I imported directly in the HTML,
<script src="my_js/newsArticleScript.js"></script>
The sendMessage() function is directly declared in the file, it's not inside any class or module but it calls other functions defined on the same file, so I don't want to separate it.
But now it's being bundled by WebPack. Here is my config file (the homepageScript.js
is for another page):
const path = require('path')
module.exports = {
entry: {
homepage: './src/homepageScript.js',
newspage: './src/newsArticleScript.js'
},
output: {
filename: '[name].bundle.js',
path: path.resolve(__dirname, 'dist/my_js')
}
}
I'm currently developing a web application and am in the process of refactoring my code so it's bundled by WebPack.
In my HTML I have a button that calls the sendMessage()
function when clicked,
<button type="button" class="btn btn-default" onclick="sendMessage(document.getElementById('claim').value)">Submit</button>
In the first version of my code, the sendMessage()
function was defined in a .js
file that I imported directly in the HTML,
<script src="my_js/newsArticleScript.js"></script>
The sendMessage() function is directly declared in the file, it's not inside any class or module but it calls other functions defined on the same file, so I don't want to separate it.
But now it's being bundled by WebPack. Here is my config file (the homepageScript.js
is for another page):
const path = require('path')
module.exports = {
entry: {
homepage: './src/homepageScript.js',
newspage: './src/newsArticleScript.js'
},
output: {
filename: '[name].bundle.js',
path: path.resolve(__dirname, 'dist/my_js')
}
}
I changed the script import on the HTML to import the bundled version. And now, when I press the button I get the error
[Error] ReferenceError: Can't find variable: sendMessage
I've read about it, and I learned that webpack does not expose the functions globally. I have tried to export the function, but kept getting the same error.
Can anyone help me with this? Essentially what I need is to understant how to configure webpack or change the JS so it can be accessed by the HTML.
I'm new to JS so I'm pretty sure the way my app is designed is not the best, so any tips on improvements (maybe I should use modules, or there are better ways of calling JS function upon clicking a button) would be wele as well. Thank you :)
Share Improve this question asked Nov 23, 2017 at 0:00 jsantosjsantos 3022 silver badges9 bronze badges2 Answers
Reset to default 14Generally using text-based event handlers isn't a good idea. That said, you have a few options, with increasing amounts of changes.
For texual
onchange
handlers to work,sendMessage
would have to be a global. So the quickest fix would be to change your code to do that. If for instance you havefunction sendMessage(arg){}
in your code, you'd add an additional
window.sendMessage = sendMessage;
after it to expose it as a global variable.
A more modern approach would be to remove the
onchange
from the button and have the button labeled with an ID in the HTML, e.g.id="some-button-id"
.Then in your JS code, you could do
var button = document.querySelector("#some-button-id"); button.addEventListener("change", function(){ sendMessage(document.getElementById('claim').value); });
to add the
change
handler function using JS code, instead of with HTML attributes.
To add a modern option using webpack's library output (https://webpack.js/configuration/output/#outputlibrary) you can expose your modules exports by defining an output variable for your module in your webpack config, like so:
module.exports = {
...
output: {
...
library: 'MyLibrary'
}
}
Now assuming you webpack entry point js file uses a namedExport
function, you will be able to call it within your html or a subsequent script with:
MyLibrary.namedExport()
So in the original question, assuming the newsArticleScript.js
exports the sendMessage
function as a named export (export const sendMessage = (arg) => ...
) and the webpack config defines the output variable NewsArticle
, the sendMessage could be used as onclick handler with
<button .. onclick="NewsArticle.sendMessage(...) />