Potentially removing brunch from the Phoenix new template generator

Not necessarily - often it’s just a case that people want to see their favorite tool supported, regardless of how appropriate that tool may be. In this particular case it just happened that an approach using smaller building blocks ended up being more effective under the circumstances.

The issue is that such “convenience” comes with an opportunity cost - a cost that users of the Phoenix framework shouldn’t underestimate nor take for granted. Supporting only one single approach/tool is ultimately more effective; support of the other tools in the wild should really be left to the “evangelists” of those tools. How serious can you take anyone who would reject Phoenix because brunch is its default asset management tool?

[quote=“chrismccord, post:13, topic:2454”]
My main concern with the proposed approach is you end up accidentally rebuilding brunch, but worse, with a hodgepodge of dependent scripts.[/quote]

I’m past the “remove brunch from Phoenix” discussion - there is no need to change it, especially given that it is so easy to replace if and when the need arises.

However in general this particular argument seems to favor monolithic tools over pipelined tools. I personally find the whole “batteries included” mindset a bit oversold, a holdover from commercial products where companies are trying to compete on the sheer number of features to the point that you are accepting a fair bit of bloat. Given that OSS is notorious for not settling on a standard, focusing on (quick to learn) single-responsibility tools that combine well with one another seems to be a reasonable approach, especially when you should be able to replace any part that is no longer pulling its weight (rather than replacing your entire build process because your monolithic tool is starting to show a key weakness in one particular area). Yes, it is absolutely possible to create “a hodgepodge of dependent scripts” but ultimately no tool (or set of tools) is a substitute for thinking.

:thumbsup:

I think it is clear that the utility of npm scripts is often overlooked and I guess it is my overly idealistic hope that having people focus on “(quick to learn) single-responsibility tools that combine well with one another” could be a way to further increase the quality of tooling - hopefully to make the node/JS world just a little less painful.

Favorite tool is a term that’s hard to apply to JS build tools :slight_smile: On a serious note I think there is an argument to be made for supporting a few popular choices. Doesn’t have to be directly by phoenix though.

That’s why I think external package is the most realistic option :slight_smile:

1 Like

I simply didn’t see it happen, neither in my personal project, nor at the professional one. Though in both cases, the amount of javascript used is very small, so no advance usage there.

I’m certainly not saying it doesn’t happen, but I see a lot of general statements without more concrete claims. Perhaps a description of use-case where brunch doesn’t suffice, and it’s not trivial to switch to something else might shed some light?

1 Like

Ah, I’ve described many of those in a few topics recently. :slight_smile:

  • It has no ability to process images such as minifying or progressifying images (unable to find plugins nor would they fit in its work-flow, due to 1-N inputs and 1-M outputs, multiple images can be combined into a single one with a generated css describing it, and consequently they could also be split up, in addition to processing the images to shrink them, make webp variants of them, etc…).
  • Its webcomponents concatenation and process abilities are entirely absent (unable to find plugins nor would they fit in its work-flow, due to 1-N inputs and 1-M outputs, mayn webcomponent files generate one html and one js per ‘output’ of however many output definitions there are).
  • There is no way to force a synchronized call to run concurrently with other things (OhGodTheSlowElmPlugin!)
  • As well as missing about 20 plugins that I’ve needed recently (some I’ve wrote, some I’ve included other build systems in for)
  • And it just generally failing on any kind of processing that involves anything more complex than a single file input to a single file output, it is not made for it as it expects to do all of the, say, javascript processing and combining itself.

Among others.

A recent specific case was adding in more webcomponent libraries, which are html based. I needed to concat the html files from a given tree in a specific order, split it it into its html/javascript/css parts, run the css into the brunch css path, the javascript into the javascript path, and the html needed to go to a further splitting and minification path. Impossible with brunch alone (even with scripts, it has no way to be given multiple outputs for a single input unless you write the output to a directory it watches, which at least on windows causes a race condition where brunch tries to reprocess assets again while the file is still being synched to the disk, thus writing out a blank section for that file, thus making me have to re-save the file yet-again for it to grab it).

Compare this to the unix philosphy of just piping programs (as in an npm run script): node-sass path/to/input/scss | postcss --use autoprefixer | cleancss > priv/static/css/app.css
Of which you can split and recombine and whatever you want, including calling other tasks so you can break it up like functions as much as you want (or write things into a myscript.js file or so and calling/piping into a node myscript.js call as even more examples). The above webcomponent horror was trivially handled by the npm part as I could do exactly what needed to be done there.

