user11720384
user11720384

Reputation:

How to have one main JavaScript file for multiple pages?

I have a small application with two pages: the login page and the main page. My problem is that when I use just one main JavaScript file for both pages (like it's recommanded) I get a lot of ReferenceError because some variables on a page are not defined on the other one...

e.g:

Line of code for the login page

copyrightYear.textContent = new Date().getFullYear();

Main page complains

Uncaught TypeError: Cannot set property 'textContent' of null

How can I fix that? Don't tell me I have to say if(copyrightYear) { do stuff } everytime, it's just a nightmare if I have to do that for every variable

Upvotes: 9

Views: 7828

Answers (2)

cloned
cloned

Reputation: 6752

You figured it out, you have to check this for every variable. But generally it's much more convenient to use functions and only call these functions when you need them.

So for example, say you want to set some copyrightYear (even tough this shouldn't be set via JS, you should generate this on Backend side to have it in the source code)

You have something like this:

function updateYear() {
  // here you do your magic of selecting the element, setting the year, whatever.
}

// another function, totally unrealted to updateYear()
function toggleMenu() {
  // some function where you toggle the menu if you click somewhere
  // like: button.addEventListener('click', () => {} );
}

And in your JS file you have one block where you call all these functions:

if (document.querySelectorAll('.elementForYear') {
  updateYear(); // here we call it because we are sure this element exists... so everything inside function must work
}
if (document.querySelector('.myMenu') {
  toggleMenu(); // if the element myMenu exists, we know we can add these toggle Functionality.
}  

You can also add these if inside the function and call the function regardless of if it's needed or not, that's up to you and up to coding guidelines.

Generally I find it makes sense to have one function only rely on one (or max two to three elements if it's some toggling of other elements) ... And then you just check for one element. And if this one element exists you can go ahead and call the function.

Upvotes: 2

T.J. Crowder
T.J. Crowder

Reputation: 1075785

Two answers for you:

The recommendation isn't a dictate

My problem is that when I use just one main JavaScript file for both pages (like it's recommanded)

That's a very general recommendation. It doesn't apply to every situation. There's no point in loading code in a page that won't use that code.

If you have code that you use in both pages, and also page-specific code, it's absolutely fine to have a file that both pages share and also page-specific files:

<script src="main.js"></script>
<script src="page1.js"></script>

If you're really worried about the extra HTTP request (much less of an issue these days than it used to be), use modules and a bundler like Webpack or Rollup that will create a bundle combining the main module with page 1's module for page 1 and another bundle combining the main module with page 2's module for page 2.

But even then, the extra HTTP request may be better for your users, if you expect them to go from page1 to page2 in a reasonable timeframe. The reason is that if you have main.js and page1.js/page2.js and you allow caching of them, when the user goes to page1 they get main.js and page1.js, and then when they go to page2 main.js comes out of their local cache and they only have to load page2.js. In contrast, if you had a single bundle file for each page, they'd have to re-download all of that common code when going from page1 to page2 (or vice versa). But if you expect a visitor to visit either page1 or page2 but not the other one, you save the HTTP request by using page-specific bundles.

There's really no one-size-fits-all solution. :-) There are all sorts of considerations.

Note that HTTP/1.1 made additional HTTP requests more efficient and is nearly universally supported, and HTTP/2 makes them a lot more efficient, effectively eliminating the case for reducing the number of HTTP requests as part of the page startup. All major modern browsers support HTTP/2 as do up-to-date web servers.

Put the code for each page in a function

If you really want to keep a single page, put the code that's specific to each page in functions for those pages, and then have code in the main part of the file call the appropriate function based on location.pathname.

Upvotes: 11

Related Questions