es2018 vs es2018.promise vs es2018.regexp - javascript

TypeScript compiler has the following options for the --lib cmd line arg:
ES2018
ES2018.Promise
ES2018.RegExp
What is the difference between them? Should I use ES2018 or ES2018.Promise if I need Promisefinally() support only and do NOT care about other ES2018 features?
Also, since what TS version those ES2018 libs are supported? When I try to use them with TS 2.6.2, it throws:
Error: tsconfig.json(16,13): error TS6046: Argument for '--lib' option
must be: 'es5', 'es6', 'es2015', 'es7', 'es2016', 'es2017', 'esnext',
'dom', 'dom.iterable', 'webworker', 'scripthost', 'es2015.core',
'es2015.collection', 'es2015.generator', 'es2015.iterable',
'es2015.promise', 'es2015.proxy', 'es2015.reflect', 'es2015.symbol',
'es2015.symbol.wellknown', 'es2016.array.include', 'es2017.object',
'es2017.sharedmemory', 'es2017.string', 'es2017.intl',
'esnext.asynciterable'.

The lib option only provide typing for these libraries. If you specify ES2018 than you will get ES2018 typing even if you target for ES2015. By default, TypeScript sets some libs depending on which target you specify but it allows you since version 2.0 to manually add more typing.
What is the difference between them?
They are a subset of different families of features.
Should I use ES2018 or ES2018.Promise if I need Promisefinally()
support only and do NOT care about other ES2018 features?
Yes, you are can scope to what you need. However, it won't increase your generated JavaScript if you include more.
Since what TS version those ES2018 libs are supported?
If you are using a target that does not support a feature natively, you may download (npm) a package to Polyfill. It's not related directly to a TS version.

Related

Enable destructuring objects rest properties with Babel?

