Hacker Newsnew | past | comments | ask | show | jobs | submitlogin

This is basically my frustration with the whole trend toward smaller pieces over big monoliths. I don't need a best-in-class every tiny little thing; I just want reasonable tools I can expect to work together well.


The JS build system ecosystem could definitely use some help along the whole "reasonable tools I can expect to work together well" front. I swear, 30% of my time is spent fighting the build systems and their plugins that hate each other.

EDIT: to add, I think the TS team has done such a bangup job on Typescript that I would love it if they could create a build system as well. Some things that would be nice to have:

* Build-time loading of static resources (.json into js objects, html into strings, etc.)

* File watching and processing for more than just .ts/.js files

* Optimization. Not just tree-shaking and minification, but you could actually get a little more advanced due to the static types and ES6 modules.

* Environment-dependent compilation (compile these files in this way, inserting these static values where ENV variables are used in the source, etc.)

* Target capabilities analysis (ie. for this set of browsers and versions, what is the Lowest Common Denominator for browser capabilities, and ergo, what babel transforms and browser shims should be included?)

* Integrated contracts testing with test elision (ie. run these tests in these (karma? selenium?) environments and if failing, throw a compilation error or warning, and if passing, strip the tests from the compiled source).

* Source packaging (gzipping, etc.), and deployment plugins (ie. deploy compiled assets to S3, package for NPM, etc.).

All of these are pain points in Typescript projects, and all of them touch TS projects in such a way that it makes it even more painful in existing build systems.


Get rid of Gulp and half your problems vanish, in my experience.

Gulp is the source of so much pain for people and yet so much of the ecosystem keeps suggesting that more gulp is the answer to their gulp problems.


I find webpack to be quite a 'holistic' solution I got pretty much everything out of the box or with minimal googling.

I agree though over-fragmentation is a huge problem for JS, we need the big players (either foundations or companies) to put their weight behind one or two solutions and just get on with it :-)


Google sort of already has one, and has for a long time.

Now that their Closure Compiler supports ES6 quite well, I've had a decent amount of success writing my app using straightforward ES6 and referencing the extensive Closure Library for functionality I would've previously pulled in npm packages for.

And the nice thing is that the whole library is written in such a way that all of the compiler's advanced optimizations and branch pruning, and dead code elimination work nicely on it so your compiled JS ends up containing only the code you need, and none of the code your don't need. If you want to use JSX in React projects, you can still zip the code through Babel or Typescript before feeding it to Closure.

It certainly won't work for every project, but it's one way to write modern JS without having to deal with the node/npm ecosystem too much...at least until things settle down a bit.


As someone who uses both stacks regularly, on different projects:

More people should consider using Angular 2 for some kinds of projects.

Now, I have professional projects in both Angular 2 and React/Redux ecosystems, and frankly I enjoy using React a lot more in projects where I can focus on the frontend. I moved some projects to isomorphic React (ie, render using React on backend) in Node.js and Rails apps, and thoroughly enjoyed that experience. I keep on top of Elm and omnext and so forth, and I have personal projects built with those, and I do experiments with completely unidirectional dataflow in Elm using an Elixir backend ...

However.

Twice recently, when I had a full-stack project with a relatively short timeline, I made a conscious decision to keep the frontend from getting too uppity and absorbing too much of my mental energy.

In those cases, I used Angular 2, generated from the ng2 CLI.

It's worked pretty well. Well, the first one had some dependency issues from time to time, which is understandable because of the beta -> rc1 -> rcX -> Angular2 release process that was happening.

Why ng2? Well ... not because I'm convinced that it's "the best" in any particular dimension. Its special sauce is supposed to be Zones, which make knowing when side-effects have occurred less something that we have to track and manage manually, but there's other work in that problem space!

I used it because it's an opinionated stack that already has the important pieces in place (router, DI, build/minify, type checking, components), and more importantly, because I can be fairly confident that another dev could get up to speed quickly due to decent docs and guides ... and it's less easy for someone to "paint themselves into a corner" by doing things really wrong.


Indeed. This is actually the point of DHH's much maligned "Rails is Omakase" article.


Why was that article maligned? Seemed pretty solid to me.


This was exactly my thought and I was so glad when I saw this talk[1] address it.

On a side note, I had submitted this to HN but somehow my submissions are visible only to me and doesn't appear when I checked the newest tab after logging out.

[1]: https://youtu.be/OcUzuQ_31co?t=34m5s (the relevant part in the EmberCamp keynote by Yehuda Katz and Tom Dale)


The other nice thing is that bigger monoliths often (not always) make opinionated decisions. This is usually a good thing.

