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
Related
I am hoping to use async/await in my source code and have it transpiled by babel to something useable by >0.25% not dead.
My head is spinning with the plethora of ways to attack this. Some are deprecated, some flat out don't work, and the one that I have gotten to work more than doubles the size of my library.
I've tried using #babel/polyfill with #babel/plugin-transform-async-to-generator and it works well, but the library goes from ~500kB to ~1.1MB.
I also tried leaving it to #babel/preset-env by giving it >0.25% not dead, but that hasn't made a difference. I get:
regeneratorRuntime is undefined
I'm hoping there is a better way to do this than including all this regeneratorRuntime stuff...
I'd rather go back to the callback pyramid of doom than ship a library over 1mb...
I am using:
webpack 4.41.0
babel 7.6.2
If you only need the generator polyfill — which is needed for async/await — then you can just use facebook/regenerator.
You could follow the steps to support async/await in IE 11:
use babel-preset-env
yarn add regenerator or npm install regenerator
add node_modules/regenerator-runtime/runtime.js (10.7kb minified) into your bundle
Reference link: Add ES7 Async/Await Support for your Webapp in 3 Easy Steps
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'm relatively new to ES6+ (called modern JavaScript) but it seems if I want to use it in browsers I need babel-minify or terser. (First I thought Babili is another player but it's just the old name of Babel-Minify)
About polyfills for the browser there are production ready solutions like #babel/polyfill or Polyfill.io and with them it can be achieved to send smaller + faster code to modern browsers because they need no/few polyfills (test the browser quickly, load the needed polyfills dynamically and then start our app's main script). So it seems absolutely reasonable to use these modern technologies.
Here comes my dilemma about choosing babel-minify or terser.
The Webpack team decided to switch to terser in upcoming Webpack 5.
The Babel team made a comparison table showing terser is much better in speed.
The docs says that terser is a fork of uglify-es which was widely used before.
These makes me think that I have to choose terser.
But on the other hand, Babel is still needed for transforming (and can be used for many useful things). They are in the business a long time ago (although Babili/babel-minify was first released on August 26, 2016, so uglify is older). They have a great developer community on GitHub, bugs may have discovered and fixed sooner. Based on these I feel more trust to them when it comes to production safe output. But I haven't found any article showing the pro's of babel-minify over terser.
Questions:
I would go with terser because it seems promising and the reasons written above, but:
What are the cases when I should use babel-minify over terser?
Does it have any advantages of doing all the things with Babel packages?
In most cases, it won't matter too much whether or not you use terser or babel-minify. That said, the benefit to using babel-minify would be tight integration with the rest of the babel ecosystem. If you are using babel outside of a bundler like webpack, or on the CLI, babel-minify can be ran at the same time as other babel transforms, and therefore requiring minimal additional config. Babel-minify would also be able to use the same cache as the rest of the babel plugins, if you have caching enabled through for example babel-loader.
Originally, babel-minify (then babili) was created because there was no uglify-js version compatible with ES6 or newer, and babel already had a parser that supported the new syntax. Since then, terser has become a good alternative, and performs faster than babel-minify while still supporting ES6 (probably because it's not tied in to babel's transform pipeline). Due to this and the reasons you listed, terser would probably be the best option to choose now.
One possible exception would be if you use experimental syntax that has not yet been standardized as part of ECMAScript, but is supported in babel's parser (possibly with a plugin). In this case, babel-minify might prove to be beneficial.
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
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.