So yes, entirely replacing brunch by rewriting its large 443 line brunch-config.js file was gnarly, tried to port it to gulp, did not get any shorter but it certainly cleaned things up, then ported it to just raw npm calls this morning and ended up at less than 60 lines, each with only 1-6 calls in them (and whoa fast, gulp had the same elm sync call issue as brunch so it was not any faster than brunch).

1 Like

As someone who does care about the front end, i.e. anytime when I am working in a project with as much front end code as backend code. Using npm scripts would be preferable. it’s so easy to wrap any glup/grunt/other scripts in npm scripts. npm scripts are the common denominator in the node ecosystem.

1 Like

If you mean that we should be invoking a “npm run” in config/dev.exs instead of brunch directly, yes, I agree. We do even generate the proper scripts in your package.json but last time we checked they were not working on Windows. :frowning: Hence the direct brunch call.

Could someone check if the following watcher works on Windows today?

npm: [“run”, “watch”, cd: Path.expand(“…/”, DIR)]

2 Likes

I would be horrified if I found something was meddling with the quality of my images after I had already processed them myself :lol:

1 Like

Do you have a reference barebones Phoenix project for me to try this command on?

Works fine on Windows 10 (stock project, brunch, edited files changed, etc…). :slight_smile:

It does not, they are run through svg optimizers, png compressors, etc… It is lossless unless you use jpeg, which is lossy anyway, it just runs the images through absolute max compression, which can take some time to run but it still renders just as fast and on average compresses my images from between 20-90% off the file size. Well worth it.

And apparently it is Thanksgiving this week so my weekend ended up having to make food and deal with family, so I had about an hour of computer time total. Will make when I get time. ^.^

And later that same day after a few restarts it suddenly throws:

** (stop) :eacces
    erlang.erl:2057: :erlang.open_port({:spawn_executable, 'c:/Program Files/nodejs/npm.cmd'}, [{:cd, "c:/Users/<user>/Projects/my_server"}, :stderr_to_stdout, :use_stdio, :exit_status, :binary, :hide, {:args, ["run", "watch"]}])
    (elixir) lib/system.ex:550: System.cmd/3
    (phoenix) lib/phoenix/endpoint/watcher.ex:15: Phoenix.Endpoint.Watcher.watch/3
    (elixir) lib/task/supervised.ex:94: Task.Supervised.do_apply/2
    (stdlib) proc_lib.erl:247: :proc_lib.init_p_do_apply/3
Function: &Phoenix.Endpoint.Watcher.watch/3
    Args: ["npm", ["run", "watch"], [cd: "c:/Users/<user>/Projects/my_server"]]

It most certainly has access to "c:/Users/<user>/Projects/my_server", it even has write at 'c:/Program Files/nodejs/npm.cmd' as it is admin right now…
Have I mentioned how much I hate windows… >.<

1 Like

100% in agreement with you Chris. Has anyone who’s worked on ElixirScript done any investigation of bridging the Elixir < = > JS gap or is the technology still too immature? Just curious.

1 Like

As a user of phoenix I would like the phoenix developers to focus on elixir code and not javascript build tools.

As a front end developer I know there are so many different ways to hook in the javascript and so many different ways to build UI in browsers and so please don’t make phoenix have this complexity.

Instead of complex javascript/node integration Use something simple and reliable with documentation and make it easy to remove - something like brunch.

Then I can rip it out and replace it with webpack or as the gentleman here has done ‘npm tasks’.

7 Likes

My 10c here. For context I am a front end developer, there are around 50 other FE devs at my company, and we work on several farly complex application platforms. I work on top of a C# codebase, but I don’t think the the backend is particularly relevant to this discussion - we face the same set of issues that having an Elixir/Phoenix based codebase would have as regards frontend.

I guess every non-junior dev at our company, and almost every non-junior FE dev I know has seen the “just use use NPM scripts” article referenced in the first post. And everyone reads it, thinks “isn’t that a great idea! Why am I using webpack/gulp/etc” and implements it in a few small projects, and it works great. Then you try to use it on a non-trivial project, and you start to hit issues. The NPM scripts approcach does not scale, it is fragile, and it gets complex really quickly. It seems a really simple solution, because it is. In the same way as [eg] awk or sed or ed are.

All of the current solutions are substandard in some way - WebPack get complex fast, Brunch just builds stuff, Gulp is Gulp (hello enormous config files). But Brunch is simple enough to do any common task with almost zero config - if I want to add, say, Scss support, it is a single line - no other FE build system can currently provide that. Webpack is arguably better for anything moderately complex (eg I need to unit test everything, so I’ve got to go there), but then the setup is still horribly complex. NPM is too low level; it gets more and more complex until the point that you build a build system. If you have 60 lines of NPM script, there’s gonna be an issue giving that to someone else. As an example - how do glue all of these ES6 modules together? I personally know how to do it, but then, if I write an NPM script that lints, transpiles then concatenates, it’s going to be utter gibberish. If I do that with a taskrunner or build tool, it will not be.

