> There is no future in it.
Came here to say this. This is the most compelling argument against CoffeeScript.
The situation would be different if CoffeeScript was being developed as actively as the ES2015 standards are, but it's just not. They used to have a massive lead on Ecmascript, but not anymore, and it's set to start falling behind now, thanks to Babel being virtually completely up to date with even stage 0 proposals.
With ES2015 transpilation, you can have most of the cool stuff CS offers in a forwards-compatible setup. That's what everyone should be working towards now, in my opinion.
CS was a great influence and very important in JS development, though.
Did you read the blog post? Or maybe this one http://babeljs.io/blog/2015/02/15/not-born-to-die/?
Babel is not just an ES6 transpiler. The plans for Babel aren't just ES7+, it's goal is to become the base of all major JavaScript tooling. Linters, minifiers, type systems, formatters, syntax highlighters, codemods, etc. They all need similar tools to work and Babel is there to provide that tooling.
Babel member here.
TypeScript is a language and Babel transpiles your 'next-gen' JavaScript to more compatible one.
Babel configuration should be easy using http://babeljs.io/docs/plugins/preset-env/, you basically give your target (Chrome 54), it will add the missing polyfills and outputs the correct code.
If you need help I would recommend you joining our Slack: https://slack.babeljs.io/.
You can use Flow (https://flow.org/) for static typing.
You can still use those features as individual plugins, but they are no longer available as grouped "presets". I think the plugins are now named as "-proposal-" too. See http://babeljs.io/blog/2018/07/27/removing-babels-stage-presets
Don't use it in your code. You definitely want to optimize your code by having babel being part of a build step. Here are some steps to get you going.
If you do what I was saying, you can have a script in your package.json that has:
"build": "babel srcFileHere.js --out-file newFile.js"
and if you run on the command line:
npm run build
You should get the desired result. btw, you can transpile whole directories at a time with the CLI tool.
EDIT: Also, if i find my build step becoming too complicated for a simple npm script, I implement Gulp or some other kind of more thorough build file.
Yep, it's called arrow syntax.
Support is not very widespread yet, as it is ES6, but you can use it by compiling with babel.
It's mostly just a shorter replacement for anonymous functions, but it does have some cool features/caveats to look out for.
someIntegerArray.map( (integer) => integer * 2 );
will return a new array with each value multiplied by two, because a one-statement arrow function with no curly braces will automatically return the result.
function test() { setInterval( () => { this === "Hello world"; // true }, 1000); }
// call with this === "Hello world"
test.call("Hello world");
Arrow functions also are automatically bound to the outer scope, meaning the this
value within it will be the same as the this
value outside.
I'm having trouble finding it now, but I recall at one point the creator of JavaScript saying that the behavior of var
is something that he considers to be a mistake in the design of the language.
The rule of thumb that I prefer is to use let
for variables, and const
for values. Remember that const
is also block scoped; take a look at the example here: http://babeljs.io/docs/learn-es2015/#let-const
I'd recommend fetch or SuperAgent for use with React since they provide the same interfaces on the server and in the browser
As for the best utility, Babel. Being free to utilize ES6 and ES7 is huge.
If you use Babel in your build step, it will convert it to ES5.
const name = 'Michael';
const message = Hello ${name}, how are you?
;
Converts to...
var name = 'Michael'; var message = 'Hello ' + name + ', how are you?';
You can use all the nice ES6 stuff, knowing you're safe with it being converted to ES5.
This also means that one day, your code will be future-ready and you'll be able to remove that Babel step all-together.
Correct! Good catch.
Wrapping the object in parens works:
arrayOfObjs.map(o => ({[o.a]: o.b}));
ES6 has (and was heavily inspired by) a lot of the conveniences available in CoffeeScript. And, like others have said, it's going to be the standard going forward, whereas CoffeeScript's popularity is just going to keep shrinking.
You mentioned this project will be using React; I cannot stress enough about how strongly the React developers and overall community favor ES6 over CoffeeScript, the latter of which has extremely little-to-no presence in open source libraries, tutorials, blogs, examples, etc. And I don't mean this to sound like an argument from authority! Rather, imagine you and your team trying to use React and React-based libraries and finding that most of it's written in ES6. It's doable, but why deal with the frustration?
The author messaged me asking how to do it without async+await / pure jQuery.
Easy answer is to compile it down with Babel. If you don't have a babel step in your compile, just pop it into this online generator:
If you are supporting browsers without promises, you can use poyfill.io to polyfill them pretty easily.
If you can't use anything, then you are stuck in callback hell with your original code :(
npm WARN deprecated [email protected]: We're super 😸 excited that you're trying to use ES2017+ syntax, but instead of making more yearly presets 😭 , Babel now has a better preset that we recommend you use instead: npm install babel-preset-env --save-dev. preset-env without options will compile ES2015+ down to ES5 just like using all the presets together and thus is more future proof. It also allows you to target specific browsers so that Babel can do less work and you can ship native ES2015+ to user 😎 ! We are also in the process of releasing v7, so please give http://babeljs.io/blog/2017/09/12/planning-for-7.0 a read and help test it out in beta! Thanks so much for using Babel 🙏, please give us a follow on Twitter @babeljs for news on Babel, join slack.babeljs.io for discussion/development and help support the project at opencollective.com/babel
This project is now a bit dated.
Use ES6's template strings.
They already work in the stable versions of Firefox and Chrome. Io.js supports them and for Node (and older browsers) there is Babel.
If you can, just switch to io.js. It and Node.js will be merging soon anyway (ongoing right now actually).
If you can't, take a look at Babel, which can either compile ES6/7 to ES5 before you run your app or can insert itself into the global require function to compile files as you require them. Either way it works wonderfully.
To be honest, native ES6 classes aren't perfect yet. Even the latest io.js build has issues with them sometimes. Babel provides a fast and concise translation of classes easily enough I prefer it over the native classes. And with ES7 extensions like class properties, it's even better.
> Which one do you prefer and why.
> Does Babel's configuration bother you?
No. Since env
is now the preferred preset, targeting evergreen or a specific threshold has never been easier. Tuck this away in .babelrc, package.json or inline in your webpack config and that's that:
{ "presets": ["env"] }
You could also use ES6 arrow functions:
someFunction().then(() => SomeObject.someMethod());
ES6 is the new version of JavaScript. Even if it's not fully supported by all browsers, it's widely used because you can have it compiled to ES5 syntax with tools like Babel.
The reason for all these packages is the fact that babel isn't just es6 -> es5 anymore. It's a general transpiler for JavaScript so it doesn't do anything out of the box. You have to install the right presets based on what you want to do. babel-preset-es2015
is the actual preset that will transpile from ES2015 (formerly known as "ES6") to ES5. If you were using an alternate syntax like JSX for React, you would also want to install babel-preset-react
, etc.
I would definitely recommend taking a look at this page.
async/await has already moved up to stage 3 according to the documentation: http://babeljs.io/docs/plugins/preset-stage-3/
This means it's already in the candidate stage and not a stage 0 strawman, more or less just waiting to be wrapped up and move on to stage 4 (finished).
You should see the tickets we get on Babel (http://babeljs.io) and that only has a couple thousand users. Working on that project I have an endless amount of respect for support people for any company.
Don't tell anyone. Doubtful it'll make it into ES7. (Hrrm, I think my original post got deleted because I used a url shortener. And Reddit doesn't want to let me use URL syntax for this link. Sorry.)
Who said it was an either-or thing?
Many people have started using TypeScript (or flow!) for the type checking part and Babel for the compilation since:
*Babel is actually a general purpose JavaScript compiler that you can build your own tools on top of. Check out the Babel Plugins GitHub org. Also see the plugin documentation.
Async code takes some time to understand IMO. Besides callback there are also promises (and async/await in ES7). I prefer to work with promises over callbacks but async/await looks really cool. The latter will require Babel to transpile ES6/ES7 to ES5 (what most modern browsers understand today).
I can't tell you if Alt is bad. I can't even tell you if Redux is good to tell you the truth. However the author of Redux are doing lots of great stuff for React so I believe in his implementation and I know it works awesome with React hot loading.
I will be learning Redux when it is time to use a Flux architecture in my application.
ES6 import/export logic is unopinionated. It's up to the interpreter to resolve modules and so forth. However, most interpreters, like Node and browsers, don't support ES6 modules at all, so it needs to be transcompiled into a syntax they understand.
For example, using Babel, you can transform ES6 module syntax into CommonJS (what Node uses) or AMD (for browsers) or even UMD (everything) syntax.
For more information on that, see here.
In the announcement, they referred to those as "virtual methods":
http://babeljs.io/blog/2015/05/14/function-bind/ (thread)
It's certainly a big improvement over monkey-patching.
> My personal opinion is that the Babel guys don't implement arrows correctly because they disagree with the spec (I would love to hear from them if they read this).
This is unequivocally false. Please see the FAQ. This only applies to top level this
. Furthermore see https://github.com/babel/babel/issues/562 for why this decision was made in the first place.
As /u/wreckedadvent mentioned, you can "transpile" (basically like compiling) ES6 and even some ES7 features down to plain old ES5 that runs in every major browser. In my opinion, this is well worth doing. It works fine and will save you headaches in the long run.
Every halfway serious project should already have some kind of compilation or minification pass, so then it should be easy to include BabelJS into the mix.
If you're still looking for a general toolset for doing these things, you should try Webpack, which lets you use BabelJS as a plugin.
The whole point of a transpiler is to implement ES6 concepts using the features ES5 supports.
There are no block-scoped variables in ES5. But that just means the transpiler needs to alter code that uses them. Babel does so like this.
For performance reasons, it usually creates a new variable name which is in the surrounding scope [though babel ensures it uses a name that isn't referenced in the JS]. But when needed, it turns the block into a new closure.
It does do exactly that and it's amazing. (Not sure about IE8, but IE9 for sure)
I really do think it's worth learning because it's not really a framework, it's just a compiler that lets you use modern JavaScript right now without worrying about compatibility.
Check out http://babeljs.io for more information.
You can do it manually if you prefer that, just go here: https://buble.surge.sh or there: http://babeljs.io/repl and copy paste your code. The npm tools would automate that but if you don't need it ...
If you want to have information about scoping etc, the already mentioned acornjs is not going to be enough, since it just provides the static AST tree, I think. Babel plugins receive information about scoping and the ability to introduce new vars etc.
Look on Google for "code smell" to learn about bad coding practices, then check out some style guides to see proper ways to structure your code. One great starting place is https://github.com/styleguide
As far as what's relevant html and css are definitely essential, the only thing different now is how we generate it. A while ago people would write plain html and css files whereas now it's more common to use js/php/ruby/python/etc. and/or preprocessors. For now stick with what you're learning and become comfortable with it then look at js and get good with it since if you add node.js to the mix you can use the language for both frontend and backend. In this scenario get good with plain js first otherwise you risk going all over the place and not understand anything if you start using all types of libraries and frameworks; this holds true for any language and it might not be something you realize until you're in over your head.
As for other languages first become proficient with js, check out es2015 and http://babeljs.io because just do it 🙂, and then if you decide you don't like it for some reason or want to move in a different direction you can look at other backend languages.
tl;dr learn html and css, then learn plain js, then learn es2015, then look at other languages if you want.
Super excited for this. It's clear, extremely practical, and solves an annoying pain point that I see surprisingly frequently. Sad to see that we'll have to wait quite a while to see it land for real though.
If you're really impatient, it looks like it's been in Babel since 5.4 (May 2015): http://babeljs.io/blog/2015/05/14/function-bind/
Okay so no one else has really said anything useful here so I'll give it my best go. First, read this excellent short history of javascript. It's quite interesting but the main point is that ECMAScript 5 (ES5) is the current standard and is what is implemented in web browsers.
There's currently an ES6 draft which adds many things to the language and for those people who want to use those things, they can write javascript according the the ES6 draft and have something like babel transpile it to ES5 so that it can be run. Babel has a short overview of ES6.
For your purposes, you should just learn regular ES5 javascript to start. You can pick up the differences that makes up ES6 after that. There's also even more experimental features under ES7, but these are not important things for a beginner to learn.
Here, they have tutorials for all the common tools http://babeljs.io/docs/setup/#browserify
[EDIT]: I personally use the CLI (browserify script.js -t babelify --outfile bundle.js) or more specifically "watchify script.js -t babelify --outfile bundle.js" which reruns the transform automatically when a file is changed.
I think ES7 JS can be counted as Javascript-like language. And you can run it with require hook. Not suitable for libraries, but suitable for apps. Don't forget to enable stage 1: http://babeljs.io/docs/usage/experimental/
The issue I have is that it adds unnecessary syntax. Virtual methods attempt to solve a problem that JS doesn't have at the expense of cognitive overhead. The pipe function and currying/partial application does the same thing without extra syntax.
Babel recently added support for this bind operator. Here's their examples (source).
//Babel ES6 example import { map, takeWhile, forEach } from "iterlib";
let _val; _val = getPlayers(); _val = map.call(_val, x => x.character()); _val = takeWhile.call(_val, x => x.strength > 100); _val = forEach.call(_val, x => console.log(x));
//Babel ES7 example import { map, takeWhile, forEach } from "iterlib";
getPlayers() ::map(x => x.character()) ::takeWhile(x => x.strength > 100) ::forEach(x => console.log(x));
An example using Ramda and ES6 functions. Lodash-fp can do the same thing as well. Change the fat arrows to functions and it's ES5.1 which works today (without compilation).
var R = require('ramda');
//we get a function that we can reuse var dry = R.pipe( getPlayers, R.map(x => x.character()), R.takeWhile(x => x.strength > 100), R.forEach(x => console.log(x)) ); dry(); dry();
The Ramda example is DRY (reusing chains in data processing is common, but the Babel examples need to be wrapped in a function to do this). It doesn't need me to track variables, and most importantly, I may have problems, but 'this' isn't one of them (seriously, 'this' causes a lot of JS bugs).
Automatically compiling ES6+ JavaScript or compile-to-JavaScript languages is quite possible. Babel even offers a require-hook to compile future JavaScript syntax and features to current JavaScript transparently, and there are similar require hooks for coffee-script and others.
Compiling SASS will pretty much require Ruby and the SASS gem. If you use Compass, it'll require that gem, too. However, there are grunt and gulp plugins for compiling SASS and Compass stuff.
If by front-end event logging you mean logging everything a user does on your webpage, that might be a little difficult and not really appreciated by your clients. Though if you mean recording statistics from the server, that's just a matter of running some code on each request to accumulate any statistics you want. It would probably be in the form of some middleware for Express of Koa.
Serving handlebars, or any other template, is incredibly easy and there are a number of rendering middlewares to do that. Consolidate offers MANY templating engines under a unified interface. Some view engines further simplify it.
As far as testing and so forth, there are many ways to do it, but it's usually very opinionated. The Mocha unit test framework is a good starting point, I think.
Actually, you want both babel and a shim. IE8 needs shims for a significant number of ES5 features/edge cases (bug fixes). Code generated by Babel for a decently-sized project will usually fail somewhere in IE8. Compiled ES6 classes have some issues all the way up to IE10, only IE11+ works 100% out of the box.
I would say the correct answer is to keep an eye on the caveats page and include the recommended polyfills for IE8-10 users. For me personally, I include them only for browsers that need them using IE's conditional comments. I haven't considered inlining any of the polyfills or doing a perf analysis of how the extra blocking round-trip affects load times. I just ensure it works and accept perf won't be optimal for the small number of people using IE < 11.
Babel Caveats: http://babeljs.io/docs/usage/caveats/
Conditional comments: https://msdn.microsoft.com/en-us/library/ms537512(v=vs.85).aspx
ES6 things seem to have a higher adoption with people using React, since many are already using Babel to transform their JSX anyways
http://babeljs.io/docs/learn-es6/#arrows
With React, ES6 makes for some super clean code
return <ul>{list.map(item => <li>{item}</li>)}</ul>;
or
return <ul>{list.map(item => <li><Thing props={...item} /></li>)}</ul>;
The problem is with the new class syntax. The new class syntax doesn't allow you to set property values, only methods. Here's a babel .js example showing the difference: http://babeljs.io/repl/#?experimental=true&playground=false&evaluate=true&loose=false&spec=false&code=var%20a%20%3D%20%7B%0A%20%20b%3A%20thing(function%20()%20%7B%0A%20%20%20%20%0A%20%20%7D)%0A%7D%3B%0A%0Aclass%20A2%20%7B%0A%20...
My personal opinion is that the class syntax should have allowed properties all along, its an integral part of who people write javascript and requiring workarounds to do what we're discussing here is a huge limitation. It means most serious projects will have to skip classes and uses the standard prototype syntax. This creates an awkward transition where a new project will use classes until it reaches a certain point and then has to transition. It will be even more confusing for new JS programmers.
Others have explained why a wrapper is needed to use generators in an async/await-esque way. Well, Babel will allow you to write async/await now by implementing wrappers for you during the compile step.
http://babeljs.io/docs/usage/transformers/other/async-to-generator/
http://babeljs.io/docs/usage/transformers/other/bluebird-coroutines/
If you're excited about them -- start using them. Node (and io more-so) supports a good amount of the ES6 spec today (enabled with the --harmony
flag (and a bunch of other flags in io)). The only thing I really want that isn't in today is destructuring and the spread op.
If you want to use even more features, run code through babel in either node or your browser. This gives you access to almost every feature of ES6 (as well as a handful from ES7) reference chart
As for a date, hahahahhaha. Yeah, right. You must be dillusional if you honestly expect a hard-date from any modern open source project :P
There must be something wrong with the emojimart repo. I tried running parcel on docs/index.html and I get the following error:
```
🚨 /Users/.../Documents/GitRepos/emoji-mart/docs/index.html: [BABEL] /Users/.../Documents/GitRepos/emoji-mart/docs/index.html: Unknown option: base.parserOpts. Check out http://babeljs.io/docs/usage/options/ for more info
at Logger.error (/Users/.../Documents/GitRepos/emoji-mart/node_modules/babel-core/lib/transformation/file/logger.js:39:11)
at OptionManager.mergeOptions (/Users/.../Documents/GitRepos/emoji-mart/node_modules/babel-core/lib/transformation/file/options/option-manager.js:267:20)
at OptionManager.init (/Users/.../Documents/GitRepos/emoji-mart/node_modules/babel-core/lib/transformation/file/options/option-manager.js:465:10)
at File.initOptions (/Users/.../Documents/GitRepos/emoji-mart/node_modules/babel-core/lib/transformation/file/index.js:194:75)
at new File (/Users/.../Documents/GitRepos/emoji-mart/node_modules/babel-core/lib/transformation/file/index.js:123:22)
at Pipeline.transform (/Users/../Documents/GitRepos/emoji-mart/node_modules/babel-core/lib/transformation/pipeline.js:45:16)
at babel6 (/usr/local/lib/node_modules/parcel-bundler/src/transforms/babel/babel6.js:26:19)
```
Even the documentation setup here http://babeljs.io/en/setup#installation
Says to instal babel-preset-env
and set it up in .babelrc
as
"preset": ["env"]
Which is what gave me error, so it should be
"preset": ["@babel/env"]
Maybe it's just naming convention.
> Yes, I know that. My point is that implementing block-scoped variables in ES5 is not technically possible.
The variables you put in your ES6 code are scoped according to the blocks in your ES6 code, when the resulting program is executed. Thus, babel implements the block-scoping.
The generated code doesn't use block-scoped variables -- they're not part of ES5. The same goes for literally everything an ES6->ES5 compiler implements. It's why you have a transpiler.
That said, transpilers rely on static analysis, and javascript is dynamic enough that you can break its assumptions if you want to. In this case:
let x = 4; { let x = 5; } let code = "_x"; eval(code);
But that's mostly because es6 eval isn't implemented via babel [with good reason, though it wouldn't be impossible], and not anything particular to block-scoping.
> Do you have a snippet that Babel will turn into a closure?
Yeah I've started using the same pattern for the same reason of avoiding the constructor boilerplate. Although I think you'd still need to destruct in the render if you don't want this.props
or this.state
littered throughout JSX wouldn't you?
To add to your addition to the seconded statement... :D
Using class properties with arrow functions will avoid the need to bind functions in the constructor as well:
// with class properties class Video extends React.Component { state = { loopsRemaining: this.props.maxLoops }
decrement = () => { this.setState((prevState) => ({ loopsRemaining: prevState.loopsRemaining - 1 })) } }
// without class properties class Video extends React.Component { constructor(props) { super(props)
this.state = { loopsRemaining: this.props.maxLoops, }
this.decrement = this.decrement.bind(this) }
decrement() { this.setState((prevState) => ({ loopsRemaining: prevState.loopsRemaining - 1 })) } }
That's correct, although if you are not afraid of a build step, there's a Babel transform or <code>async-to-gen</code> that will allow you to transform async
/await
into ES2015-compatible code, which means you will be able to run it on Node 6.
oh if you want to know what Babel transpiles to, you can stick your code in here and it will throw out fully backwards compliant javascript. The reason I asked the question is that I was under the impression that you need to use a node server or something to take full advantage of babel and webpack, or else the user will only be served (potentially incompatible) ES6 javascript. IIRC You use the npm build command in the create-react-app directory to convert the project to a production ready state, that's if what you have here isn't this already. Very interesting work!
A lot of people are using all the newest features of JS and then using something like babel to transpile it to ES5 code. If you don't want to use a transpiler, you can look at this chart to see which browsers support individual features. If you need to support <= IE8, you will probably need to use a transpiler though.
It's not about opinions at all.
This preset gives you the state of ecmascript 2017
http://babeljs.io/docs/plugins/preset-es2017/
This preset gives you all drafts from stage-0
http://babeljs.io/docs/plugins/preset-stage-0/
These are curated after the actual proposals. TS doesn't do that, and as a direct result it can't even understand the kind of javascript that is out in the real world.
I'm interested in knowing what tooling doesn't support JSX by now. A lot of time and effort went into getting Babel everywhere and anywhere that supports Babel supports JSX (as well as ES2015 and Flow).
Speaking of which if you want a well integrated solution with templating and strong-typing, Babel+Flow+React works really well.
I don't understand what problem this solves. An async function is just a function that returns a promise. You can export it the same way as any other function, then import and use it like you would use any promise-returning function.
I pasted the 'current situation' example from the README into the babel playground, added export
in front of it, and it seems to handle it just fine.
Am I missing something?
I tried to use this package but get an error when run webpack:
ERROR in ./~/react-gmaps/dist/index.js Module build failed: ReferenceError: [BABEL] .../node_modules/react-gmaps/dist/index.js: Using removed Babel 5 option: .../node_modules/react-gmaps/.babelrc.stage - Check out the corresponding stage-x presets http://babeljs.io/docs/plugins/#presets at Logger.error (.../node_modules/babel-core/lib/transformation/file/logger.js:39:11) at OptionManager.mergeOptions (.../node_modules/babel-core/lib/transformation/file/options/option-manager.js:265:20) at OptionManager.addConfig (.../node_modules/babel-core/lib/transformation/file/options/option-manager.js:207:10) at OptionManager.findConfigs (.../node_modules/babel-core/lib/transformation/file/options/option-manager.js:413:16) at OptionManager.init (.../node_modules/babel-core/lib/transformation/file/options/option-manager.js:461:12) at File.initOptions (.../node_modules/babel-core/lib/transformation/file/index.js:194:75) at new File (.../node_modules/babel-core/lib/transformation/file/index.js:123:22) at Pipeline.transform (.../node_modules/babel-core/lib/transformation/pipeline.js:45:16) at transpile (.../node_modules/babel-loader/index.js:14:22) at Object.module.exports (.../node_modules/babel-loader/index.js:88:12) @ ./src/components/list-page.js 22:18-40
It's new syntax that's supported by many (but not all) modern browsers that your average person might use to view your site. MDN is always a great source, and has more information on it here
There are a few tools that can take code written using the new syntax that's come out in the last year or two and re-write it into what you're used to seeing (and therefore what older browsers will support). Babel is among the more popular options, though how you use it will depend on what other tools you might be using (such as grunt or gulp) or if you're not using any others at all.
> That's fine, not every library is for everyone. It sounds like React just isn't for you.
Don't be silly. React is still the best thing out there. This is just a tread about its cons. I don't like using spaces instead of tabs and a bunch of other code, design, and library features throughout many languages and tools, but I get over my personal preferences to get the job done.
> The point is that their not choosing how you combine functionality.
I get that, but there's such a thing as a defacto standard. Now that features and addons (first or third party) are moving toward higher-order components instead of mixins, there are some fundamental incompatibilities that haven't been solved yet. If I was writing every third party feature I used, I would get to choose what to do, but I'm not doing that. It's unreasonable to do so.
> If your point is that you'd be foolish not to have a build system
No, I had thought that, starting with 0.13, it was required (whenever they switched from the jsx transformer to babel) and they had stopped making with-addons builds. And while the in-browser jsx transformer is now fully discontinued, you don't technically have to use jsx to use react, and you could include one of the with-addons builds instead.
SystemJS does a lot of what I'd like.
A big problem right now is that Babel has discontinued babel-browser which seems to throw a wrench in it as being a plausible option
class RecipeList extends React.Component {
recipeClicked(recipe_id) { this.props.dispatch(selectRecipe(recipe_id)); }
render() { var rows = this.props.recipes.map((recipe, i) => ( <RecipeItem recipe={recipe} key={i} onClick={::this.recipeClicked}/> ));
// More unimportant render code here
Which version of babel are you using? The latest version of babel (babel 6+) requires you to also install some plug-ins. If, for example, you want to use babel to write ES2015 code you will need to install the ES2015 preset:
npm install babel-preset-es2015
As described at: http://babeljs.io/docs/plugins/preset-es2015/
You should also create a .babelrc file in your projects root folder. My .babelrc file (for es2015) looks like:
{ "presets": [ "es2015" ] }
The .babelrc description can be found at http://babeljs.io/docs/usage/babelrc/
Babel always looks for a configuration file (e.g. .babelrc
) relative to the file you want to compile. Possibly helpful – the CLI command babel-doctor
: http://babeljs.io/blog/2015/11/03/babel-doctor/
You don't invoke babel.transform directly, it's used as part of a build process or require hook. If you're writing for node, the easiest way to use it is via require hook:
npm install -g babel-register
Then in your app's entry point:
require("babel-register");
From there, everything required in will be transformed by babel. If you need to integrate into a build process, the setup page is actually pretty good. If you can't figure it out from those docs, look for a project skeleton/starter/bootstrap/boilerplate that uses babel and copy that.
You are, however, not finished! Babel has taken the pain in the ass route that's popular in node and ships without defaults! You want the es2015 behavior. Once you follow that setup you'll be good to go.
The good news is that you only really have to do it once and then copy/paste the setup between all your projects. Still annoying.
Use Babel, which will transpile async/await code (if you use stage 0) into regenerator code: See: http://babeljs.io/repl/#?experimental=true&evaluate=true&loose=false&spec=false&code=const%20timeout%20%3D%20(ms%20%3D%201000)%20%3D%3E%0A%20%20new%20Promise(resolve%20%3D%3E%20%7B%0A%20%20%20%20setTimeout(resolve%2C%20ms%2C%20'Hel...
CLI commands: http://babeljs.io/docs/usage/cli/
presets go in a .babelrc file in the root directory of your project (same place as package.json). Here is an example: http://babeljs.io/docs/plugins/preset-es2015/
Typescript is a very slightly extended ES6. If you write your type definitions/aliases (type
, interface
, enum
keywords) in .d.ts files, I'm pretty sure you could run the rest of your .ts files through Babel and get out the code you expect since Babel knows to drop TS-style type annotations so it can be used with flowtype. I don't use TS that heavily so there could be some syntax/keyword additions that I'm forgetting but MS really wants it to be just a type system on top of ES6.
I think it's just a matter of getting used to it. Aesthetically, they're less ugly than the more verbose function (a) { return function (b) { return a + b; }}
.
If your argument would be that you're supposed to have newlines and indentations, then it's worth noting that you can do the same with fat arrow functions. Take a look.
The ES6 spec was finalized a few months ago, and support for various features is being gradually added to browsers. You can check out the compatibility in current browsers here. let
and const
can be used in Chrome in strict mode. However, most devs that want to write ES6 (or even newer ES7 proposals) code will be using a transpiler, like Babel.
TCO isn't implemented by any engine yet. It also only works for functions which follow the pattern and they also must be in strict mode. Your function doesn't meet either criteria.
However, rearranging it slightly does fix the problem.
function add(n, acc = 0) { 'use strict'; // we won't need this in a class or module if (n === 0) { return acc; } return add(n - 1, acc + n); } console.log(add(5)); // 15
Same thing without ruining the function's signature (the "acc" parameter doesn't belong there):
function add(n) { 'use strict'; function _add(n, acc) { if (n === 0) { return acc; } return _add(n - 1, acc + n); } return _add(n, 0); } console.log(add(5));
Try it in Babel's REPL. You'll see that it will be transformed into a loop.
Recursion is great for recursive things like trees. For simple repeat-until scenarios, you're better off with a simple loop.
http://www.2ality.com/2015/06/tail-call-optimization.html
http://babeljs.io/repl/
That's legal in JavaScript:
let thing = 'world';
{ let thing = 'earth'; console.log('hello', thing); }
console.log('hello', thing); http://babeljs.io/repl/#?experimental=true&evaluate=true&loose=false&spec=false&code=let%20thing%20%3D%20'world'%3B%0A%0A%7B%0A%20%20let%20thing%20%3D%20'earth'%3B%0A%20%20console.log('hello'%2C%20thing)%3B%0A%7D%0A%0Aconsole.log('...
Okay. I love Node, and while it has a number of positives the primary one is that it's JS and you only need one language on the client & server. If you don't care about front-end development, there are plenty of valid choices for server side languages. I'm not saying don't go with Node, but take a look at Ruby, Go, and Python at least. They're all perfectly valid choices so my suggestion, if you're not in a real rush, would be to build something small with each one. A 1 week-1 month project.
If you do levitate towards Node, or even if you're just building a sample project, take a look at babel which allows you to write ES6+ code (which is much nicer in many ways than normal JS)
This was a simple example to illustrate the concept.
http://babeljs.io/blog/2015/05/14/function-bind/
> document.querySelectorAll("div.myClass")::find("p")::html("hahaha");
You can also use it for method extraction:
const qs = ::document.querySelector;
Instead of:
const qs = document.querySelector.bind(document);
The online repl for babel doesn't seem to transpile the array methods, I wonder why?
I quite like this pattern - I did something similar in my .tap
library (https://www.npmjs.com/package/tap-chain + blog post http://hughfdjackson.com/javascript/tapping-into-the-method-chain/). I think there's something genuinely useful in being able to add in functions in a chain - it can help readability.
Have you seen http://babeljs.io/blog/2015/05/14/function-bind/, which solves the same problem with a proposed extension to the language?
By default, Babel puts all of the helper functions it needs right at the top of each file. That means if you're bundling your code up for a browser, you're going to end up with a ton of duplication. Babel provides two ways to avoid that. runtime or external helpers.
Babel does add more code just because it's necessary to implement some features, but more of the very repetitive chunks of code are placed in helpers.
Yeah it's annoying as it requires you to have inspected the output to even know it does this.
Specifically, the way I do it is add this to my browserify options:
transform: [["babelify", { "extensions": [".es6"] // I use .es6 so I'm not transpiling every single file "externalHelpers": true, "loose": "all" // I've been using this to cut filesize further, but don't use before reading http://babeljs.io/docs/advanced/loose/ }]]
You might like virtual methods (a proposed ES7+ feature):
http://babeljs.io/blog/2015/05/14/function-bind/
function randomItem() { return this[this.length * Math.random() | 0]; } function last() { return this[this.length - 1]; } let someArray = [...'abc']; console.log(someArray::randomItem()); // a, b, or c console.log(someArray::last()); // c
It's like extending built-ins without the mess.
Well, in this case, a virtual method wouldn't make any sense since ES6 got the spread operator. You can just write a.push(...b)
.
i would suggest learning ES2015 (ES6).
Basically: When you know ES6, you can always transpile it to ES5 using babel.io
So yes, you can use ES6 in Production right now thanks to transpilers (and a lot of sites already do so)
Interestingly there's a stage 0 ES7 proposal for a new function binding syntax using :: such that events within a class could have an instance method passed in as the callback.
E.g.:
<div onClick={{::this.handleMyClick}}></div>
would work. babel writeup
> Are the browsers the ones who determines what goes and what does not?
Pretty much. Each browser has an interpreter that will support a certain amount. It's like having lots and lots of compilers to support.
There are things like babel that allow you to target the latest standards but I haven't used it yet.
HackerNews discussion about ECMAscript 2015 might provide some insight.
I haven't seen any changelogs or anything official, but they said previously that 14 would have some new optimizations
https://github.com/facebook/react/labels/Component%3A%20Optimizing%20Compiler
Babel's had support for some of the new stuff since 5.0
http://babeljs.io/blog/2015/03/31/5.0.0/#react-optimisations
You're right about CoffeeScript; things are a lot harder to read, and it's very difficult to reason about code, especially with its lack of decent variable shadowing. Hence why I stopped writing code in CoffeeScript, especially with the advent of ECMAScript 6 and Babel. It has everything CoffeeScript has, and allows for variable shadowing. Sure, it's of the opinion that shadowing is bad, but in case you mistakenly name a local variable the same as a global variable, at least you are not toast, unlike in CoffeeScript (albeit, the likelihood of accidentally shadowing a variable would be minimized if you used a code linting tool).
And I might ask, how is Jade harder to read? I've notice a lot of the times when my DOM layout in HTML starts to become incredibly complicated, I sometimes lose track of which closing tag belongs to which opening tag. Jade fixes the problem by just eliminating the need for a closing tag altogether.
From the docs:
> Technical details > > The runtime optional transformer does three things: > > * Automatically requires babel-runtime/regenerator when you use generators/async functions. > * Automatically requires babel-runtime/core-js and maps ES6 static methods and built-ins. > * Removes the inline babel helpers and uses the module babel-runtime/helpers instead.
Just to clarify for others: babel (and traceur) can do the async/await right now. TypeScript doesn't support it yet, but should be getting it in 1.6
https://github.com/Microsoft/TypeScript/wiki/Roadmap
Enabling in babel:
http://babeljs.io/docs/usage/experimental/
Enabling in traceur:
https://github.com/google/traceur-compiler/wiki/LanguageFeatures#async-functions-experimental
Generators are the easiest approach, and lets you re-use native javascript structures.
If you want to use them on the client side you will have to use babel with regenerator and take a look at co.
Basically what co does it accepts your promises (via the yield keyword) and replaces it with the result of the 'then' value. If the promise throws a 'catch' then co will throw the error in suspended stack.
Unfortunately neither Babel nor the JSX Compiler (with Harmony transformations) handles your example correctly:
var foofar = function (foo, /: number/bar /: string/) { return foo.toString() + bar; };
and
let foofar = function(foo/: number/, bar) { return foo.toString() + bar; }
respectively. Let's hope those can be fixed with relatively little effort (at least Esprima handles block comments quite nicely).
That said, type inference may help you there, and for a single-argument fat-arrow function Babel does work.
edit: link formatting