# ES6 Modules
Separate from the _module pattern_, "modules" provide a standardized way to organize and share JavaScript code across multiple files. They address issues with global scope and dependency management in earlier versions of JavaScript.
ES6 Modules are the standard for modern JavaScript, especially new projects.
ES6 Modules rendered the module pattern (Immediately Invoked Function Expressions) unnecessary.
###### Key benefits
- Improved code organization, reuse, and maintainability.
- Split code into smaller, focused files.
- Explicit dependencies (via imports/exports) and encapsulation, reducing global namespace pollution.
- Enhanced performance and optimization.
- Enables static analysis for tree shaking.
- Supports async loading and browser optimizations.
###### Key features
- File-based: Each file is treated as a separate module.
- Strict mode: Modules automatically use strict mode, enforcing better coding practices.
- Export and import: Use `export` to make functions, objects or primitives available to others modules, and use `import` to use them in another module.
###### Named Exports
There are two ways to use exports: named exports and default exports.
Named exports allow you to export multiple values from a module. The imported name must match the exported name, unless renamed using 'as'.
```javascript
// mathUtils.js
export const PI = 3.14159;
export function calculateCircleArea(radius) {
return PI * radius * radius;
}
// Or, at the end of the file:
// export { PI, calculateCircleArea };
```
```javascript
// geometryHelpers.js
import { PI, calculateCircleArea } from './mathUtils.js';
```
###### Default Exports
```javascript
// UserProfile.js
export default class UserProfile {
// ...
getDisplayName() { return this.name.split(' ')[0]; }
}
```
```javascript
// Or, at the end of the file:
export default UserProfile;
```
```javascript
// Import in app.js
import UserProfile from './UserProfile.js'
```
# History and context
- Early JS, designed primarily for simple web page interactions, lacked a module system. All scripts shared the global scope, leading to poor organization and naming conflicts.
- In the 2000s, developers used module patterns to create private scopes and hence simulate modules: Immediately Invoked Function Expressions (IIFE), the revealing module pattern, and namespace pattern.
- In 2009, CommonJS was introduced for server-side JS development (Node.js), introducing:
- `require()` function for importing and `module.exports` to export.
- Starting around 2010, JS package managers emerged to automate the process of using libraries from a central repository. Node Package Manager (npm) won out, with yarn having considerable adoption as well.
- As applications grew larger, bundlers like Webpack (2012) became necessary. These tools take all your JS files, their dependencies, and package them efficiently for the browser. (Single file.)
- This allowed developers to use CommonJS-style modules in the browser.
- Most languages provide a way to import code from one file into another. JS wasn't originally designed with this feature, because it was only to run in the browser, with no access to the file system.
- ES6 modules were introduced as part of the ECMAScript 2015 spec, aiming to provide a standardizes, easy-to-use module system.
- This introduced `import` and `export` statements, providing clean syntax for working with modules.
- Javascript files are not automatically ES6 modules. However, many modern build tools and frameworks (like Create React App, Vue CLI, etc.) are configured to treat .js files as modules by default.
>So this is modern JavaScript in a nutshell. We went from plain HTML and JS to using **a package manager** to automatically download 3rd party packages, **a module bundler** to create a single script file, a **transpiler** to use future JavaScript features, and **a task runner** to automate different parts of the build process.
Source: [History lesson on JS package managers and bundling](https://peterxjang.com/blog/modern-javascript-explained-for-dinosaurs.html)
# Bundlers
A bundler is a dev tool that processes and transforms your code and its dependencies, combining many JavaScript files into a single file (or a few) that is production-ready for the browser.
Webpack is the most popular bundler.
What bundlers do:
- Organization: combine multiple files into one (or a few) file(s).
- Compatibility: convert modern JS code for broader browser compatibility.
- Performance: optimize, minify and split up your code to make it load faster.
- Dependency management: makes sure everything plays nice together.
In the pre-bundler era, you might have constructed these functions in separate JS files:
```html
<head>
<script src="https://unpkg.com/@popperjs/popper.min.js"></script>
<script type='text/javascript' src='tinycolor.js'></script>
<script type='text/javascript' src='/nav.js'></script>
// More scripts as necessary...
</head>
```
Using a bundler will merge all these files and their dependencies into a single file:
```html
<head>
<script type='text/javascript' src='/bundle.js'></script>
</head>
```
Source: [The Complete JavaScript Module Bundlers Guide](https://snipcart.com/blog/javascript-module-bundler)
# CommonJS
- CommonJS is another module format used by Node.js by default and unavailable in the browser.
- Node.js is evolving to support ES6 modules. However, CommonJS modules still exist for legacy reasons. Making it important to understand both.
- Uses the `require()` syntax, which is simply a function call at runtime.
- This entails synchronous loading— execution waits until the module is fully loaded & executed.
```javascript
// Export from commonJsModule.js
const message = "Hello, CommonJS";
module.exports = message;
```
```javascript
// Import into app.js
const message = require('./module1');
```
# Webpack
Webpack is a powerful bundler for JavaScript modules.
- Webpack also helps with asset management, like images.
- Prior to webpack, front-end devs would use tools like grunt and gulp to process assets and move them from their `/src` folder into their `/dist` or `/build` directory.
- Webpack can include _any type of file_, besides JS, for which there is a loader or built-in Asset Modules support.
- For example, you can load CSS, images, fonts, etc.
- Webpack uses "loaders" to interpret and process these files, optimizing them and making them usable in your JavaScript.
- HtmlWebpackPlugin can be used to automatically build HTML files, like `index.html`, in `/dist`.
- Use source maps to aid in debugging the original code, instead of the generated code.
Source: [Webpack documentation](https://webpack.js.org/guides/)