Jleibham Jleibham - 1 month ago 13
Javascript Question

document.getElementById not working with Webpack

I've been trying to implement basic Javascript with Webpack but have found a lot of trouble trying to get basic methods to work. I know it is probably a problem with my js loading before the DOM but all my fixes to this issue have been futile.

For instance, I'm trying to just run

let taskinput = document.getElementById('new-task');
and when I search the taskinput variable in the console I get a return of
Uncaught ReferenceError: taskinput is not defined(…)
.

I've tried quite a few different solutions to make this code operate after the DOM has loaded but nothing seems to work.

I tried the basic attempt of just putting my javascript file at the bottom of the DOM.

I've tried a basic js method like so:

document.onreadystatechange = function() {
if (document.readyState === "complete") {
initApplication();
}

function initApplication() {(... placed code in here ...)}


I've tried using jqueries

$( document ).ready(function() { });


I've tried injecting my javascript file into my HTML with the html-webpack-plugin

Is there something I'm missing with Webpack?

index.html

<!DOCTYPE html>
<html>
<head>
<meta charset="utf-8">
<title>Sample Site</title>
<meta name="viewport" content="width=device-width,initial-scale=1">
</head>
<body>
<button id="new-task">click</button>
<script src="/assets/app.bundle.js"></script>
</body>
</html>


app.js

'use strict';

document.onreadystatechange = function() {
if (document.readyState === "complete") {
initApplication();
}
}

function initApplication() {
onButtonClick();
}

let onButtonClick = function() {
let taskInput = document.getElementById('new-task');
taskInput.onclick = alert('hey');
}

Answer

For instance, I'm trying to just run let taskinput = document.getElementById('new-task'); and when I search the taskinput variable in the console I get a return of Uncaught ReferenceError: taskinput is not defined(…).

First of all, module code in webpack bundles is run in its own scope, effectively in a closure, and not in the global scope (which you can access with window). Secondly, even if you go to your console and declare a variable with let, for example let a = 1, even though your console operates in the global (window) scope, if you try to do window.a you will get undefined because let variables do not get attached to the window scope. See this

Is there something I'm missing with Webpack?

Probably the fact that the code in your bundles, generated by webpack, does not run in the global scope, as explained above.

If you want to expose a variable to the global scope in order to be able to use it, for debugging purposes, in the console, declare it as window.variableName. Or you can add a breakpoint in your code, by adding debugger, after the variable you want to check out, without exposing it to the global scope.