This document discusses module bundling tools for JavaScript applications. It introduces the problems of growing code complexity and need for optimized delivery of code. It then summarizes two popular module bundling tools: Webpack and jspm. Webpack supports CommonJS, AMD and ES6 module syntax and uses loaders and plugins to bundle assets. jspm uses the SystemJS module loader and bundles modules for production, while loading them asynchronously for development. Both tools aim to address the challenges of modular code management and optimized delivery.
4. The Problem
• Web sites are turning into Web apps
• Code complexity grows as the site gets bigger
• Developers prefer discrete JS files/modules
• Deployment requires optimized code in just one
or a few HTTP calls
• No standardized import functionality (until now)
8. True App Modularization
• Code is split up into different modules.
• Dependency graph
• The loading order is irrelevant.
• Code gets executed if all dependencies are
loaded.
• Dependencies can be mocked.
9. App delivery
• Requests are expensive.
• Deliver as few files as possible.
• Deliver the «above the fold» data first.
• Deliver only code that is needed by the client.
11. Assets Versioning
• Adds its hash value to the file name
• Allows for setting long expiration headers
• Requires the HTML to update as well.
• Supported by most popular backends
/static/dist/main-ebf5ec7176585199eb0a.js
28. jspm / SystemJS
• Package manager (jspm) and module loader
(SystemJS)
• For development: load modules synchronously
• For production: create a bundle
• Support for SPDY (via its own CDN) and possibly
HTTP2
29. jspm / SystemJS
• In active development
• Uses npm and Github as registries
• A CSS loading plugin is available
• Development != Production environment
This is an actual portrait of me, drawn by the very talented Tika.
From Require.js
Real Website example: 45 Scripts
Server side Bundler
No explicit dependencies in the scripts. Bundler does not value dependencies.
Order of the scripts is important
Global Object, provides a namespace.
Everything goes into that object.
Closure
Does not pollute global namespace.
Dependency on global objects.
Unit testing is difficult
Modules define their dependencies.
Module loaders build a dependency graph and package the modules accordingly.
Dependency Injection.
Modularization competes with delivery over HTTP (1).
Think about how you package your assets.
The app should deliver several static files:
A common-chunks.js file with all the code that is shared over multiple pages. So it can be cached by the browser.
A Js file with code specific for the current app.
Code for sections wich are rarely used or needs a big library should be split out into a separate module which is loaded asynchronously on-demand.
e.g. Webpack exports a JSON with the asset targets and file names. Django has a library called django-webpack-loader that reads that JSON and adds the data into the HTML template. It also waits for Webpack to complete building if necessary.
CommonJS: Introduced with Node.js. Designed for synchronous loading. (Browserify)
Problem: It doesn’t work in the browser.
Asynchronous Module Definition (AMD): Designed for asynchronous loading.
Runs a callback when ready. A bit like $(function(){});
Require.js, Angular.js
UMD: Universal Module Definition (for libraries)
CommonJS: Designed for synchronous loading. (Browserify)
Asynchronous Module Definition (AMD): Designed for asynchronous loading. Require.js, Angular.js
UMD: Universal Module Definition (for libraries)
Currently 3 popular bundlers. JSPM is very new.
With plugins
Survey in August 2015.
Half the people are using a module bundler.
Ashley Nolan
http://ashleynolan.co.uk/blog/frontend-tooling-survey-2015-results
By Tobias Koppers.
This is a free-time project.
MIT license
Compared to Browserify it can split the code into multiple modules.
Component structure: CSS and Image are also part of a component and can therefore be included.
CSS load order is not guaranteed if CSS is embedded in the Javascript files.
You can extract the CSS into its own file.
The configuration is a Javascript object.
Because it is a CommonJS module, configurations can be extended by other modules.
E.g. a production config can just import the default configuration and overwrite the necessary properties.
Assets are loaded using a loader. The test property is a regex that is applied to all the files in a directory.
Loaders can be chained and passed attributes.
The first loader tests for js and jsx files and uses babel to parse ES6 code.
SCSS and LESS loaders can work in the same project. (3rd party library used less).
URL loader copies the files if they are less than 20kB. Otherwise it embeds them. Copied files can be given a hash-name.
Automatically creates separate bundles for parts of the app that are only needed on demand.
Here the FilmApp is a large React application that is only loaded if an element with the ID 'film-gallery' is present in the DOM.
Webpack Dev server stores files in memory.
You have to chose between live reload and source maps.
Web inspector only shows source maps for css if the source file is a CSS file.
Bower can be used, but it is not necessary.
No Gulp required. (Gulp can be used but makes the builds slower.)
NPM is the default package manager (and task runner)
Have a separate config file for production builds.
Replace destination paths, add ugilfyJS
NODE_ENV environment variable is used by React to remove debugging statements.
jspm is a package manager for the SystemJS universal module loader, built on top of the dynamic ES6 module loader
SystemJS is a Polyfill for the System specification
There is no Javascript watch and compiling tasks in development.
jspm Version 0.16.0 was released on 18. August.
jspm Version 0.16.6 was released on 19. September.
7 Releases in one Month.
SystemJS: 6 releases in the last two weeks.
Sass loader plugin is still in alpha stage.