When did javascript go from <script src="..."> to require("...")?
the ever-changing javascript ecosystem
As JavaScript has evolved over the years, so too have the ways in which developers import external libraries and manage dependencies in their projects. In this blog post, we'll explore the journey of JavaScript module systems from the humble beginnings of script tags to the modern import methods we use today.
The Beginning: Script Tags
In the early days of JavaScript, developers primarily relied on script tags to include external libraries in their projects. A script tag was used to reference an external JavaScript file using the src
attribute, and the browser would download and execute the code from the specified file.
html
<script src="path/to/your/library.js"></script>
While this method was straightforward and easy to understand, it had several drawbacks:
Global scope pollution: All variables and functions in the imported libraries were added to the global scope, potentially leading to naming conflicts and making it difficult to manage large projects.
Dependency management: Managing dependencies between multiple libraries was cumbersome, as the order of script tags mattered. Developers had to ensure that a library's dependencies were loaded before the library itself.
No clear module boundaries: Functions and variables from different JavaScript files could easily overwrite one another, making it challenging to maintain and reason about the codebase.
Enter CommonJS and Require
To address these issues, the CommonJS module system was introduced. CommonJS, originally developed for the server-side JavaScript runtime Node.js, used the require()
function to import libraries and module.exports
to export functionalities. This allowed developers to encapsulate code into separate modules and manage dependencies more effectively.
javascript
// Import a library
const myLibrary = require('my-library');
// Export a function
module.exports.myFunction = function() {
// ...
};
CommonJS significantly improved dependency management and reduced global scope pollution. However, it still had some limitations, especially in the browser environment:
Synchronous loading: The
require()
function loaded modules synchronously, which could lead to performance issues, particularly in the browser, where downloading and executing scripts could block the rendering of the page.Lack of native browser support: Browsers did not support the CommonJS module system out of the box. Bundling tools like Browserify and Webpack were required to make CommonJS modules compatible with browser environments.
The Rise of ES Modules
To address the limitations of CommonJS and provide a native module system for JavaScript, ECMAScript 2015 (ES6) introduced the ES Module (ESM) system. ES Modules use the import
and export
keywords to handle dependencies and create modular code.
javascript
// Import a library
import myLibrary from 'my-library';
// Export a function
export function myFunction() {
// ...
}
ES Modules offer several advantages over CommonJS:
Native browser support: Modern browsers natively support ES Modules, eliminating the need for bundling tools in many cases.
Asynchronous loading: ES Modules are loaded asynchronously by default, improving performance and avoiding the blocking issues associated with synchronous loading.
Static imports: The
import
andexport
syntax allows for better static analysis, enabling features like tree shaking and more efficient bundling.
The Future of JavaScript Imports
While ES Modules have become the standard for modern JavaScript development, other module systems like CommonJS still have their place, particularly in server-side applications using Node.js.
With the increasing adoption of ES Modules, developers can expect better tooling and support for managing dependencies and creating modular JavaScript applications. Additionally, the JavaScript community continues to innovate and explore new ways to further improve the import process, such as dynamic imports and top-level await.
In conclusion, the evolution of JavaScript module systems has come a long way from the simple script tags of the past. Today, developers have a powerful and flexible set of tools to create modular and maintainable JavaScript applications, both in the browser and on the server.
Some further reading:
https://creative-coding.decontextualize.com/external-libraries/
https://developer.mozilla.org/en-US/docs/Web/JavaScript/G
uide/Modules