In my work I deal with a legacy system with an ExtJS GUI. The two ways that ExtJS fails to be opinionated are perpetual pain points for me and my team! One is: every component has a million optional configurations, not to mention all of the events you can listen on. For the most part this is great, but there was never any systematic separation for "here are the absolutely-required things, there are the things which are optional but must be configured together, and over yonder are the things which are totally optional." Then you could require that the required-configs were, say, statically known when you were deriving a concrete class from an abstract one. Instead ExtJS wanted to accept doing all of this stuff at runtime, so because it failed to take a strong stand on its required configs, when you inevitably forget to configure some of them, you get an error puked out from somewhere very deep in the framework, where the call-stack and error messages show nothing related to your class at all, just "TypeError: SomethingYouNeverCaredAbout is null." It would have all been saved if `Ext.define` looked for some "abstractProperties" array, and made sure that every new `Ext.define` either set abstract properties or propagated them, finally checking that whichever ones are still present in the `Ext.create` call are filled in. Simple descriptive error messages are then available when you forget a required config.

The other way ExtJS violates the principle is... God help you if you ever have to figure out how the underlying form submits and grid reloads actually work. You'd think with something so critical, it would be clear... it's not.

"My grid refreshes automatically when the underlying store loads. Great! The underlying store can be loaded or reloaded with the .load() method, which accepts a callback. Wonderful!" It starts off very promising. But then you dig deeper and find that the .load() method packages the params and the callback into some object and then calls some .read() method which doesn't exist on the class you're looking at (inheritance! go up to the superclass!). Once you've traced that down the actual .read() bounces to some .doAction() which repackages these into some `Operation{type: 'readAction'}` or whatever... and then this gets handed up to some Proxy object which then stores it in some meaningless array, because of course these things get batched together... if you're not sick yet you find out that the Proxy needs to push the stuff to some Reader and Writer, just in case you wanted to communicate with the server via XML instead of JSON, or wanted to store the resulting array under a key not named 'results'. But you don't want to do any of this because the query finally gets XMLHttpRequested somehow (God knows how) to some `router.php` which we stole from IBM[1] a long time ago, which finally took a stand, "I will accept these two inputs, send them to the backend this way, and emit one of two corresponding outputs." (Except for that then you open that and it contains code for some sort of `doAroundCalls` because apparently the original author[2] decided to vacillate on what they'd accept, trying to also allow you to bookend one RPC service with two other RPC services, which never happens because Ext.JS never does it!) It gets a little more complicated because there is one rather significant bug which nobody has ever fixed in IBM's router.php, which is that formHandler services get the $_POST params (an associative array) as their first argument whereas XMLHttpRequests get the `json_decode($HTTP_RAW_POST_DATA)` (a StdClass object) as their first argument, so there's no interoperability on the frontend or the backend. Happy debugging, you. It's all one big mess.

You begin to wish ExtJS had done what they eventually ended up doing[3], and just told people, "here is how you're going to do this thing. We have a Java router, a PHP router, here is how you set up your backend on these platforms..." That would have been very bold since ExtJS was originally just a set of helper classes to help automate GUI stuff with YUI, so I understand that the history made them feel a bit shaky about doing that, but... I really don't value that there's 10 layers of abstraction just in case I want to transmit the same stuff over-the-wire in XML rather than JSON.

If any developers of toolkits are reading this: please, please consider very firm protocols: "here is what you're going to send me, and here's what I'm going to respond with." Because, half of programming anyways is translating outputs to inputs; we all know how to write the adapters which connect the two. Please make your life really simple by not supporting a million different ways to do the thing. I promise, you're also making my life simple because even though I will grumble about spending a half-day writing that adapter, I will then save untold dozens of half-days because the overall architecture is modularized, "oh there's a bug in the adapter, my bad, but it's only a 5 minute fix." My communication with you must pass through a gateway; please limit me to only a very small choice of inputs which you are going to tolerate, and break very loudly at the gateway when I forget some of those. It's far better than having a nigh-undebuggable error somewhere in the middle of your framework code that I never want to read.

[1] http://www.ibm.com/developerworks/library/wa-aj-streamline/

[2] This could be Dan Dallala of Microsoft? His Gist appears to be an older version of the file and is one of the top results when googling strings out of the source file...

[3] It's not complete as to how the backend should be set up, but at least there is now a documented interface for this Ext.Direct communication. https://docs.sencha.com/extjs/6.0.1/guides/backend_connector...




Guidelines | FAQ | Lists | API | Security | Legal | Apply to YC | Contact

Search: