-
Notifications
You must be signed in to change notification settings - Fork 17
Javascript Development Concept
The AsTeRICS Grid uses the following stack of tools and libraries for Javascript development:
- npm --> node.js package manager, see https://nodejs.org and https://www.npmjs.com/
- webpack --> tool for packing all javascript modules (in our case ES6 modules) to a single file (e.g. https://github.com/asterics/AsTeRICS-Grid/blob/master/package/static/build/asterics-grid.bundle.js), see https://webpack.js.org/
- babel --> for transpiling new (ES6) javascript to older one (ES5), see https://babeljs.io/
- core-js --> a library providing polyfills, see https://github.com/zloirock/core-js
If someone wants to use a certain feature of javascript he/she should follow this flowchart to make a decision if/how to use it:
The concept for supporting ES5 while run native ES6 Javascript on modern browsers comes from this article: https://philipwalton.com/articles/deploying-es2015-code-in-production-today/
Generally the AsTeRICS Grid can run in two different modes on the client:
- Normal mode: Runs on a modern browser that supports ES6
- Legacy mode: Runs on older browsers which do not support ES6 (or more detailed: do not support ES6 modules)
The distinction between these modes is done by the type=module
and nomodule
attributes on the <script>
tags:
- Scripts for normal mode are included like this:
<script type="module" src="build/asterics-grid.bundle.js"></script>
- Scripts for legacy mode are included like this:
<script nomodule src="build_legacy/asterics-grid.bundle.js"></script>
- For scripts that should be used in both, normal and legacy mode, a normal script tag without additional attributes is used like this:
<script src="polyfill/web-animations.min.js"></script>
That means that modern browsers (supporting ES6 modules) are using the script with type=module
and older ones the script with nomodule
.
In the folder https://github.com/asterics/AsTeRICS-Grid/tree/master/src there are the javascript source files that are using the ES6 module system for dependencies (import
and export
statements). They are bundled using webpack to the file asterics-grid.bundle.js
, which has two reasons:
- bundling replaces the ES6 module system (
import
/export
) with some webpack-stuff which is ES5 compatible and therefore makes the ES6 modules compatible with older browsers. - Only one file has to be included and loaded within the html-file which can have advantages in performance.
webpack
itself is a npm module (see https://www.npmjs.com/package/webpack) and therefore is included in the npm configuration file package.json
(see https://github.com/asterics/AsTeRICS-Grid/blob/master/package.json#L16).
The bundling of webpack can be started using the command
npm start build
This command bundles everything from the src
folder to the folders package/static/build
and package/static/build_legacy
in the files asterics-grid.bundle.js
which is included in the html file (see https://github.com/asterics/AsTeRICS-Grid/blob/master/package/static/index.html#L46).
The folder build
contains the bundle asterics-grid.bundle.js
which includes all the modules in a single file, but with unchanged syntax. So all ES6 syntax like arrow functions (e.g. a => a*a
) will stay exaclty the same. However everything written in ES5 syntax (e.g. function(a) {return a*a}
) also won't change and stay in this syntax.
The folder build_legacy
also contains a bundle asterics-grid.bundle.js
, but an transpiled version where all ES6 syntax like arrow functions are replaced by the ES5 equivalent. So any function like a => a*a
in this file will be changed to function(a) {return a*a}
.
Transpiling for the bundle in build_legacy
is done using babel. The webpack plugin babel-loader
is used, which can be seen in the webpack.config.js, https://github.com/asterics/AsTeRICS-Grid/blob/master/webpack.config.js#L53:
options: {
presets: [
['env', {
modules: false,
useBuiltIns: true,
targets: {
browsers: [
'> 1%',
'last 2 versions',
'Firefox ESR'
],
},
}],
],
}
The configuration in the browsers
field contains queries to select browsers to transpile the javascript for. See https://github.com/browserslist/browserslist#full-list for valid queries. So in our case the configuration means that babel transpiles the code to be compatible with all browsers that have more than 1% usage, are within the last 2 versions or are a Firefox ESR version. At some day in the future, if these browsers all support ES6 this means, that babel will not transpile ES6 to ES5 anymore but will keep the ES6 syntax.
Babel also could provide polyfills for missing functionalities in older browsers like e.g. Promise
. However we decided to not use babel for this issue, because we don't want to load Polyfills on modern browsers and this is currently not possible using babel. Therefore core-js
is used, a set of Polyfills, that is also used by babel in the background. core-js
is included with this line, see https://github.com/asterics/AsTeRICS-Grid/blob/master/package/static/index.html#L13:
<script nomodule src="polyfill/core_js_shim.min.js"></script>
Using the nomodule
attribute means that this file is only loaded if the browser does not support ES6 modules (and therefore in lecacy mode). See https://github.com/zloirock/core-js#features for documentation of the polyfills provided by core-js
.
The described solution sums up in:
- New browsers which support ES6 modules use the
package/static/build/asterics-grid.bundle.js
file and therefore run all code written insrc
(also ES6 code) native. - Older browsers which do not support ES6 modules use the transpiled
package/static/build_legacy/asterics-grid.bundle.js
file and polyfills ofcore-js
. This should lead to support of nearly all browsers.
See https://caniuse.com/#feat=es6-module to get an idea which browsers will run (1) and which (2).