OvermindDL1

OvermindDL1

I’m curious about peoples thoughts about this, especially of @chrismccord.

In my project I have brunch and 2 other javascript build systems as well as a dozen libraries I specifically call, it is… unwieldy.

I started looking at other popular javascript build systems recently (as shown by a past recent thread). Grunt was horrible, don’t touch it, Gulp is good, kind of like Brunch (it has watcher, reloaders, hot-reloaders, etc…), it is completely async (if the supporting libraries are, like brunch, which elm’s brunch plugin is not for one example), it is a bit more verbose but not overly so, however it is significantly more capable, looks like it can handle all the things that brunch cannot that I’ve needed. Webpack can kind of do the same things as gulp, though it takes significantly more code to do things except the most simple of cases, which ‘can’ be shorter than gulp, but not really, I’m not seeing the point in it.

However, I ran across an article: Use npm as a Build Tool - Keith Cirkel
I completely forgot about another build tool that comes with phoenix, npm itself!

With some simple npm packages I got watchers, reloaders, concurrent compiling, can use all the base packages that the 50-thousand gulp/webpack/brunch plugins use under the hood but directly, etc…

So I spent this morning disabling brunch just commented its like in my dev.exs file, it ‘works’, mostly (it has bugs that necessitate two-recompiles often), and rewriting everything I did in brunch and the other systems in just npm itself, following that article, the result is that it is shorter, compiles faster (mostly due to being able to run the stuff the other systems absolutely had to do synchronously but concurrently, and no multiple rebuilds), and I say it is more readable.

So… why not just use npm for the build system of the assets in Phoenix? Replace in the dev.exs template this:

node: ["node_modules/brunch/bin/brunch", "watch", "--stdin", cd: Path.expand("../", __DIR__)]

To become this:

node: ["npm", "run", "watch", cd: Path.expand("../", __DIR__)]

That will call the ‘watch’ task, which in my package.json (you can define tasks outside of the package.json in your own *.js files if you want too) is defined as:

    "watch": "parallelshell \"npm run watch:javascript\" \"'npm run watch:scss\" \"npm run watch:webcomponents\" \"npm run watch:elm\" \"npm run watch:bucklescript\" \"npm run watch:copy\"'",

And those all run concurrently, and inside those are build systems that also run concurrently. It is actually surprisingly nice. I think that I’ll run like this for a while and maybe entirely remove all the other build stuff here later.

And yes, it is *SO*FREAKING*NICE* that I do not have to double-save my files just to get brunch to notice an update (with 50 seconds in-between because the elm-brunch plugin sucks and freezes everything while it spends its 50 seconds to compile the elm stuff), and the important stuff (I.E. not the 50-second long elm compiles) are compiled about instantly so my iteration time just dropped like a rock in a vacuum high-gravity environment. ^.^

So yeah, with this change and with the recent symlink windows fix for phoenix (run as admin in dev mode…) iteration time has become fantastic again! ^.^

But yes, any thoughts as to removing brunch from the phoenix new template generator entirely and just using npm itself? It reduces dependencies, its faster, its shorter, and its less confusing then the odd brunch config (which though nice once you understand it, is definitely confusing at first).

Showing Posts 1 to 10

chrismccord

chrismccord

Creator of Phoenix

I’m not sure it’s enough to just run a bunch of parallel node process. Ie, what about final concatenation? Script precedence/ordering? Script dependencies? Different js/css bundles? module loaders? Etc? In general, if I could escape the js ecosystem entirely and not have to include any asset builder I would, but it is an unfortunate reality. I don’t think the proposed solution covers enough or would be extensible enough for folks.

peerreynders

peerreynders

An excellent article. I would also imagine that npm scripts would be a very effective way of communicating most of the information needed when somebody wants to use their favorite build tool instead - assuming that means they actually bothered to learn how to use it, rather than always relying on pre-digested configurations that are churned out by other applications.

Why I Left Gulp and Grunt for npm Scripts
Why npm Scripts?

chrismccord

chrismccord

Creator of Phoenix

This is already easily achievable today by swapping out a single line in your dev.ex :watcher configuration. For example, swapping brunch for webpack is maybe a 30s affair today.

peerreynders

peerreynders

I think that you simply can’t predict all or even most of the “extension scenarios” that people may want - cover the basics then there comes a point where they need to be responsible for customizing their own environment for their own needs - and at that point it is more important that the general information on the critical aspects of the build process are readily apparent so that it can be mapped over to the desired build tool.

