Check out a free preview of the full Webpack 4 Fundamentals course
The "History of Modules" Lesson is part of the full, Webpack 4 Fundamentals course featured in this preview video. Here's what you'd learn in this lesson:
Sean reviews the progression of JavaScript web development around the sharing modules, which are highly self-contained with distinct functionality that can be rearranged, removed, or added as necessary without disrupting the entire codebase.
Transcript from the "History of Modules" Lesson
[00:00:00]
>> Sean Larkin: And so you know the birth of JavaScript modules happened kind of around this early period thanks to Node.js. Who uses Node.js as like I mean, we all use it everyday. If you're using webpack, you're using node, you rely on node. Node is the canonical like you will find and maybe some, I know some .NET people don't like hearing this but if you want to build a canonical web application, be prepared to install node.
[00:00:29]
It is foundational for not only how we get packages, how we share packages, how we run our tools, our linters, our commands. And so Node.js, you have a problem here like node is JavaScript that runs on the server, right? They took theV8 engine and shove it in a like a binary and give it a runtime for the server side, but how do you load JavaScript if there's no DOM, right?
[00:00:58]
How do you add a script tag if there is no HTML in node, right, so that was the issue. And that is when the birth of CommonJS came about.
>> Sean Larkin: And so, what you'll see here is just a little example where you have three separate files. And to be able to actually include other files, they created the CommonJS module format.
[00:01:24]
The use a syntax called require, which allows you to inject other pieces of a module into the current module. So in here, we just we see I just broken it up into three separate files, but we had division.js. And so the syntax is used for CommonJS, you can have a default export or you can have named exports.
[00:01:46]
And so we're looking at a default export here which allows you to, and the syntax is module.exports. And it's just a function that takes two arguments, and returns the division for it, or the modulus, I can't remember which one that is. And then, we have another file that's pulling in the division, and you can see since it's just a default export, we can name it whatever the heck we want.
[00:02:09]
And, this module is defining some named exports. So this is saying exports.add, exports.subtract, exports.divide. And so that is this module's way of providing that scope or those values to another file if it wants to request it. So if we go up to our index.js here, we're actually pulling in these named exports, which all just get put under an object called the default export, and get required.
[00:02:43]
And then this way, so now we've just solved some scope. We just solved scope here without iffies or anything. We now can pull in pieces of values, assign them to variables in a different module without having problems with scope or anything like that. And actually kinda gave us a little static analysis, right, we can tell right here exactly what is used for the most part.
[00:03:08]
This is when the explosion of JavaScript starts. Like you may hear people, you may hear me say like JavaScript is taking over the world as a programming language, as a platform, as a way to rapidly develop and create fast running applications.
>> Sean Larkin: And it still boggles me today, like how new programming languages that get created don't adapt these models.
[00:03:36]
But like you think about it there is NPM, it is so easy to ship whatever module you want. And so NPM was created as a package registry to be able to share CommonJS node modules across an entire ecosystem and registry. And it's super easy to get started, NPM install whatever the heck I want.
[00:04:01]
>> Sean Larkin: And so, like the hyper mass distribution, everybody's starting to write all of their tools, all of their scripts, all of their utilities in JavaScript on node. And the module system really cause this pre-Cambrian just explosion of the evolving ecosystem. And even today it's even faster. But what are these problems?
[00:04:26]
There's still problems here. There is no browser support for CommonJS. You can't just go write a CommonJS module and load it in the browser. There's no live bindings, and this is specifically with circular references. So, as more modules started to be created and the ecosystem keeps rapidly developing, we started finding out like people are using modules in very interesting ways.
[00:04:53]
Trying to self-referral and having circular dependencies and things like that. And this really starts to show itself through CommonJS.
>> Sean Larkin: And the resolution algorithm for CommonJS is kinda slow, it's really slow. And it's built in to know, but it's still really, really slow cuz it's synchronous. By the way, did I say there's no browser support for CommonJS.
[00:05:20]
>> Sean Larkin: But is there a solution?
>> Sean Larkin: So, you'll start noticing that also people started wanting to ship their web modules through NPM. Like NPM was this huge instant. Like think of the time when you're writing web development three years ago. It was like, you had to go to a CDM or a GitHub distro, pull something down, concatenate it together.
[00:05:43]
And to a lot of people, that was unacceptable, especially those who were using Node. They were like, why don't we just ship these libraries out of Node.js, right, or NPM? And so people started doing that, but they would find out, crap, this CommonJS doesn't work. And so this is when bundlers and linkers we're really starting to take a popularity.
[00:06:06]
>> Sean Larkin: Who's heard of Browserify? Yep, who's heard of modules WebMake? [LAUGH] No, it's not very popular, but you'll find out why it's super important. But these bundlers started to be created, what they do, their main premise is to allow you to write CommonJS modules. But then it get bundled, and stripping those statements, and then executed in the same orders so that it works in the web exactly as it might work or you would expected to work in your code.
[00:06:34]
We all started to see different approaches like loaders, or things that like JavaScripts that executes in the browser that's responsible for going in dynamically realtime fetching, different module formats.
>> Sean Larkin: But there's also problems with this.
>> Sean Larkin: CommonJS is, when you look at it here, it doesn't look too harmful.
[00:07:00]
But the problem is that require is actually a function that you can pass anywhere. And so, we started seeing people abuse the crap out of CommonJS syntax, like I love Sindre Sorhus. Does anybody know who Sindre Sorhus is? He's probably the author of every, you use a package that he wrote for sure.
[00:07:22]
He's responsible for 300 billion downloads a year on NPM, or a month, I can't remember what it is, it's a staggering amount. But he writes these tiny packages. Like he'll write ones though that take require and you pass a require function in, and then you call it a different require.
[00:07:41]
And there's no way for bundlers to be able to statically analyze this stuff. We can't know without evaluating the code what's happening with this function. And so,
>> Sean Larkin: You end up with a lot of problems with getting really bloated bundles. And then there's no support for lazy loading in a way that we would expect.
[00:08:01]
Require sure it is kind of dynamic, but there's no way to asynchronously load something, especially for the web.
>> Sean Larkin: And like i said, CommonJS is just too dynamic of a module format to be able to have really optimized code.
>> Sean Larkin: And then the scary thing was not everybody was shipping CommonJS.
[00:08:25]
Like we had AMD which cropped up. So who's seen the AMD module pattern? You can thank Dojo for that I think or I think it came out of Dojo.
>> Sean Larkin: Even we had some libraries at Microsoft who use AMD today and it just kills me. Who has tried to bundle Moment.js with webpack and notice they end up with like 3 billion megabytes of code?
[00:08:48]
That's because they're using AMD and they're doing it too dynamic. They're using some dynamic capabilities of AMD that cause you to pull in every locale. If moment was just shipped in ESM, you wouldn't have any issues, but with legacy code, we all struggle with legacy things. Even Monaco in VS Code is written entirely AMD.
[00:09:10]
And one of the things I'm working right now with them is trying to push them as far away as possible from using AMD anymore.
>> Sean Larkin: And so, this is also like a design pattern, the angular kind of tough day like we want dependency injections. And this was before modules were a thing, right, and so it's seemed like a good idea.
[00:09:30]
And then there's also AMD + CommonJS, this is a thing, I would never write this but I've seen it done before.
>> Sean Larkin: But there's problems, like it's too dynamic, the MomentJS scenario. And it's more than just that, if you try to run the Monaco Editor, which is like so it's what gives you the VS Code like IEEE experience.
[00:09:54]
Basically, code Sandbox in stacklets basically just took Monaco Editor and threw it up in a browser where it originally started to like, it's the same thing. But you'll find out very quickly that that's five megs of code, if you tried to bundle it.
>> Sean Larkin: And, the syntax is really awkward.
[00:10:12]
It's non-standard, not even node, nor the browser supports it. So it's not even a real module system.
Learn Straight from the Experts Who Shape the Modern Web
- In-depth Courses
- Industry Leading Experts
- Learning Paths
- Live Interactive Workshops