I want to build a simple library in JS (vanilla). I am a bit confused about whether to follow the class-based paradigm or prototypal-based paradigm. ES6 is now in the mainstream, even though ES5 is being used.
What things Should I consider
The best way to do this is to write your source code using the latest ES6+ features. Now your javascript library may be consumed by three different types of clients:
Browser
NodeJS
Another library
1. Browser - For browser, the best option is to have the source code transpiled into ES5 and then build in IIFE form.
2. NodeJS - The best option is to transpile it to es5 and build in CommonJS(CJS)format.
3. Another library - The best option is to transpile the source code to es5 but still retain the es5 modules (export/import). You can export the build as esm modules. This helps the bundling tools for better treeshaking while using your library as a dependency.
The mostly used js bundling libraries: Rollup, Webpack and Parcel supports them. You can check them out for more info.
Happy coding =)
You could use ES6 and transpile the code with babel to ES5 for backward compatibility.
Take a look at this boilerplate for example code.
npm-module-boilerplate
I've noticed some web projects using typescript and webpack also use babel to finish off the compilation. For example, they use ts to compile to ES2015 and then use babel to compile to es5. Why not just use ts directly to compile to es5?
Is it in the case the project also has js that needs to be compiled so they just use babel for everything? Or what am I missing?
Thanks.
There's a few possible reasons for this.
They're using Babel to automatically polyfill - TypeScript only performs syntactic transformations, leaving the user to figure out what runtime libraries they'll need to be around (e.g. Promise, Symbol, etc). This allows you to decide which implementation of these polyfills will work the best for you, but it can be a pain. Babel spares you the burden of thinking about that. It's a tradeoff.
They need it for a custom transformation - TypeScript has a transform pipeline, but it's only accessible when you use the TypeScript API at this point in time. If you're already using Babel and want to start using TypeScript, but you're already using a transform, this is a reasonable compromise.
It was created when TypeScript didn't support compiling generators to ES5 (or even back when TypeScript didn't support async/await in ES5) - TypeScript has supported async/await in ES5 since 2.1, and has supported generators behind the downlevelIteration flag since 2.3. Before that, users often relied on Babel to pick up the slack, but Babel isn't needed here anymore.
It was created before Webpack 2 and the project used a specific way of importing modules - TypeScript has an allowSyntheticDefaultImport option which tells TypeScript that default imports can be used to import certain modules. Babel supports this behavior, but Webpack didn't until Webpack 2 came out. Babel isn't needed here anymore for newer versions of Webpack.
This might not be the complete set of reasons, but it's a few I can think of off the top of my head.
Why not just use ts directly to compile to es5?
That is what I do.
About mixing Babel and TypeScript
There is no flaw in using the both together. Since both do:
(non js OR js) => standard js
You can do
(non js OR js) => standard js => es5
Either by TS -> JS -babel> ES5 or Babel -> JS -ts> ES5
The reason people do it is for varied syntax support : https://kangax.github.io/compat-table/
Personally
As mentioned. I don't use Babel as I TypeSafety is big for me and don't need to use syntax that isn't yet type safe 🌹
Typescript is the evolution frOM ES2016 onwards. Typescript helps the developer from c# and java background to become javascript developers using various tools. Visual Studio code, WebStorm, Sublime etc.
Why: We can not use Typescript alone for converting ts to ES5
Compiling to ES5 with TypeScript is not as complete as it is with Babel. Some modern language features, such as Array.prototype.find, cannot be compiled to ES5 with TypeScript.
Here is the link that will help you out: https://www.stackchief.com/blog/TypeScript%20or%20Babel%3F
Looking at some boilerplate's projects on github like:
https://github.com/KunalKapadia/express-mongoose-es6-rest-api
https://github.com/kylealwyn/node-rest-api-boilerplate
Some of them still use Babel. Node already supports almost all new features on ES2016 and ES2017 (Except Experimental). The only thing left is Modules. There is another reason to use Babel on Node projects?
It really depends on your Node engine version, so simply check Node Green Project, You'll see how much Node covers ES6,7 and....
However, I would mention this that sometimes you are going to use Node Version 4 deliberately, for instance, when you want to deploy to AWS Lambda, you should set your project engine to 4 and in this case, you need Babel if you are coding in Fully ES6.
Electron's documentation (for example http://electron.atom.io/docs/api/browser-window/) says to import some features using a destructuring statement:
const {BrowserWindow} = require('electron')
This works when running the code in Electron but Jasmine and Visual Studio* claim that the "{" is a syntax error.
What is the correct usage?
*The code is actually written in Typescript (1.8 targeting ES2015) but the transpiled code in JS is identical in this case.
This code is valid ES6/ES2015, but is not valid ES5.
Destructuring assignments are supported in node.js >= 6.4. If your Jasmine is run with an older version, it will not work. Not sure about Visual Studio, but it looks like you need a recent version of VS 2015 to be able to have ES6 features.
Therefore you should either update your tools, or just configure Typescript so it targets ES5 instead.
I'm working with node.js, and in one of my js files I'm using const in "strict mode". When trying to run it, I'm getting an error:
SyntaxError: Use of const in strict mode.
What is the best practice to do this?
Edit:
'use strict'
const MAX_IMAGE_SIZE = 1024*1024; // 1 MB
The const and let are part of ECMAScript 2015 (a.k.a. ES6 and Harmony), and was not enabled by default in Node.js 0.10 or 0.12. Since Node.js 4.x, “All shipping [ES2015] features, which V8 considers stable, are turned on by default on Node.js and do NOT require any kind of runtime flag.”. Node.js docs has an overview of what ES2015 features are enabled by default, and which who require a runtime flag. So by upgrading to Node.js 4.x or newer the error should disappear.
To enable some of the ECMAScript 2015 features (including const and let) in Node.js 0.10 and 0.12; start your node program with a harmony flag, otherwise you will get a syntax error. For example:
node --harmony app.js
It all depends on which side your strict js is located. I would recommend using strict mode with const declarations on your server side and start the server with the harmony flag. For the client side, you should use Babel or similar tool to convert ES2015 to ES5, since not all client browsers support the const declarations.
If this is happening in nodejs, it is due to the older version of nodejs. Update node by using,
1) Clear NPM's cache:
sudo npm cache clean -f
2) Install a little helper called 'n'
sudo npm install -g n
3) Install latest stable NodeJS version
sudo n stable
Update nodejs instructions taken from, https://stackoverflow.com/a/19584407/698072
Usually this error occurs when the version of node against which the code is being executed is older than expected. (i.e. 0.12 or older).
if you are using nvm than please ensure that you have the right version of node being used. You can check the compatibility on node.green for const under strict mode
I found a similar issue on another post and posted my answer there in detail
One important step after you update your node is to link your node binary to the latest installed node version
sudo ln -sf /usr/local/n/versions/node/6.0.0/bin/node /usr/bin/node
This is probably not the solution for everyone, but it was for me.
If you are using NVM, you might not have enabled the right version of node for the code you are running. After you reboot, your default version of node changes back to the system default.
Was running into this when working with react-native which had been working fine. Just use nvm to use the right version of node to solve this problem.
Since the time the question was asked, the draft for the const keyword is already a living standard as part of ECMAScript 2015. Also the current version of Node.js supports const declarations without the --harmony flag.
With the above said you can now run node app.js, with app.js:
'use strict';
const MB = 1024 * 1024;
...
getting both the syntax sugar and the benefits of strict mode.
I had a similar issue recently and ended up in this Q&A. This is not the solution the OP was looking for but may help others with a similar issue.
I'm using PM2 to run a project and in a given staging server I had a really old version of Node, NPM and PM2. I updated everything, however, I kept keeping the same error:
SyntaxError: Use of const in strict mode.
I tried to stop and start the application several times. Also tried to update everything again. Nothing worked. Until I noticed a warning when I ran pm2 start:
>>>> In-memory PM2 is out-of-date, do:
>>>> $ pm2 update
In memory PM2 version: 0.15.10
Local PM2 version: 3.2.9
Gotcha! After running pm2 update, I finally was able to get the application running as expected. No "const in strict mode" errors anymore.
I was using pm2 to start and maintain the node processes.
From the CLI it worked perfectly.
which node
/usr/local/bin/node
node -v
v10.15.0
However, I set up a cronjob and I got the syntax error.
Then wrote a cronjob to check which node and node -v and surprisingly, it was a different path and version.
which node
/usr/bin/node
node -v
v0.10.48
To fix the cronjob I had to use the flag --interpreter for pm2, like so:
pm2 start dist/server.js --interpreter=/usr/local/bin/node
The use of const in strict mode is available with the release of Chrome 41.
Currently, Chrome 41 Beta is already released and supports it.
cd /
npm install -g nave
nave use 6.11.1
node app.js
const is not supported by ECMAScript. So after you specify strict mode, you get syntax error. You need to use var instead of const if you want your code to be compatible with all browsers. I know, not the ideal solution, but it is what it is. There are ways to create read-only properties in JavaScript (see Can Read-Only Properties be Implemented in Pure JavaScript?) but I think it might be overkill depending on your scenario.
Below is browser compatibility note from MDN:
Browser compatibility
The current implementation of const is a Mozilla-specific extension
and is not part of ECMAScript 5. It is supported in Firefox & Chrome
(V8). As of Safari 5.1.7 and Opera 12.00, if you define a variable
with const in these browsers, you can still change its value later. It
is not supported in Internet Explorer 6-10, but is included in
Internet Explorer 11. The const keyword currently declares the
constant in the function scope (like variables declared with var).
Firefox, at least since version 13, throws a TypeError if you
redeclare a constant. None of the major browsers produce any notices
or errors if you assign another value to a constant. The return value
of such an operation is that of the new value assigned, but the
reassignment is unsuccessful only in Firefox and Chrome (at least
since version 20).
const is going to be defined by ECMAScript 6, but with different
semantics. Similar to variables declared with the let statement,
constants declared with const will be block-scoped.