I wrote a related blog post [0] and provided a sample starting point [1] a few months back.<p>I'm amazed more people haven't heard of webpack, it solves a ton of these problems.<p>[0] <a href="https://github.com/cesarandreu/blog/blob/master/a_reasonable_starting_point_for_building_a_web_app/a_reasonable_starting_point_for_building_a_web_app.md" rel="nofollow">https://github.com/cesarandreu/blog/blob/master/a_reasonable...</a><p>[1] <a href="https://github.com/cesarandreu/web-app" rel="nofollow">https://github.com/cesarandreu/web-app</a>
I am so happy to have left the web back into native, just about when gulp, grunt, npm, yeoman and friends were picking up steam.<p>It is not enough to jungle DOM libraries, CSS generation, JavaScript frameworks, browser compatibility headaches, one also needs to use the build tool of the day.
This. A thousand times this. Embrace the unix philosophy of small tools and npm scripts and watch your baroque frontend build process with all its plugin dependencies reduce to amazing simplicity. Here's another good write up with some significantly more useful examples:<p><a href="http://blog.keithcirkel.co.uk/how-to-use-npm-as-a-build-tool/" rel="nofollow">http://blog.keithcirkel.co.uk/how-to-use-npm-as-a-build-tool...</a><p>> Package.json also doesn’t support variables<p>Not sure what he means by this, npm scripts do support env vars from package.json config values:<p><a href="https://docs.npmjs.com/misc/scripts#configuration" rel="nofollow">https://docs.npmjs.com/misc/scripts#configuration</a>
> When you use npm scripts, you don’t search for a Grunt or Gulp plugin. You choose from over 227,000 npm packages.<p>This statement is sensationalist and I don't think it presents a useful argument. Sure I could write a script that uses one of those packages but that has nothing to do with whether or not any of those packages actually helps me achieve my goal.
Using npm instead of Grunt/Gulp/etc. has been extensively discussed by Keith Cirkel at <a href="http://blog.keithcirkel.co.uk/how-to-use-npm-as-a-build-tool/" rel="nofollow">http://blog.keithcirkel.co.uk/how-to-use-npm-as-a-build-tool...</a>. Would've been nice to at least acknowledge that, if not join efforts and try to address some of the inherent shortcomings (e.g. the readability of long lines - <a href="https://github.com/keithamus/npm-scripts-example/issues/30" rel="nofollow">https://github.com/keithamus/npm-scripts-example/issues/30</a>).
I'm moving in a similar direction for similar reasons - but by shifting functionality out of the node ecosystem altogether. I recently released devd, a small, dev-focused HTTP server with build-in livereload which has taken the place of gulp livereload and node-based dev servers for many of my projects (<a href="https://github.com/cortesi/devd" rel="nofollow">https://github.com/cortesi/devd</a>).<p>I'm now working on the next step. It's not quite ready to be announced yet, but I'm cooking up modd, a similarly focused tool for monitoring the file system and responding to changes (<a href="https://github.com/cortesi/modd" rel="nofollow">https://github.com/cortesi/modd</a>). Modd has already supplanted gulp entirely for many of my use cases, and has replaced supervisor and a bunch of other tools to boot. Many of the actions triggered by modd for front-end projects are precisely invocations of npm scripts as described in the article. A few more features (desktop notifications with Growl/notify, and script access to the list of changed files), and modd will be ready for me to ask for public feedback.<p>Both modd and devd are small, single-purpose tools written in Go, released as statically compiled binaries with no external dependencies. I've tried to make them tight and focused, and if I get it right, they will hopefully be a refreshing change after gulp and grunt.
How to Use npm as a Build Tool - Keith Cirkel
<a href="http://blog.keithcirkel.co.uk/how-to-use-npm-as-a-build-tool/" rel="nofollow">http://blog.keithcirkel.co.uk/how-to-use-npm-as-a-build-tool...</a><p>Using npm scripts to build an asset pipeline - Modulus
<a href="http://blog.modulus.io/using-npm-scripts-to-build-asset-pipeline" rel="nofollow">http://blog.modulus.io/using-npm-scripts-to-build-asset-pipe...</a>
Why don't they provide a good working example, using Browser Sync or LiveReload, Sass, etc ?<p>I haven't found a good build process using npm as a task manager or build tool; I haven't seen any good example on any article I've read so far; gulp was built for, and it's much clear in my opinion!
Npm scripts work for very superficial tasks, but fail to deliver even for such a simple task as live reload:<p>- You need to run both server and watcher from the same shell, and the proposed way is to use parallelshell which is not a robust tool such as Gulp. Specifically trying npm run dev as suggested leads to some error that, after termination, leave 4 processes running in background that you have to kill manually, or else you can't access the same ports. Not fun.<p>- It requires to "highjack" your source files with script tags that I don't feel belong there:
<script src="//localhost:9091/livereload.js"></script><p>Why Gulp plugins are better?<p>- Fast: use streams, no temporary files.
- Gulp plugins have uniform API: stream in, stream out; no massive command line options.
- Convenient and expressive node-glob abstraction to select files/directories to be watched.
- Less magic, more control and understanding of what is going on, less chance and dependence on bugs.<p>Here is the absolutely basic LiveReload setup that I wasn't able to achieve with Npm scripts:<p><a href="https://github.com/dmitriz/min-server" rel="nofollow">https://github.com/dmitriz/min-server</a>
I may not have been in the node and npm space long enough to fully understand the point of this, but it sounds like the endless argument of "stop using jQuery and go with raw Javascript instead".<p>The argument goes that modern Javascript has moved far enough along that a library like jQuery is not as necessary. But the majority of the examples I've seen of how to avoid jQuery means essentially coding your own custom version of jQuery.<p>This argument of dropping Grunt/Gulp seems the same to me. "Don't use a pre-coded builder or task runner, just build it yourself". I'm not sure I agree that's necessarily the best route for every project and/or coder.<p>Right now I've been playing with node and gulp, just for fun. So far I've found the most comfortable route for me is to have gulp kick off the process and then use non-gulp packages when it feels right. For instance, I don't use a gulpified version of Handlebars, I just use the actual npm package. I can't say this is the "best standards" way to go about it, but it feels right for me.
Most of the issues with Grunt and the like can be done away with by following good coding practices. i.e. keep your code outside the Grunt context and write unit tests for it. See the Thin Grunt Manifesto:<p><a href="https://www.exratione.com/2015/08/thin-grunt-manifesto/" rel="nofollow">https://www.exratione.com/2015/08/thin-grunt-manifesto/</a><p>I'm not sure I buy fleeing to the command line as a viable alternative. You are in essence going to have to write a bash script at some point because the command will bloat beyond what can be sanely contained in a JSON property. Then you have to write tests for it. So why not just do that in Javascript, since you already have the infrastructure sitting there.<p>I think it is the case that most groups simply write lazy Grunt code in ways that make it hard to test. This is a chronic problem throughout the devops space; the code is frequently terrible. So don't do that. Don't drag the Grunt instance out into your code. Separate your concerns. Write testable functions and classes.
Many a time I have begun a node project, and many a time I have started under the basic premise of "I'll just use an npm task for this one little build task". Task runners do seem to add a bit of complexity to a project which new contributors sometimes find friction in. As the project grows and I add more and more tasks - for linting, building sub projects, testing, etc - I end up writing "glue" js files which get called by npm to get the desired output of a library or tool, or to compose a set of tools in the way I need. After a while you realize its been done before, and in a composable way - you're writing gulp and grunt tasks without actually calling gulp or grunt, and you've ceded reusing any existing code for it. Upon this realization I normally realize I can pull in gulp and then discard a large chunk of my handwritten tasks in favor of easily composing task runner plugins.<p>Also, minor nit: The author claims `&&` is "cross platform". I regret to inform him it is not. It may well work for bash and cmd.exe but it has been disallowed as a command seperator in powershell for a few versions. Aiming for cross-shell compatible commands is more of a minefield than you'd expect - I actually knew someone who'd rewired a ruby DSL to use for a shell. I've found it best for crossplat to write as much in JS as possible and just let npm tasks call out to scripts, to use as little of the shell as possible.
I am using npm scripts for everything too. Check out my article "tiny npm package": <a href="http://g14n.info/2015/12/tiny-npm-package/" rel="nofollow">http://g14n.info/2015/12/tiny-npm-package/</a><p>Checkout my postversion hook!<p>By the way, even if JSON does not support comments, sometimes I add a "#TODO:fooscript" prop in the scripts, and add comments as well.<p>Another interesting trick is that a script can call other npm scripts.<p>Also another nice feature is that command in node_modules/.bin folder are added to PATH.<p>Yes, npm scripts rock!
<i>I was struggling to integrate Webpack, Browsersync, hot reloading, Mocha and much more using Gulp</i><p>I'm a little unclear on why you'd try to integrate Webpack into Gulp - Webpack is more than sufficient by itself. And I've tried using NPM-only scripts, but they haven't yet matched the dev server, hot reloading, production-readying functionality inside Webpack.<p>Webpack configuration files are absolutely gross, though.
The `cross-env` used by the author seems useful, I didn't know about that, and for this reason I'd usually write a separate bash script when I wanted to execute something like<p><pre><code> FOO=1 some-command
</code></pre>
because this syntax doesn't work in `package.json` on Windows.<p>BTW. If you're not into bash for writing long scripts, it's pretty easy to write shell scripts in nodejs. Node 0.12+ has native `execSync` that is nice to have to write build code in JS in synchronous way. I wrapped it with two helper functions to have sth like `execAndPrint` and `execAndReturn`:<p><a href="https://gist.github.com/jakub-g/a128174fc135eb773631" rel="nofollow">https://gist.github.com/jakub-g/a128174fc135eb773631</a><p>It's not as powerful as bash script (doesn't support | syntax for redirecting etc) but if you need that, you can extract it away to a helper bash script.<p>See also <a href="https://github.com/shelljs/shelljs" rel="nofollow">https://github.com/shelljs/shelljs</a>
That title I would call sensationalist. Our tooling choices don't have to take this king-of-the-molehill, all or nothing, "did X just kill Y?" extreme stance. (I thought the article made some reasonable points, though.)<p>With so much conflicting wisdom to sort through - "yuck, monolith!", "omakase!", "YAGNI!", "not enough abstraction!", "too much abstraction!" - we should admit that we often end up leaning on instinct/emotion when making these decisions.<p>Just remember that you don't have to pick one philosophy and stick with it for all time exclusively. Often down the road you'll see the value in something you thought you had sworn off.
> I’ve found Gulp and Grunt to be unnecessary abstractions. npm scripts are plenty powerful and often easier to live with.<p>The main problem with this line of reasoning is that as things get more complex and expansive over time (and they will do as night follows day) on the npm scripts front, the developer would likely resort to build abstractions to hide all the tangled wires and simplify the dev process and then we're back to square one.<p>Abstractions are necessary evil but they should be built and also managed efficiently and wisely to avoid the common pitfalls and pain points and make the development process easier and less annoying.
I'm glad to see more people following this approach.<p>The real consequence of having the community diverging on build tools is the added work required by tool creators to support them. I created a tool that included a grunt wrapper just before gulp became the new 'hottness' and quickly became fed up with the whole mess.<p>Soon after, I discovered that npm scripts can call the bin scripts of locally installed dependencies. I haven't looked back since.<p>NPM scripts make composing tasks nice... and there's nothing stopping you from adding custom configs to the package.json object.
I went the other way as well and used Python with Envoy to call every thing from the command line.<p>It's quick, easy to debug (arguments to commands can be dumped in debug mode, run manually etc).<p>Also for certain tasks Python annihilates Gulp plugins.<p>This is a production example (not pretty code per se) <a href="http://kopy.io/yvEGl" rel="nofollow">http://kopy.io/yvEGl</a> when combined with intellij watchers this makes it very easy to rebuild on change.
> Misconception #3: Gulp’s Streams Are Necessary for Fast Builds<p>The author fails to acknowledge that gulp is also asynchronous. This is what makes it "fast". Streaming is just a nice abstraction for passing data through a pipeline.<p>Sure you can do async on command line but that's not trivial and the author doesn't address that.
this reminds me of 'real programmers' by xkcd[1]<p>[1]<a href="https://xkcd.com/378/" rel="nofollow">https://xkcd.com/378/</a>