ES6 browser support now means you can use the simpler JavaScript module syntax (export
and import
) natively in most modern browsers. Unless you're still writing for IE9, this is the way to go.
This simplifies things and is all you need to break down your JavaScript code into re-usable modules for small-medium-sized projects.
"The goal for ECMAScript 6 modules was to create a format that both users of CommonJS and of AMD are happy with" —Exploring JS
When searching JavaScript modules on the web, you'll come across (often older pre-ES6 module) examples using AMD and CommonJS syntax (originating from the JavaScript front-end library Dojo and the JavaScript server environment node) both created to implement JS modules before widespread support:
- AMD: Asynchronous Module Definition, asynchronous, targeted at browser environments (from Dojo)
- CommonJS or CJS: CommonJS Modules, synchronous, targeted at server-side environments (e.g. node)
AMD and CommonJS code examples use exports
(with an s), define()
and require()
(to mangle both into one non-ES6 thing). ES6 module syntax now does the job.
What no-one mentions, either because they've been using node since before the dinosaurs, or they're just so js they can't possibly imagine anyone not actually knowing this stuff:
- the HTML script tag for the main JavaScript file (from which any module files are imported) needs a
type="module"
attribute e.g.<script type="module" src="main.js"></script>
. - in your HTML, you only need a single
script
tag with the "module" attribute for your main JavaScript file, from which you can import module files. - Same-origin policy applies, so can't run from a file system (e.g. dragging your HTML file to the browser). Start a local server from the command-line in the folder containing the HTML file - use node
http-server
or another static server command for a popular language listed below. - MDN covers ES6 modules very well under
import
andexport
, but ignore finds on MDN for JavaScript code modules, these are Firefox-specific "JavaScript code modules", not JavaScript ES6 modules. Confusing, eh? - you must
import
modules before an IFFE, and they're "use strict" by default, so no need to declare it explicitly in the module
- improve links to local servers
- add link to CodeCademy JS Module tutorial
- insert results from calling modules into the HTML instead of just showing in the console
- use the example to explain (asynchronous/synchronous) AMD and CommonJS (
define()
,require()
,exports
) and ES6 (export
/import
)
the Require module system isn't standard based. It's is highly unlikely to become standard now that ES6 modules exist.
ES6 modules will basically make UMD (Universal Module Definition) obsolete - essentially removes the schism between CommonJS and AMD (server vs browser).
—Using Node.js require vs. ES6 import/export
If you’re a newcomer to JavaScript, jargon like “module bundlers vs. module loaders,” “Webpack vs. Browserify” and “AMD vs. CommonJS” can quickly become overwhelming.
Good authors divide their books into chapters and sections; good programmers divide their programs into modules.
—JavaScript Modules: A Beginner’s Guide
- the primary references:
- Other useful sources:
- history lessons (only if you really need them):
- AMD versus CJS. What’s the best format? (2011)
- why modules? Addy Osmani Writing Modular JavaScript With AMD, CommonJS & ES Harmony (2012) (the old name for ES6)
- AngularJS and Browserify developers discussing AMD vs CommonJS
- Big list of static server one-liners
- Shortlist/quick reference:
- node (install globally with
npm install http-server -g
and run from your project directory withhttp-server
on the command-line to view on http://localhost:8080) - Python
python -m SimpleHTTPServer
Python3python -m http.server
(default port 8000) - Ruby
ruby -run -e httpd . -p 8000
- PHP
php -S localhost:8000
- node (install globally with