8

New Web Dev here.

Recently I got into DOM manipulation with JS, everything was sweet with one-page websites, but then I tried with projects with many html files and that's when I got confused.

It's a static website, each page has different elements so my first thought was "Ok so, one JS file per page, right?" And I think that's fine for a 2-3pages websites, but what if it is a medium size one? I mean 10-15 pages (home, login, profile page, settings, a gallery page with a carousel, etc). The browser would make so many requests.

I googled for a while and I read people who claim they 'merge' their JS files into one single script so I tried it. I don't know if I misunderstood something but I literally put all my JavaScript into one file, now I have a big JS file and a lot of errors on the console (obviously) because the script can't find a 'register' button on the home page, a 'profile-foto' in the login form and a 'carousel' on the settings page.

So here are my questions:

  1. What do they mean by 'merging' scripts?

  2. Is there a tool for that? How does it work?

  3. What do you do guys in these cases?

Thanks in advance!

4
  • 6
    "I read people who claim they 'merge' their JS files into one single script" - if you read something somewhere online, why don't you share a link, so readers don't have to guess around what you might have found?
    – Doc Brown
    Jan 20, 2022 at 4:37
  • The answers so far provide a great reference to look up various tools and practices, but since you're a newbie, you might find all the info a bit overwhelming. So let me just give you the core principle that you can build your understanding on. When a browser loads a script, it executes what's in it. Now, if you just do something like document.querySelectorAll('.my-class'), it will try to go through the document and find those elements. However, if you place that code in a function (or in an object), then when the script is executed, it'll just create the function (or the object), 1/2 Jan 20, 2022 at 12:18
  • but it won't execute its body until you explicitly make the call. You're basically declaring library code to be used later. That means that you can load that script on any page, but execute it only where you want it. Furthermore, you can parameterize such scripts - e.g. maybe the logic is the same on two different pages, but the CSS selector is different, so you pass in the selector. So you need to make a distinction between the more general, shared "library" scripts, and page-specific scripts that use them. This modularity stuff mentioned in answers is really a fancier version of that. 2/2 Jan 20, 2022 at 12:18
  • I think the answers here are a big misrepresentative of how omnipresent bundling your code with tools like webpack/esbuild is. I haven't seen a web project of >1000 LoC not using them in around 5-6 years. Jan 20, 2022 at 17:12

3 Answers 3

9

I will answer this from the standpoint of code organization and architecture, rather than which tools to use.


Typically multi-page sites have common library and framework code. This code is used on enough pages and in enough use cases that it becomes worthwhile to deliver that code in the initial page load. Since there are differences in what each page needs, you have a number of options to manage that code.

  1. Manually curate an additional file per page. To be honest, this technique has always created more problems than it solves. My recommendation is to avoid this. Too much code gets duplicated unless you use a javascript bundler.

  2. Use a javascript bundler to combine many smaller scripts into a custom file per page. This is more complicated, but allows you to reuse code, and have a tool replicate the code for you.

  3. Dynamically require the scripts while the page is loading. This technique likely uses RequireJS or ECMAScript imports. Only a small initializer script gets loaded when the page is first loaded. This initializer script then requires/imports the major modules for the current page. Each module is free to load additional dependencies. You will need to be well acquainted with asynchronous programming to utilize this technique, but it is worthwhile.

Contemporary web applications tend to use technique #3. Requiring the necessary scripts when the page loads rather than using embedded <script> tags gives you the best balance of code reuse and load time. The files are loaded asynchronously, which does not hold up the DOMContentLoaded event. This means web pages become reactive to user input quicker.

JavaScript bundlers are usually command line applications that read a config file and generate a new JavaScript file after combining multiple scripts. This helps reduce the number of requests when loading a page. This is an optimization for slow, unreliable network connections where the overhead of establishing a socket connection with the server is noticable to an end user. There is a balance here, though. Unreliable mobile networks can cause a lot of dropped packets. Large files can take a lot longer in this case than small files, which negates the speed boost you would expect.

Lots of people take public transportation and use their mobile devices to browse the web. These vehicles are made of metal and carry lots of people at a high rate of speed. Disconnecting from one cell tower and connecting to the next isn't too bad for one person. But when 1,000 people in an express train going 60mph do this network lag becomes horrible.

Until you can measure a performance problem, I recommend option #3. This provides the easiest way to manage an ever increasing number of scripts, and allows for infinite combinations so each page only loads what it needs.

3
  1. Whether a site architecture yields "too many requests" is really dependent on the site. Nothing about "10-15" pages screams "too many" to me, for what it's worth.

  2. Many sites "build" their JavaScript using a set of commands line tools. E.g.:

    1. JavaScript on the command line: node
    2. A package manager: npm or yarn
    3. A bundler: webpack, parcel, rollup, etc.
  3. They use a CI/CD service, (like GitHub Actions or Circle CI) to run their builds and manage deployments.

  4. Consider running through a course or tutorial on reactjs. This will teach you a front-end framework while familiarizing you with the CLI tools you're asking about.

2
  • Do those bundlers do anything beyond appending N files into a single new one?
    – BitTickler
    Jul 6 at 21:15
  • @BitTickler Yes. They often transpile, embed resources (images, css), minify, tree-shake, re-split chunks along meaningful boundaries, emit source maps for debugging, and probably other things I'm forgetting.
    – svidgen
    Jul 7 at 5:09
3

Welcome world of web development.

Recently I got into DOM manipulation with JS, everything was sweet with one-page websites, but then I tried with projects with many html files and that's when I got confused.

In principle it works the same way for one HTML file as for many of them. Back in the day - say in 2010 - the way to build websites was exactly this:

Each HTML file got a section with a script-Tag which either contained code to run on this HTML directly or loaded necessary JS off the web.

It was common to render your website on the server where you used your webframework and HTML templating techniques.

No reason to be confused.

The browser would make so many requests.

That's what browsers (and servers) are made for: Making (serving) many requests.

Which works basically fine. And to support this kind of behaviour one used typically HTTP Pipelinig

So, it is totally fine having different pages requiring different JS files. And don't forget the caching mechanism of the browser.

I googled for a while and I read people who claim they 'merge' their JS files into one single script so I tried it.

The process is called bundling. There are several ways to accomplish this from e.g. Browserify to Webpack - naming only two. People use these tools to help accomplish the task of bundling for them.

If you take for example webpack, it not only allows it to mash your Javascript together, but to intelligently split the complete bundle in easy digestible chunks (code splitting). This could be used together with the option to have multiple pages (entry points).

So you do not need to merge everything by yourselves.


What do they mean by 'merging' scripts?

As written above: bundling

Is there a tool for that? How does it work?

There are many tool which do solve the problem in different ways. The explanation of each of them is beyond the scope of this question.

What do you do guys in these cases?

Most of the time the decision which tool one chooses is answered for them externally, i.e. if you develop e.g. "classic vue2" you would use webpack.

For the rest: A good answer would be very subjective. One finds the problems of one bundler more acceptable than the problems of other bundlers. Every decision has its tradeoffs to make.

Not the answer you're looking for? Browse other questions tagged or ask your own question.