| marp | true |
|---|---|
| theme | default |
| paginate | true |
| backgroundColor | |
| backgroundImage | url('https://marp.app/assets/hero-background.svg') |
Play around with different module systems by generating JavaScript output with:
- CommonJS modules (
npm run build:main) - UMD modules (
npm run build:umd) - AMD modules (
npm run build:amd) - ES6 modules (
npm run build:esm)
Start the dev server using npm run start and look at
index-esm.html(browser native ES6 modules)index-amd.html(AMD modules with RequireJS loaded into browser)index-webpack.html(Webpack bundled build à la Angular)
https://www.zachgollwitzer.com/posts/scripts-commonjs-umd-amd-es6-modules
-
Initially
<script>tags only- Everything is global
- Name clashes when libraries use the same identifiers
-
CommonJS (CJS) (2009)
exportsobject andrequire()function- came with Node.js
require()is synchronous and thus not suitable for browsers
-
AMD (Asynchronous module definition) and RequireJS (2009)
define()function -
UMD (universal module definition) pattern (2015)
-
ECMAScript modules (esm) since ES6/ECMAScript 2015
-
Bundlers like Webpack (2012)
https://developer.mozilla.org/en-US/docs/Web/JavaScript/Guide/Modules
-
JavaScript file that contains an
importorexportstatement is considered a module -
exports define the public interface of the module -
importis used to import other modules -
importas static statement vs.importoperator (function that returns a promise with the Module namespace object used for dynamic module loading) -
"Equivalent" to Typescript modules
-
ES6 modules are natively supported in modern browsers (https://caniuse.com/es6-module)
-
Use an
importmapto map module names to files -
importwithout.jssuffix does not work withoutimportmap(see example) (and Typescript doesn't add.jssuffix to generated JavaScript files...)
-
There is a mismatch between CommonJS module
exportsand ES6export(most of the libraries on https://www.npmjs.com/ are distributed as UMD modules with CommonJS support) -
CommonJS can export anything from a module (e.g. lodash exports a
functionthat also serves as an object with properties) -
ES6 modules always export a Module namespace object with properties for every exported "member"
-
Default export (
export default smiley) is available as propertydefaulton Module namespace object -
import smiley from 'module-demo/smiley'is syntactic sugar forimport { default as smiley } from ''module-demo/smiley'
lodash.d.ts:export = _(Typescript special syntax for CommonJS style exports)
Three possibilities:
-
import * as lodash from 'lodash'makes Typescript compile happily- When used in a native ES6 module environment however, the
lodashobject is a Module NS object which is not callable (see demo)
- When used in a native ES6 module environment however, the
-
@ts-ignore import lodash from 'lodash'- works, too! (because we know the esm version of the library
lodash-esindeed does a default export) - however this does not work for
module: umd,module: commonjsetc. (_.chain(...)is "transpiled" tolodash_1.default.chain(...))
- works, too! (because we know the esm version of the library
-
import lodash from 'lodash'withesModuleInteropset totrue- works in both ES6 and UMD environments (see demo) because of helper function
__importDefault
- works in both ES6 and UMD environments (see demo) because of helper function
- for me the best option is to use (1) if the imported module needs not to be called or (3) otherwise
Webpack is a wide-spread bundler and used by Angular CLI internally.
It bundles all modules into a single bundle.js.
This is well explained in here.
TL;DL: All modules are packed into one big map keyed by module name.
__webpack_require__(...) is then just a lookup into the map.
I've not yet looked into the options of different output module formats of Webpack or dynamic module loading with Webpack.
Slides created using: https://marp.app/
Used typescript starter project: https://github.com/bitjson/typescript-starter
History of JavaScript modules: https://www.zachgollwitzer.com/posts/scripts-commonjs-umd-amd-es6-modules
Explanation of "modern" ECMAScript Modules (esm): https://developer.mozilla.org/en-US/docs/Web/JavaScript/Guide/Modules
Typescript docs on modules: https://www.typescriptlang.org/docs/handbook/modules.html
Explanation of bundlers: https://lihautan.com/what-is-module-bundler-and-how-does-it-work/