I used grunt-uglify in my project and I'm working with es6. for some es6 features, such as fat arrow function, it's throwing an error. I think the uglify don't understant that syntax. so do i have a way to fix this issue. I mean can i use anything to make uglify understand all the es6 syntaxes?
You can use the harmony branch of grunt-contrib-uglify.
npm install git://github.com/gruntjs/grunt-contrib-uglify.git#harmony --save-dev
works perfectly with es6. No additional settings for grunt are required.
Officially there's no tool that minifies ES6 yet (Other tools like Google Closure compiler supports ES6 but it transpile it into "traditional js" and then it's minified).
Although not all the es6 features are supported in UglifyJs, the Harmony branch of UglifyJS2 seems to support arrow functions and other features.
You can read the discussion about it in the issue of github here. It seems there's not another option to wait (or create your own ES6 minifier).
Update
Now you have 2 options to minify ES6:
Babili, an ES6+ aware minifier based on the Babel toolchain (beta)
The Harmony branch of UglifyJS
A Grunt plugin ES6 parser, mangler/compressor and beautifier toolkit for ES6+ is now available:
https://github.com/adascal/grunt-terser
Great job, it just works as expected.
The harmony branch of grunt-contrib-uglify is deprecated, it's not a sustainable solution.
If the resulting code does not need to use ES6 syntax, it is also possible to transpile ES6 to ES5, before uglifying your code. This can for example be done with the Grunt task grunt-es6-transpiler.
I just updated to uglify-js#2.8.29 and it worked.
Related
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
We have in-house written build automation running on NPM and NodeJS. I'm fully comfortable with automating some transform steps to get TypeScript and Babel working together. I just wonder what the benefit will be. Can anyone tell me? It would appear that since TS has added support for ES6 that you don't really need Babel. The one thing that seems probable is Babel supporting new features sooner, but TS doesn't seem to be too far behind at the moment.
Am I missing something?
In my opinion you transpile TypeScript code to ES6 by using typescript and then re-transpile it to es5/es3 using babel to use in most javascript run times. Now because typescript compiler gives you es6 javascript you can do tree-shaking which is only supported for es6 module. And after tree-shaking your es6 javascript you can now compile it down to es5 to be able to used by most of the javascript run times out there.
Basically
Compile ts to js-es6
tsconfig
{
"compilerOptions": {
"target": "es6"
}
}
tree shake or dead code elimination in es6 javascript
Tree Shaking
Using rollup etc
Transpile to es5 javascript to be able to run in most of the javascript runtimes
.babelrc
{
"presets": [
"es-2015",
"stage-2"
]
}
Currently appears as UglifyJS2 and Google Closure doesn't support JavaScript minification of scripts including async/await usage without transpiling them.
Is there a way or another minifier to get these JavaScript scripts minified without the need to transpile them?
UglifyJS introduced support for async/await in uglify-es#3.0.17
( https://github.com/mishoo/UglifyJS2/issues/1789)
Not yet. Right now in order to minify the code you will need to transpile it first.
There is an open issue in UglifyJS2 repo - Harmony support #448:
https://github.com/mishoo/UglifyJS2/issues/448
You can track the progress of this issue. Hopefully the support will get added.
If you are willing to add the transpilation step then see this answer:
minify es2017 with gulp
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.