Universe Ecmascript
About
This package lets you use new JavaScript language features that are part of the ECMAScript 2015 specification (including importing modules) but are not yet supported by all engines or browsers. Unsupported syntax is automatically translated into standard JavaScript that behaves the same way.
This video from the July 2015 Meteor Devshop gives an overview of how the package works, and what it provides.
Modules:
You can use modules in plain *.js
ans *.jsx
files, there is no need for *.import.js(x)
extension anymore.
But modules from *.js
, *.jsx
will be auto loaded in first moment when all dependencies are loaded.
It mean that:
- If no imports and no exports was specified in file, this file will be loaded as was a before ( without module definition )
- If no dependencies (none import) but if there is at least one export in file, the file will immediately will be loaded and it will set as a module without registering.
- If all dependencies are loaded it will be immediately loaded without registering
- If not all dependencies are loaded, your module will be registered and imported when all dependencies will loaded.
For more info see original universe:modules docs
Installation
To use modules in your Meteor app you need to
meteor add universe:ecmascript
This package register compilers on js
and jsx
extension and because of that it will not work with ecmascript
and jsx
core packages installed at the same time.
You may need to remove them from you app.
ecmascript
is installed in all newly created apps by default and you can remove it with
meteor remove ecmascript
Our package give the same set of functionalities + modules support so it is completely safe to remove it.
Removing jsx
can be more tricky as it could be implied by react
"umbrella" package.
If your using react
package then you need to remove it and add other dependencies back:
meteor remove react jsx meteor add react-meteor-data //if you use it
TL;DR
Full install script for react apps:
meteor remove ecmascript react meteor add react-runtime react-meteor-data universe:ecmascript
Safari and FlowRouter issue
There is one common issue with FlowRouter and Safari. You need to tell FlowRouter to wait for routes to load, otherwise it may not load correctly.
You can do it like this:
if (Meteor.isClient) { FlowRouter.wait(); } System.import('/routesOrSomethingElse').then(() => { if (Meteor.isClient) { FlowRouter.initialize(); } });
Supported ES2015 Features
Syntax
The ecmascript
package uses Babel to compile
ES2015 syntax to ES5 syntax. Many but not all ES2015 features can be
simulated by Babel, and ecmascript
enables most of the features
supported by Babel.
Here is a list of the Babel transformers that are currently enabled:
es6.modules
Language-level support for modules for component definition:
- lib/math.js
1// lib/math.js 2export function sum(x, y) { 3return x + y; 4} 5export var pi = 3.141593;
- app.js
1// app.js 2import * as math from "lib/math"; 3alert("2π = " + math.sum(math.pi, math.pi));
Makes it safe to use reserved keywords like catch
as unquoted keys in
object literals. For example, { catch: 123 }
is translated to { "catch": 123 }
.
Makes it safe to use reserved keywords as property names. For
example, object.catch
is translated to object["catch"]
.
Provides a shorthand for function expressions. For example,
[1, 2, 3].map(x => x + 1)
evaluates to [2, 3, 4]
. If this
is used
in the body of the arrow function, it will be automatically bound to the
value of this
in the enclosing scope.
Adds support for binary and octal numeric literals. For example,
0b111110111 === 503
and 0o767 === 503
.
Enables multi-line strings delimited by backticks instead of quotation marks, with variable interpolation:
1var name = "Ben"; 2var message = `My name is: 3${name}`;
Enables class
syntax:
1class Base { 2constructor(a, b) { 3 this.value = a * b; 4} 5} 6 7class Derived extends Base { 8constructor(a, b) { 9 super(a + 1, b + 1); 10} 11} 12 13var d = new Derived(2, 3); 14d.value; // 12
Allows defining block-scoped variables that are not allowed to be redefined:
1const GOLDEN_RATIO = (1 + Math.sqrt(5)) / 2; 2 3// This reassignment will be forbidden by the compiler: 4GOLDEN_RATIO = "new value";
Enables the let
and const
keywords as alternatives to var
. The key
difference is that variables defined using let
or const
are
visible only within the block where they are declared, rather than being
visible anywhere in the enclosing function. For example:
1function example(condition) { 2let x = 0; 3if (condition) { 4let x = 1; 5console.log(x); 6} else { 7console.log(x); 8x = 2; 9} 10return x; 11} 12 13example(true); // logs 1, returns 0 14example(false); // logs 0, returns 2
Allows omitting the value of an object literal property when the desired
value is held by a variable that has the same name as the property
key. For example, instead of writing { x: x, y: y, z: "asdf" }
you can
just write { x, y, z: "asdf" }
. Methods can also be written without
the : function
property syntax:
1var obj = { 2oldWay: function (a, b) { ... }, 3newWay(a, b) { ... } 4};
Default expressions for function parameters, evaluated whenever the parameter
is undefined
, ...rest
parameters for capturing remaining
arguments without using the arguments
object:
1function add(a = 0, ...rest) { 2rest.forEach(n => a += n); 3return a; 4} 5 6add(); // 0 7add(1, 2, 3); // 6
Allows an array of arguments to be interpolated into a list of arguments
to a function call, new
expression, or array literal, without using
Function.prototype.apply
:
1add(1, ...[2, 3, 4], 5); // 15 2new Node("name", ...children); 3[1, ...[2, 3, 4], 5]; // [1, 2, 3, 4, 5]
Provides an easy way to iterate over the elements of a collection:
1let sum = 0; 2for (var x of [1, 2, 3]) { 3sum += x; 4} 5x; // 6
Destructuring is the technique of using an array or object pattern on the left-hand side of an assignment or declaration, in place of the usual variable or parameter, so that certain sub-properties of the value on the right-hand side will be bound to identifiers that appear within the pattern. Perhaps the simplest example is swapping two variables without using a temporary variable:
1[a, b] = [b, a];
Extracting a specific property from an object:
1let { username: name } = user; 2// is equivalent to 3let name = user.username;
Instead of taking a single opaque options
parameter, a function can
use an object destructuring pattern to name the expected options:
1function run({ command, args, callback }) { ... } 2 3run({ 4command: "git", 5args: ["status", "."], 6callback(error, status) { ... }, 7unused: "whatever" 8});
Supports catch-all ...rest
properties in object literal declarations
and assignments:
1let { x, y, ...rest } = { x: 1, y: 2, a: 3, b: 4 }; 2x; // 1 3y; // 2 4rest; // { a: 3, b: 4 }
Also enables ...spread
properties in object literal expressions:
1let n = { x, y, ...rest }; 2n; // { x: 1, y: 2, a: 3, b: 4 }
Allows the final parameter of a function to be followed by a comma,
provided that parameter is not a ...rest
parameter.
Permits the use of Flow type annotations. These
annotations are simply stripped from the code, so they have no effect on
the code's behavior, but you can run the flow
tool over your code to
check the types if desired.
Polyfills
The ECMAScript 2015 standard library has grown to include new APIs and
data structures, some of which can be implemented ("polyfilled") using
JavaScript that runs in all engines and browsers today. Here are three new
constructors that are guaranteed to be available when the ecmascript
package is installed:
A Promise
allows its owner to wait for a value that might not be
available yet. See this tutorial for more
details about the API and motivation. The Meteor Promise
implementation is especially useful because it runs all callback
functions in recycled Fiber
s, so you can use any Meteor API, including
those that yield (e.g. HTTP.get
, Meteor.call
, or MongoCollection
),
and you never have to call Meteor.bindEnvironment
.
An associative key-value data structure where the keys can be any JavaScript value (not just strings). Lookup and insertion take constant time.
A collection of unique JavaScript values of any type. Lookup and insertion take constant time.
An implementation of the global
Symbol
s namespace
that enables a number of other ES2015 features, such as for
-of
loops
and Symbol.iterator
methods: [1,2,3][Symbol.iterator]()
.
- Polyfills for the following
Object
-related methods: Object.assign
Object.is
Object.setPrototypeOf
Object.prototype.toString
(fixes@@toStringTag
support)
Complete reference here.
- Polyfills for the following
String
-related methods: String.fromCodePoint
String.raw
String.prototype.includes
String.prototype.startsWith
String.prototype.endsWith
String.prototype.repeat
String.prototype.codePointAt
String.prototype.trim
Complete reference here.
- Polyfills for the following
Array
-related methods: Array.from
Array.of
Array.prototype.copyWithin
Array.prototype.fill
Array.prototype.find
Array.prototype.findIndex
Complete reference here.
- Polyfills for the following
Function
-related properties: Function.prototype.name
(fixes IE9+)Function.prototype[Symbol.hasInstance]
(fixes IE9+)
Complete reference here.