I was thinking more along the lines of more fundamental details like expected/critical source and target file locations etc. I expect that right now some of this information could be buried in “the (default) way brunch works” - i.e. one would have to familiarize oneself first with brunch before employing one’s own build tool - I expect that npm scripts could expose that type of information in a more transparent way.

As it is, over the past two years I have been noticing a growing number of people declaring to have (re)discovered npm scripts either standalone or in combination with some higher level build tool (e.g. webpack).

OvermindDL1

OvermindDL1 OP

All described in the article I linked and npm handles fine. :slight_smile:

In parts:

Handled by the various things, like brunch uses something like browserify internally to do that, why not just use browserify straight? So I do, it handle concatenation, it uses babel to do transpiling, I can pass in my own files or even raw source into it without touching the file system, etc…

Also handled by browserify. Browserify itself did not exist when brunch was built, but it is basically a command-line and node library that does the same for javascript work. There are similar things for css (stylus), templates (vulcanize/crisper), webcomponents(polymer-build) , etc… (brunch’s webcomponent support is… extremely lacking, it is one of the two brunch plugins I have that require repeated recompiles because brunch does not know about them). Just call browserify straight (either the cli version or import it and use it from your npm scripts).

Again, browserify. :slight_smile:

Specify exactly what files you want in your browserify output files, spin up an instance per output file you have, pass in the files, globs, raw source that you want it to handle. :slight_smile:
Same with stylus for css, pass through a postcss or scss transpiler first or whatever you want too.

Browserify is also a module loader, in addition it will also auto-polyfill things that the browser does not support that you use (Object.assign for example), but only if you use them (don’t use them? it does not include them unless you override it), brunch does not, have to load your polyfills manually.

The npm method can handle anything that any other javascript build system can do (you can even call into build systems if you want, that is what I was originally doing, calling brunch watch from my npm run watch until I finished moving it over) and it is the most extensible method (unlike brunch, like holy-hell-it-is-limited), while still being more succinct than any other build system I’ve seen yet, just have to not be afraid of javascript scripts. ^.^

But yeah, this would reduce the npm dependencies downloaded, it is a more simple script structure (that can even call into a build system if anyone want, or just replace it with something else by changing/adding phoenix’ watcher). The reason I suggest it instead of brunch for the default scripts (could keep a new-brunch script or something if you want, or new-gulp or new-whatever) is it is simple, fast, fewer dependencies, and explicit. It is basically a makefile with a javascript syntax. ^.^ Easier all around though. :slight_smile:

Ooo, more links, nice!

Well, unless you want to have webpack do what brunch is currently doing to the project, then you have to make the webpack config file. ^.^

With npm as an initial hook someone could just call their webpack/gulp/whatever-of-choice from the npm build script itself until, if they wanted, they could replace it entirely with whatever-build-system-of-choice and then change the ‘watcher’ argument in phoenix. :slight_smile:

I have multiple watchers in my phoenix config for note (well, ‘had’, currently just have one now since I’m testing npm run watch).

chrismccord

chrismccord

Creator of Phoenix

The goal is an out of the box experience that Just Works without fanfare. With a basic brunch or web pack config, a user does not have to know about browserify, how to configure it, how to bundle, etc. So even if this can all be achieveved by stringing fewer deps together, end-users still have to know how those deps work individually and configure to their liking. This may work well for power users but newcomers, especially those not enthralled in js day to day, just want to compile and bundle js/es20xx/sass without pain.

alexgaribay

alexgaribay

Phoenix Core Team

I don’t find any issue with Brunch being the default configured Node asset bundler/transpiler. For me, I prefer Webpack since a do a lot of React development. However, I suspect most developers don’t care or don’t know all the nuances of choosing a Node asset bundler and just prefer to start with some that just works. Like Chris mentioned, it doesn’t take very long to replace Brunch in your application. Additionally, EEX templates are pretty awesome and fast :rocket:.

OvermindDL1

OvermindDL1 OP

Problem is that brunch is indeed painful, from teaching it to quite a few people as well as remembering my initial experience with it that was obvious.

To do the JS/es20** part is just browserify, its command-line is simple, like here is mine for my app.js:

"build:app.js": "browserify web/static/js/app/**/*.js -e web/static/js/app/index.js -o priv/static/js/app.js -t [ babelify --presets [ es2015 ] ]",

I don’t use a vendor directory but that can be added easily enough to browserify with another parameter to not have it transform those files. If you notice the same options that brunch scatters around in (a couple initially confusing) places are just right there, and you can have unique options for files too (want to run the ‘react’ babelify preset on only react files, you can do that easily here, not at all easily in brunch, if at all without making your own plugin).