I noticed that Babel wasn't transforming this:
function({ param, ...rest }) {}
This syntax is already supported in the latest popular browsers. However, according to Mozilla (https://developer.mozilla.org/en-US/docs/Web/JavaScript/Reference/Operators/Destructuring_assignment), it's not supported in browsers as new as Edge 79 (released this year).
I tried manually enabling some Babel plugins, but it didn't work:
#babel/plugin-transform-destructuring
#babel/plugin-proposal-object-rest-spread
#babel/plugin-syntax-object-rest-spread
#babel/plugin-transform-parameters
Is it possible to transform this syntax with Babel? I need to do testing in older browsers, but I'm getting SyntaxError: invalid property id because of this.
Sometimes babel needs to combine more than one plugins to transform something. In this case I think you would need to combine at least 2 plugins:
#babel/plugin-transform-destructuring
#babel/plugin-transform-parameters
npx babel /path/to/yourFile plugins=#babel/plugin-transform-destructuring,#babel/plugin-transform-parameters
To make life easier, I would suggest to use preset-env instead which supports official ES changes (since it includes all official plugins for you):
npx babel /path/to/yourFile presets=#babel/preset-env

Using async/await in Node 6 with Babel

I'm trying to configure Babel for Node v6.9.2. I want to use async/await constructs.
Because I'm new to Babel and all Node infrastructure, I confused how to configure it properly:
What preset should I use? Node is already implemented most of the ES6 features. So I don't want Babel to transpile features already supported by Node 6.9.x (arrow functions, new import mechanism etc) for performance reasons.
What plugins should I include so I can use async/await? There I also confused, because after some researching I found several plugins: syntax-async-functions, transform-async-to-generator and some more.
Example of .babelrc will help.
Thanks
What preset should I use?
You don't need to use any preset. Presets are just a collection of plugins which makes it easier to use if you want to transpile a set of features (for instance all ES2015 with preset-es2015). But when you want to transpile only a selection of these features, you only include the corresponding plugins.
What plugins should I include so I can use async/await?
Because Node 6 supports generators, you can use transform-async-to-generator with the following .babelrc:
{
"plugins": ["transform-async-to-generator"]
}
And of course you would need to add plugins if you need to transpile more unsupported features.
Alternative babel-preset-env
babel-preset-env automatically determines what plugins you need for the specified environment. This will not include any plugins that are not necessary. To specify your current Node version you would use this .babelrc:
{
"presets": [
["env", {
"targets": {
"node": "current"
}
}]
]
}
Short answer
Use Babel preset for Node 6.x:
https://www.npmjs.com/package/babel-preset-node6
Long answer
To see what ES feature is supported in a given Node version, see:
http://node.green/
For async/await support in particular, see:
http://node.green/#ES2017-features-async-functions
If you use Node v7.x (the current version) then you can use the --harmony flag and use async/await natively without transpilation.
Node v8.x (available as nightly builds) doesn't even need the --harmony flag for that.
But note that Node doesn't support import/export - to know why see:
javascript - Why is there a spec for sync and async modules?
Exporting Node module from promise result

standard babel presets requirements

In order to setup webpack + babel + react, I was told to include following in .babelrc:
"presets": ["latest", "stage-0", "react"]
I want to understand: why should I use babel presets, what do they allow me to do (apart from babel itself)? That's one question. Hope that's not opinion-based (in terms of stackoverflow), it's about how babel works.
As far as I read in the docs, preset-latest combines preset-es2015 + preset-es2016 + preset-es2017. As far as I understand, these are officially accepted features of upcoming ES versions and latest is a shorthand for choosing not only ES2015, but all future versions at one shot. The specs won't change, so it's stable enough to use in production.
But how about stage-0, stage-1, stage-2, stage-3 - do they represent features that are still unofficial proposals of upcoming ECMAScript versions or does that stand for something else? Babel docs is not clear about that. That's second question.
And finally, what is the difference between a plugin and a preset?
...why should I use babel presets, what do they allow me to do...
A Babel preset conveniently defines a group of Babel plugins so that you don't have to explicitly declare you want to use each of them under "plugins" in your .babelrc (or wherever you declare your config).
Take a look at the source code of the es2016 preset and you'll see what I mean... it simply exports an array of plugins: https://github.com/babel/babel/blob/master/packages/babel-preset-es2016/src/index.js
...(apart from babel itself)?
Babel itself is an interface for its plugins. It utilises a sibling program, babylon, a fork of acorn, that provides plugins a particular way of parsing, inspecting, and then manipulating the source code of your program, in order to add the features you want according to the plugins you use.
And finally, what is the difference between a plugin and a preset?
As discussed, a preset itself does not contain features, rather a list of plugins. Together these typically represent some related group of functionality. For example, the stage-0 preset will contain all plugins that implement features of proposals which are at stage zero of the process of submission defined by TC39, ECMAScript's "governing body".
You might have noticed that a preset is a JavaScript file instead of JSON. This is because the list of plugins that a preset defines can be derived from a configuration. Take a look at the env preset, for example: https://github.com/babel/babel-preset-env/blob/master/src/index.js
But how about stage-0, stage-1, stage-2, stage-3 - do they represent features that are still unofficial proposals of upcoming ECMAScript versions or does that stand for something else?
There are no "official" proposals. A proposal can be submitted by anyone. But if what you mean by official is whether the proposal is being seriously considered, that is determined by 1) what stage it is at in the process and 2) general consideration by the community of its worth as a new feature. However you should always take proposals with a pinch of salt in terms of whether they will be accepted, even at the last stage, as we have experienced with Object#observe, which was dropped at the very last minute.
I also didn't understand why "modules": false and why there is an "env" setting and that env has its own preset configuration.
Finally, I found this article What's in our .babelrc? explains it well, e.g
Secondly, we set modules to false to ensure that import statements are
left as is (opposed to transpiling them to require). We're doing this
to give Webpack the ability to statically analyze our code to produce
more efficient bundles.
Lastly, we have an environment specific override for Jest, our testing
framework of choice. Since Jest is run in node, we need to transpile
our imports to requires, and target whatever node runtime we're
currently working in.

es6 modules to commonjs with typescript under node harmony flag