I think I’ve been spoilt a bit by Elixir (and Rust, and Go to some extent), where I have a language with a build system and test framework and built in documentation, and it all works somewhat seamlessly; there are simple answers that provide solutions that work in the majority of cases. There is one way to do things, and it works, out-of-the-box.

With JS, it’s a massive mess. You need some kind of build system that is simple, allows for flexibility, and isn’t complex to introduce that flexibility. It’s needs to be high-level. NPM scripts are simple (in the same way bash scripts are simple), and they allow flexibility if you type out the magic utterances, but adding/modifying functionality is painful and means modifying things at root level; it is in no way high level.

Brunch is pretty good - it’s pretty fast, it’s very easy to understand, it’s had a very long time for issues to be known and understood. Critically, it’s really easy to replace; it’s not like the asset pipeline, it’s not baked in. A canonical set of articles on how to replace with NPM Scripts/Webpack/Gulp/taskrunner-du-jour would possibly be the most useful thing that could exist re this issue.

13 Likes

Would be nice to have a mix/cmake/cargo/findlib/etc…/etc…/etc… system for building assets. ^.^

Too many already exist though, blehg.

1 Like

I stumbled on that same article a while back and took the chance to use just npm with a new project I was starting at the time. Back then, I was a complete beginner, and I personally found setting up npm scripts easier than incorporating a dedicated builder, simply because there was no “magic”.

These days however, I tend to use a builder. Which one depends on what I’m doing. A do a lot of work with Meteor, so lean on that, although have used Brunch and Webpack with JS projects as well as Phoenix projects. I can’t say I’m ever had a problem, other than Webpack being incomprehensible! :slight_smile:

1 Like

Just want to add my 2-cents: I’m primarily a JS dev.

Did Grunt, Gulp, Webpack, Brunch. Hated all of those. I hate setting up build scripts. It is buggy, has many edge cases, inconsistencies between machines and OS, don’t play well to one another. Tried npm scripts, same thing, and actually get complicated real quick, then people put packages such as “better-npm” and bunch of other nonsense.

I really really appreciate the decision made by the Phoenix team, which to just stick with Brunch that just works. Simple, KISS, and I just want to get my work done. If I need something better later, I can just always remove it.

5 Likes

I have been using “npm” as my build tool for some time now. All one needs to do is write some custom build code (just a few lines) and use the numerous npm package to do whatever one wants with the source files. I create css bundles, js bundles, use SCSS, Rollupjs etc. with no problem. I created a recipe once and use it in every new project I start.

I am not going back to gulp etc. NPM is much simpler and more powerful. And far fewer problems with broken dependencies in the build system.

1 Like

Ok, so it seems like the brunch project is dead at this point?

Many of their libraries (at least the ones we’re using) are not maintained at all, with few or no releases over the last half year, and it’s especially evident in the last 3 months.

E.g., on our production app, we’re using sass. To get that working we’ve had to pull the master branch to get it to compile. This is an issue everybody will experience if they use recent nodejs version, but there has been no release for a year.

I feel that a simple build tool with NPM scripts would be far the best solution for Phoenix. But at least switching to a well-maintained library like webpack would be much better. Brunch has been a painful experience for us, and I don’t think Phoenix should default new users to it.

9 Likes

As someone with a foot in both the front and back-end worlds, I found it easier to work with a webpack + Phoenix combo in the end. It just seems to work smoother with Sass, PostCSS, Vue.js, React, etc. I also use a lot of NPM scripts, all organized in package.json.

That said, it is pretty easy to swap out brunch for webpack, maybe a few minutes once you get used to it. Maybe a detailed tutorial in the formal Phoenix documentation might help people in that sense.

3 Likes

As somebody who works with a lot of front end devs but generally tries to stay out of the way, the two options I would strongly favor would be:

  1. The one with the fewest outside dependencies that won’t suffer from JS project of the week syndrome and keeps things simple (npm build)

  2. The one with the highest adoption that is clearly stable (webpack)

There is a part of me that really wants to favor the npm only solution but the pragmatic part of me says Phoenix should focus on Phoenix and defer to JS tooling rather than make JS decisions. From everything people tell me, Webpack is what the world of Node seems to be coalescing around.

For me, I use so little JS that I’ll vote for whatever y’all decide to include. The above is just my “sensible defaults” perspective.

6 Likes