I just started looking into Babel. From my understanding, Babel attempts to convert ES6 code into older JS versions for better browser support. This is pretty simple for stuff like template literals. And it is even possible with classes. But how does it handle import?
I am also confused why sometimes it converts import into require, because require is node.js specific, and it definitely would not work on any browser.
Related
I am unsure the differences between importing a JavaScript module in the following:
CommonJS
ES5
ES6
NodeJS
Typescript
Why are there so many ways to import javascript modules? Is "module" defined differently in different implementations? Are all doing the same thing but with different syntax?
There are no modules in ES5 and earlier. Various module systems (CommonJS, AMD, and the CommonJS-like ones in and Node.js and TypeScript) were created because there was no standard module system in JavaScript at the time, but it's a really useful thing to have. So the need got filled by tools and toolbuilders.
ES2015 (aka "ES6") created a standard syntax for modules in JavaScript which has now been adopted by all modern browsers, Node.js, and TypeScript. That standard syntax leaves the semantics of module identifiers up to the host environment, so leaders in the web community had to come to consensus for how to do them in browsers (and Node.js had to figure out how to do it in Node.js, etc.), so there was a bit of a delay between ES2015 coming out and your being able to use that syntax natively (though Webpack, Rollup, and such handled it).
There are some use cases where ES2015's static syntax doesn't quite do the job, so there's the import() (dynamic import) proposal which is already supported in some environments and will be in ES2020.
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
Quick question. I am a bit confused about ES2015(ES6).
Let's say I use Babel to compile to ES6 Javascript to compliant ES5 for current browsers.
The import/export functions are already available in ES6 by using Babel. So why would I need something like Browserify or Webpack if I were to simply use these just to bundle my modules, when ES6 could do it for me?
Everywhere I go I see people using Babel in combination with Browserify or Webpack. Although I know something like Webpack can be used for more, but I wonder if it is also possible to bundle files using the ES6 syntax.
I might be totally in the wrong here and I might have gotten lost in the Javascript Jungle of 2016, so I hope someone can clarifty this for me.
Edit
Am I right to assume that the native ES6 import / export functionality simply does not bundle files? From what I have read so far I think you still need to include all the separate Javascript files but you simply import modules into each-others namespace by using the native import functionality?
Yes, using babel to transpile your ES6 imports into ES5 will work.
However, one advantage of using webpack is that creates one static file to be served up in your production environment.
Pre-ES6 has no native module system, so there are multiple systems constructed in userland code (e.g. CommonJS / Node modules and AMD). Those are what Babel converts ES6 module syntax to (and yes, you're correct that ES6 module syntax has no native bundling story anyway). Browsers have no knowledge of those userland APIs. Node implements its module system by wrapping a "module" in a function that injects require() etc. In a browser require() would just be a reference error. Browserify (or another bundler) makes it work in the browser, and bundles a whole dependency graph into a single script. So if the code is for the browser you're likely going to want to bundle it. If it's for Node you may not need to.
The import/export functions
Not functions, declarations.
if I were to simply use these just to bundle my modules, when ES6 could do it for me?
I wonder if it is also possible to bundle files using the ES6 syntax.
Am I right to assume that the native ES6 import / export functionality simply does not bundle files?
Yes. There's no native way to bundle ES6 modules. You can transpile ES6 module syntax to something like Node modules and bundle those.
From what I have read so far I think you still need to include all the separate Javascript files but you simply import modules into each-others namespace by using the native import functionality?
It's important to realize that while the syntax is standardized, a lot of the behavior isn't. There's a Loader spec under development to specify how modules will actually be located and loaded.
See also https://stackoverflow.com/a/33044085/1034448.
In my project I'm using React and Babel so I use some ES6 features but mainly those used by React. Webstorm gives me the option to mark my syntax either as ES6 or JSX Harmony and I got confused.
I think I know what ES6/ES2015 is and how to use it with a compiler, eg. Babel.
The hard part id JSX/JSX Harmony. I know that React uses "JSX" but:
Is this the same JSX as here? If not, which JSX is meant by JSX Harmony option in Webstorm?
I've seen the compatibility page mentioned here and know that JSX Transformer supports only small part of ES6 but also that apparently Babel supports JSX as an addition to ES6 support so JSX seems to be more than ES6 subset... If so, what features of JSX React or JSX Harmony are not part of ES6 specs?
EDIT:
As for question 1 I'm getting sure, these are two completely different things. But what is JSX Harmony then?
EDIT 2:
To answer my own question, Webstorm JSX Harmony refers most probably to the syntax supported by React JSX Compiler with --harmony flag on - adding a bit of ES6 support.
No, it's not the same jsx. There are two languages called JSX that I know of:
The templating language for React.js
A statically typed programming language that compiles down to javascript.
The two languages are as different as XML and C++.
The JSX you're looking for is from here: https://github.com/facebook/react and can be installed via npm from here: https://www.npmjs.com/package/react-tools
The JSX programming language will not compile React JSX templates.
No, it's not the JSX you've mentioned. It's this one.
JSX is a XML-like syntax extension to ECMAScript without any defined
semantics. It's NOT intended to be implemented by engines or browsers.
JSX doesn't intend to transpile the ES6 features to ES5, so, it only implements some of the most useful features to help with the templating code.
If you want to use ES6 today, you must use Babel (preferred) or Traceur to transpile your code to ES5, and then you can use most of the features already available. If you want an even more powerful transpiler, that also has type definitions, you can take a look at Typescript.