I'm using TypeScript (1.6) with node under the --harmony flag, so I'd like to transpile the es6 module syntax to commonjs.
From what I can tell, I can't do this with TypeScript 1.6. If I set my target to es6, and module to commonjs, I get a TypeScript error -
Cannot compile modules into 'commonjs', 'amd', 'system' or 'umd' when
targeting 'ES6' or higher.
Why won't TypeScript compile to commonjs with an ES6 target? I imagine a lot people want to do this since node doesn't support ES6 modules yet.
I'd thought the new moduleResolution compiler option might solve this issue, but it doesn't appear to do anything.
Currently, I'm having to use babel just to transpile the module syntax to commonjs, but I'd like to remove babel from my builds so I can take advantage of source maps.
Is there a way I can achieve this? NOTE: I do not want to transpile to ES5. I want my JS running as ES6 under the harmony flag. Thanks!
The TypeScript team will add support for what you are looking for in the next release. You can wait for a few weeks/months. Alternatively, you can use a Polyfill for the ES6 module loader:
es6-module-loader
SystemJS
There are more libraries like the ones above available online just check which one does the job for you until official support for --module with --target es6 arrives.
UPDATE
tsconfig.json
{
"compilerOptions": {
"target":"ES6",
"moduleResolution": "classic",
}
}
ES6 support with generators
No import stuff transpiling due to
"moduleResolution": "classic"

ReferenceError: Intl is not defined in Node.js

I'm trying to construct a new Intl.Collator() object in Node.js.
Does anyone know why the Intl object wouldn't be present in a Node runtime?
According to MDN, it is specified as a Namespace by ECMAScript, so I don't see why it wouldn't be there.
Unfortunately node currently (as of version 0.10, at time of writing) does not support the ECMA-402 Intl object unless you perform a custom compile of node, which is documented in the node.js Readme.
With libicu i18n support:
svn checkout --force --revision 214189 \
http://src.chromium.org/svn/trunk/deps/third_party/icu46 \
deps/v8/third_party/icu46
./configure --with-icu-path=deps/v8/third_party/icu46/icu.gyp
make
make install
If compiling a custom build of node is not an option or the idea fills you with dread, a workaround is to use the intl module, a Javascript polyfill which covers much of the EMCA-402 standard, except for the Intl.Collator, the reasons for which are covered in the project Readme file.
Using the module is straight-forward:
npm install intl --save
Then in your node code:
var Intl = require('intl');
console.log(new Intl.NumberFormat("de-DE").format(12345678));
Hope this helps.
Since io.js was merged into Node, it should be possible to use Intl in newer versions of Node (available in io.js from v3.1.0).
intl: Intl support using small-icu is now enabled by default in builds (Steven R. Loomis) #2264.
String#normalize() can now be used for unicode normalization.
The Intl object and various String and Number methods are present, but only support the English locale.
For support of all locales, node must be built with full-icu.
https://github.com/nodejs/node/blob/master/CHANGELOG.md#2015-08-18-version-310-fishrock123
Node 0.12 has included support to Intl, but it comes with only a subset of ICU locales (i.e.: English). You need to build Node with flags for full ICU (or any subset you need). Long instructions for ICU build here: https://github.com/nodejs/node/wiki/Intl
I would recommend reading the FormatJS documentation:
http://formatjs.io/
And especially the Intl Polyfill
https://github.com/andyearnshaw/Intl.js
var areIntlLocalesSupported = require('intl-locales-supported');
var localesMyAppSupports = [
/* list locales here */
];
if (global.Intl) {
// Determine if the built-in `Intl` has the locale data we need.
if (!areIntlLocalesSupported(localesMyAppSupports)) {
// `Intl` exists, but it doesn't have the data we need, so load the
// polyfill and replace the constructors we need with the polyfill's.
require('intl');
Intl.NumberFormat = IntlPolyfill.NumberFormat;
Intl.DateTimeFormat = IntlPolyfill.DateTimeFormat;
}
} else {
// No `Intl`, so use and load the polyfill.
global.Intl = require('intl');
}
Intl.js does not (and will never) implement Intl.Collator. For this one, you really need to rely on Node 0.12 built with your required locales.

Categories

Resources