For css I just have (since I use scss):

"build:app.css": "node-sass -o web/static/css/app.css web/static/css/app.scss",

And of course the "build:outputfilename" is just a convention I’ve been using, can use whatever you want.

But they do have to know about brunch/webpack, which is significantly larger of a thing to learn. I started by “Hmm, how do I output two javascript file where I can import between them”, which in brunch ended up being a couple of lines of specifying path regex’s and such, simple once I saw, but no clue how to do that at first and took a bit of research as the first couple of tries caused brunch to start throwing errors.

Where in npm, everyone knows the shell (considering calling npm/mix/etc… uses it).

Which brings up my issue, they do not ‘just work’. It works for the single JS file and single CSS file that phoenix includes, but those are trivial cases. When I expanded beyond that brunch became hell to work with. As stated, even now I have to save my file, wait 50 seconds, save my file again (or just ‘touch’ brunch-config.js to have the entire brunch watcher reload) to get the files to update properly.

I enable brunch again, I make an edit in my JS file that I have open, I save it, the phoenix page reloads…and does not include the change. I save it again, wait a bit, page reloads again and still no change, I touch brunch-config.js, wait a couple of minutes, the webpage reloads about 8 times while it compiles, then finally the change is seen. Then I notice a small bug and my element is not being cleared from the DOM, so I make the fix, save it, the page reloads while I switch to the terminal and hit then again to run touch brunch-config.js, wait a couple of minutes, and it is fixed, but now I have to make the next section…

I was dreading every-single-edit that I had to make. Maybe it is a Windows thing, but brunch is painful and its time has been increasing substantially. The NPM replacement I made this morning is significantly shorter and I’ve not had a single issue of having to recompile a file yet, plus a full rebuild now only takes the time that the longest task takes (which is elm compiling) instead of longer. :wink:

alexgaribay

alexgaribay

Phoenix Core Team

Anecdotally, I use multiple SCSS files and multiple JS files and I’ve never had issues with the transpile time. Brunch transpiles my code in a matter of seconds but I develop on OS X instead of Windows, albeit I just export a single CSS and JS file when all is finished.

andre1sk

andre1sk

I think we can come up with some nice package to do what you propose vs making it default. So those who need it would just do --no-brunch and install a package that has a task to init everything to the way you describe.

Where Next? Top

Trending in Discussions Top

AstonJ
As the title says, please share what you’ve been up to with Elixir. Whether that’s been learning it, looking into it, making stuff with i...
2977 94592 917
New
cblavier
Hey there, It’s been more than a year since we started using LiveView as our main UI library and building a whole library of UI componen...
New
mudasobwa
I am happy to introduce the very α version of the new programming language compiled to BEAM. Welcome Cure. It has literally three kille...
New
heathen
Quite interesting article Google brought me. Didn’t find any mentions about it here. What do you think in general? Would you use togethe...
New
mhanberg
Hi everyone! The first release candidate for the Expert language server project is now available! We’ve published a press release detai...
New
axelson
Hi there! :wave: @frigidcode and I (but mostly him) have been running an Elixir Book club, we’re almost done with Designing Elixir Syste...
New
AstonJ
Since we have deprecated our Erlang sections (as we have dedicated Erlang Forums now) let’s add this thread for those who’d like to post ...
New

Other Trending Topics Top

GenericJam
Edit: 2026 May 15 - This post is archived. Mob is alive!! Main docs: mob v0.7.11 — Documentation A bit of explanation for the slightly c...
New
JesseHerrick
Hey, I’m Jesse and I’m the main contributor behind Dexter, a full-featured, lightning-fast Elixir LSP optimized for large codebases. It s...
New
marciok
Hi there! We created Gust: A task orchestrator inspired by Airflow. For those who have never heard about Aiflow, it’s a Python-based wor...
New
jimsynz
Beam Bots (or just BB for short) is a framework for building fault-tolerant robotics applications in Elixir using familiar OTP patterns. ...
New
georgeguimaraes
Just published claude-code-elixir, a plugin marketplace for Claude Code with Elixir support. These are the plugins I’ve been using for my...
New
Dmk
Xamal is a deployment tool for Elixir apps that deploys native releases to bare metal servers over SSH. It’s a port of GitHub - basecamp/...
New

We're in Beta

About us Mission Statement

Options

Thread Display Mode




Thread Preview

Skip Thread Previews