9 ms·
Why I Left Gulp and Grunt for Npm Scripts
- heldrida 11y agoWhy don't they provide a good working example, using Browser Sync or LiveReload, Sass, etc ? 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!
- housecor 11y agoThe article mentions two good working examples that do everything you mentioned and more: https://github.com/coryhouse/react-slingshot https://github.com/coryhouse/react-slingshot https://github.com/kriasoft/react-starter-kit https://github.com/kriasoft/react-starter-kit
- TheAceOfHearts 11y agoIt isn't 100% up to date anymore, but I made a web app repo [0] that gives you everything you need for a frontend app. This repo is very close to what we're using in my job for our app. Furthermore, I wrote a related blog post [1] about this a few months back. You don't need gulp. [0] http://github.com/cesarandreu/web-app http://github.com/cesarandreu/web-app [1] 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 https://github.com/cesarandreu/blog/blob/master/a_reasonable...
- EvanPlaice 11y agoIf you're doing front-end development Use JSPM for module management, transpiling (Babel, Traceur, Typescript), and bundling live-server for LiveReload. With zero config it injects the LR stub and sets up a file watcher on the directory it's run in. BrowserSync can be loaded via a npm command: https://gist.github.com/addyosmani/9f10c555e32a8d06ddb0 https://gist.github.com/addyosmani/9f10c555e32a8d06ddb0 SASS can be setup with: https://medium.com/@brianhan/watch-compile-your-sass-with-npm-9ba2b878415b#.5vvem7fzs https://medium.com/@brianhan/watch-compile-your-sass-with-np... Here's what I use to build my Angular2+ES6 app: https://github.com/evanplaice/evanplaice.com/blob/master/package.json https://github.com/evanplaice/evanplaice.com/blob/master/pac... Using npm as the default task runner is becoming more common so it's not to difficult to find good examples thru Google.
- Klathmon 11y agoPersonally I ended up with a mix. Leave Gulp to be gulp and do the heavy lifting while using npm scripts to run the gulp tasks and anything that doesn't live inside gulp. It gives the simplicity of allowing people unfamiliar able to look at the package.json file and no further if they just want to use it, and allows all the "plug and play" style plugins from gulp.
- jessaustin 11y agoHere's something I've been using recently: $ jq .scripts package.json { "start": "npm-run-all --parallel client server live", "client": "beefy client/index.coffee:index.js $npm_package_config_beefy_port --cwd client -- --transform coffeeify --extension '.coffee'", "server": "BEEFY_PORT=$npm_package_config_beefy_port LIVE_PORT=$npm_package_config_live_port PORT=$npm_package_config_port nodemon --watch server --watch template --ext coffee,jade server/app.coffee", "live": "live-reload --port=$npm_package_config_live_port --delay=3000 client server template" } No sass in there, but one can see it could easily be added.
- mercer 11y agoA small tip for those who use sass and use node-sass (and npm scripts): I ran into a strange problem where if you use node-sass to watch a directory for some reason adding a new partial and the @import statements doesn't quite work as it should. If you change something in the imported file, node-sass won't recompile so you don't see your changes. The only way around it is to re-save the file that does the @import, or restart the process. The solution I found is to use the more generic 'watch' package to watch the directory, and make it simply re-run node-sass without the watch flag. Aside from solving the problem, it also ended up feeling cleaner to use 'watch' everywhere I needed it instead of relying on all the different watch approaches of the different tools. The one downside is that certain tools' own watch capabilities are faster or do partial updates. In the few cases where that is true I would just use the built-in watch functionality of course. But it's rarely been an issue for me.
- dandv 11y agoUsing npm instead of Grunt/Gulp/etc. has been extensively discussed by Keith Cirkel at http://blog.keithcirkel.co.uk/how-to-use-npm-as-a-build-tool/ http://blog.keithcirkel.co.uk/how-to-use-npm-as-a-build-tool.... 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 - https://github.com/keithamus/npm-scripts-example/issues/30 https://github.com/keithamus/npm-scripts-example/issues/30).
- aroberge 11y agoIt has been acknowledged in the post: it is one of many links prefaced by I’m far from the first person to suggest this. Here are some excellent links:
- exratione 11y agoMost 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: https://www.exratione.com/2015/08/thin-grunt-manifesto/ https://www.exratione.com/2015/08/thin-grunt-manifesto/ 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. 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.
- noir_lord 11y ago> 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. or do it in python like I did - http://kopy.io/yvEGl http://kopy.io/yvEGl it works amazingly and gives you endless flexibility without require bash.
- cortesi 11y agoI'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 (https://github.com/cortesi/devd https://github.com/cortesi/devd). 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 (https://github.com/cortesi/modd https://github.com/cortesi/modd). 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. 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.
- EvanPlaice 11y agoWhy create devd when you could have just used live-server? It automatically injects the LiveReload stub and watches the directory for changes. I guess, if your end goal is to move everything away from the node ecosystem. To each their own.
- cortesi 11y agoWell, first, I think it's perfectly fine to have multiple takes on the same problem space. This is how we progress - people try different things, and we gradually figure out what works. Live-server does a specific set of things, and devd is a different take on a slightly wider set of things, and I think that's just dandy. The overlap is far from precise, and I think there's enough room for both devd and live-server (and for the many other tools that do similar things). Second, not everything is node. Devd has lots of uses outside of node and even outside of front-end development. Third, I probably wouldn't have written it if I didn't believe that devd did at least some things better than the current tools (at least for some people). You should try it - maybe you'll like it, and if you don't then that's fine too. As you say - to each their own. ;)
- TheAceOfHearts 11y agoI wrote a related blog post [0] and provided a sample starting point [1] a few months back. I'm amazed more people haven't heard of webpack, it solves a ton of these problems. [0] 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 https://github.com/cesarandreu/blog/blob/master/a_reasonable... [1] https://github.com/cesarandreu/web-app https://github.com/cesarandreu/web-app
- noir_lord 11y agoI went the other way as well and used Python with Envoy to call every thing from the command line. It's quick, easy to debug (arguments to commands can be dumped in debug mode, run manually etc). Also for certain tasks Python annihilates Gulp plugins. This is a production example (not pretty code per se) http://kopy.io/yvEGl http://kopy.io/yvEGl when combined with intellij watchers this makes it very easy to rebuild on change.
- Already__Taken 11y agoIt adds yet another dependency just to get a project to initialize though which is a small negative. I guess npm needs python anyway for node-gyp but then you have to stick to python 2.
- noir_lord 11y agoI deploy dev environments via vagrant/ansible so that's a slight upfront cost but something I never have to touch. Using virtualenvs I can also keep one project isolated from another in terms of jumping around the filesystem. The convenience is a major win and since I use python for everything other than the web framework which is PHP it actually ties together nicely. Unconventional but it works really well.
- EvanPlaice 11y agoI'm glad to see more people following this approach. 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. Soon after, I discovered that npm scripts can call the bin scripts of locally installed dependencies. I haven't looked back since. NPM scripts make composing tasks nice... and there's nothing stopping you from adding custom configs to the package.json object.
- Wintamute 11y agoThis. 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: http://blog.keithcirkel.co.uk/how-to-use-npm-as-a-build-tool/ http://blog.keithcirkel.co.uk/how-to-use-npm-as-a-build-tool... > Package.json also doesn’t support variables Not sure what he means by this, npm scripts do support env vars from package.json config values: https://docs.npmjs.com/misc/scripts#configuration https://docs.npmjs.com/misc/scripts#configuration
- mikerichards 11y agoGulp does embrace the unix philosophy of small tools and piping output.
- Silhouette 11y agoUnfortunately it embraces it so much that there are several different variations of connecting the parts together, and even then some important tools don't play very nicely with the rest of the Gulp framework. Consequently, it takes several lines of awkward boilerplate just to run a simple Browserify job that is a one-liner at the CLI. I've also seen Gulp adapters for popular tools, such as ESLint, that break suddenly when something apparently unrelated in the NPM set-up is updated, even though ESLint itself also still runs just fine with a one-liner at the CLI. In fact, those were the two examples I used when I put my foot down over build tools on one project I work on a little while back. Within 20 minutes we'd replaced well over 100 lines of Gulp code with about 10 one-liner CLI jobs that did all of the same things. The new version has the added advantages of actually working, which the Gulp-based code used to but didn't any more, and of requiring a total of 0 changes since then to remain working, other than when the tools themselves changed their interfaces.
- Wintamute 11y agoFor every small tool you want to use in Gulp you either have to write your own Gulp task in JS, or add a plugin wrapper to the tool as an additional dependency to your project. Doesn't seem ideal. Just by switching to npm scripts you could probably reduce by at least 50% the number of 3rd party dependencies in your build. Also streaming stuff around inside a Gulp process is good in terms of speed, but imo quite complicated conceptually, and doesn't match the simplicity of piping stdout between one-liner CLI commands.
- mutatio 11y agoreally simple automation I use: https://github.com/martingallagher/gawp https://github.com/martingallagher/gawp
- fibo 11y agoI am using npm scripts for everything too. Check out my article "tiny npm package": http://g14n.info/2015/12/tiny-npm-package/ http://g14n.info/2015/12/tiny-npm-package/ Checkout my postversion hook! 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. Another interesting trick is that a script can call other npm scripts. Also another nice feature is that command in node_modules/.bin folder are added to PATH. Yes, npm scripts rock!
- michaelmior 11y ago> When you use npm scripts, you don’t search for a Grunt or Gulp plugin. You choose from over 227,000 npm packages. 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.
- paulojreis 11y agoCompletely agree. Comparing these numbers doesn't make sense; of course npm has more modules, but why would I care about having e.g. node's express framework available to my build tool/task runner?
- housecor 11y agoYou're right. You wouldn't care about everything in npm. The point is this: When using Gulp/Grunt, we have to search for a plugin. This greatly limits our selection.
- paulojreis 11y agoI see your point, it makes sense. But I have to note that in gulp (at least) you aren't restricted to plug-ins. You can use "generic" npm packages, as long as they output a stream (e.g. browserify).
- mercer 11y agoIt's definitely hyperbole, but the point still stands. Back when I used Gulp, I've run into quite a few situations where a particular package I wanted to use didn't support Gulp, but did have CLI support. And even if both were supported, adding a line to package.json was faster and simpler than using the gulp approach. That said, I have nothing against Gulp and it's quite possible I might use it in the future. For example, the approach of using npm scripts can be problematic if you need to work on different operating systems. And I'm sure there are plenty of cases where the complexity is best managed with Gulp or its ilk.
- pjmlp 11y agoI am so happy to have left the web back into native, just about when gulp, grunt, npm, yeoman and friends were picking up steam. 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.
- debacle 11y agoThe worst is when the same developer uses the same tools in his build process for two different projects but they need to be executed in a different order for each.
- gotchange 11y agoIf you're using any of those tools above just because they're en vogue, you're doing it wrong. You use those tools because they solve specific problems that you're facing and to make your job easier and not because the "cool kids" on the block are using them. I'd say that nearly all the tools listed in your comment serve a purpose and solve specific problems and ease certain pain points that I deem them useful and assets in my workflow.
- pjmlp 11y agoWe don't choose our tools, the customer's IT does it, so are the wonders of consulting when you work on existing projects. And they choose them, because they follow fashion.
- gotchange 11y agoDo your customers really dictate that you use grunt or gulp in your build process in their project? I seriously find this to be very implausible.
- dagw 11y agoI seriously find this to be very implausible. Why? If they're already using gulp and have people in-house that understand gulp, why is it so unreasonable that they don't want their consultants adding a new build system to the mix?
- jlas 11y ago> Misconception #3: Gulp’s Streams Are Necessary for Fast Builds 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. Sure you can do async on command line but that's not trivial and the author doesn't address that.
- ksherlock 11y ago'make -j' seems trivial enough to me.
- jakub_g 11y agoThe `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 FOO=1 some-command because this syntax doesn't work in `package.json` on Windows. 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`: https://gist.github.com/jakub-g/a128174fc135eb773631 https://gist.github.com/jakub-g/a128174fc135eb773631 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. See also https://github.com/shelljs/shelljs https://github.com/shelljs/shelljs
- untog 11y agoI was struggling to integrate Webpack, Browsersync, hot reloading, Mocha and much more using Gulp 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. Webpack configuration files are absolutely gross, though.
- talmand 11y agoI 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". 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. 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. 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.
- gotchange 11y agoYeah there's some Not Invented Here (NIH) sentiment to this behavior and it's holding back the community from moving forward and exploring new frontiers and solutions than reinventing the wheel or tearing down structures to rebuild them only to tear them down shortly again and so on and so forth.
- untog 11y agoThere is definitely a level of that in the article. "Use command line tools. Or, if it gets complex, make a .js file and use ShellJS" is basically suggesting you create your own version of the plugins already available.
- esailija 11y agoIt is nothing like that. Npm/node is the task runner and you are not doing anything yourself that you wouldn't have to do with grunt/gulp anyway. They are the equivalent of making a function like `add(a, b) { return a + b; }` instead of just using the `+` operator that is already there, it is nothing like jQuery vs "raw javascript".
- 11y ago
- gotchange 11y ago> I’ve found Gulp and Grunt to be unnecessary abstractions. npm scripts are plenty powerful and often easier to live with. 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. 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.
- hawleyal 11y agoHow to Use npm as a Build Tool - Keith Cirkel http://blog.keithcirkel.co.uk/how-to-use-npm-as-a-build-tool/ http://blog.keithcirkel.co.uk/how-to-use-npm-as-a-build-tool... Using npm scripts to build an asset pipeline - Modulus http://blog.modulus.io/using-npm-scripts-to-build-asset-pipeline http://blog.modulus.io/using-npm-scripts-to-build-asset-pipe...
- jscampbell05 11y agoJavascript is way too complicate these days :S
- ahallock 11y agoThe next article will be entitled "Why I Left npm Scripts for Make"
- ldd 11y agothis reminds me of 'real programmers' by xkcd[1] [1]https://xkcd.com/378/ https://xkcd.com/378/
- wwwigham 11y agoMany 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. 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.
- grb423 11y agoThis has been my experience too. I have every intention to use npm tasks but wind up pulling in gulp when my js "glue" gets too lengthy. I wind up wondering yet again why I wanted to omit gulp. The tasks are super readable and, I think, easier for new contributors than the pipes and ampers and glue scripts that my npm tasks were growing.
- matthewtoast 11y agoThat 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.) 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. 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.
- dmitriz 11y agoNpm scripts work for very superficial tasks, but fail to deliver even for such a simple task as live reload: - 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. - It requires to "highjack" your source files with script tags that I don't feel belong there: <script src="//localhost:9091/livereload.js"></script> Why Gulp plugins are better? - 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. Here is the absolutely basic LiveReload setup that I wasn't able to achieve with Npm scripts: https://github.com/dmitriz/min-server https://github.com/dmitriz/min-server