Fair question. This post is targeted to people who love webpack on the frontend but don't use it on the backend, and I don't really explain the benefits of webpack in general.
Packaging all files into a single one is a side effect that we don't really care about. If you want to build your app with babeljs, you need to compile all your backend files. Who cares what the output is, if it's multiple files or a single file? As long as it's semantically the same (meaning even __dirname and friends work appropriately), it doesn't matter.
But what you get is really powerful build system (much better than hacking one together with gulp). Just look how small my config is, and now you can add babel as a loader for JS files and it just works. And you get to use the exact same infrastructure for the frontend.
So the purpose here is to make it easier to use preprocessors on the backend? Hasn't this been common for a long time? What does webpack do here exactly?
A good solution hasn't been common. Try to use babel with gulp. You have to just glob a bunch of files and hope you've covered all your dependencies. It becomes a mess once you get into more complicated stuff.
In my experience, this approach really shines when you are building an "isomorphic" app. When the same code is expected to run in the browser and on the server, having a build tool that knows about both your entire dependency graph and your different build targets is a huge boon.
For example, you get hashed filenames (for far-future cache expiration in the browser) for free (no manifests or runtime reconciliation of names to assets necessary).
>For example, hot module replacement allows you to change a module and update the existing instance live. This is the juice within react-hot-loader and this is the kind of stuff we need to be building. You'll never look back after experiencing this.
I second this. (Disclaimer: I wrote React Hot Loader.)
Webpack's live reloading system is not browser-specific, does not depend on attaching debuggers or doing anything else invasive.
All it does is represent module cache as (id) -> (function) map and give you the tools to “handle” module updates, as if modules were Observables and you subscribed to “new versions” of them. If update is unhandled, it bubbles.
This is what allows Hot Module Replacement to work for React components, CSS and Markdown files, and even classes on backend.
I've been playing with this a for a few months now. Thanks to webpack / react starter (https://github.com/webpack/react-starter), you get that for free (with server-side rendering of your apps).
What I'd like to see is for webpack to add features from Pants like self-bootstrapping executables (PEX) or run tests based on which part of the code was affected by a commit. For the executable part, I guess Docker kind of solve that issue. See http://pantsbuild.github.io/ for more info
In 2015, we have ES6 modules now. Instead of define/require, we have import/export and it is standards based now, which is nice.
For systems that do not support ES6 syntax directly, this is provided today with tools like SystemJS [1] and jspm [2]. SystemJS is great because it supports all of the module formats for backwards compatibility. jspm is great because it doesn't matter where you grab your dependencies from (npm/github/bower/etc).
I agree with the authors comment about gulpfiles being hacky and not very DRY (don't repeat yourself). That said, his examples felt very hacked together as well, there is too much programming in there. Do I copy that build file across every new project I create?
gulpfiles are great because they provide extra functionality that is missing, like only re-transpiling files that change. For large projects this can really be a time saver. webpack has that by running a separate server process, complicated! Projects like gulp-helpers [3] try to bring a tiny bit of sanity and re-usability to gulpfiles by making things a bit more DRY and configuration based. It is just an example of one way to do things, but hopefully you see my point.
The syntax for specifying dependencies is irrelevant -- webpack aims to support all of them, and as far as I know has experimental ES6 import/export support. I'm definitely going to transition to ES6 modules soon.
The infrastructure is the important piece, not the module syntax. Webpack provides this infrastructure, and it's easy to provide it for ES6 modules as well.
For example: how do I hot reload modules? How do I eval code inside a module? Webpack allows you to do all of this, and is more advanced than anything out there. SystemJS and jspm are nice but I still find webpack to support way more features.
What do you mean "hacked together"? Look at how small my config is! Do you know how much you get from that small config? The only thing hacky is the `node_modules` hack, and as far as I know, you'd have to do something similar with anything else (I don't see anyone using SystemJS/jspm on the backend).
Also, re-transpiling files that change? Just fire up the watcher (`webpack --watch`) and webpack automatically does this...
> The infrastructure is the important piece, not the module syntax.
That's what makes SystemJS appealing; the infrastructure is the ES6 (now WhatWG) Loader Specification; a spec that browsers will be implementing. So you don't have to worry about learning yet-another-module-loader like you do when jumping from requirejs -> browserify -> webpack -> whatever's next trends.
I don't know what you are complaining about. Build systems are complex. These config files are relatively straight-forward. You tell it where to start, where to output, to use sourcemaps, and give it a few plugins. It can't get much simpler.
For hot module replacement, sure, it gets a little more complex. You add another plugin and another entry point, that's all.
You're sounding really defensive. I find it entertaining that in one sentence you say 'Build systems are complex' and in another 'It can't get much simpler.'
I disagree that build systems need to be complex. They get complex because people try to invent too many different ways of doing things instead of working towards standards. webpack is a prime example of that.
I'd love to see a full demo seed example of your ideal build system. Something that includes hot code swapping and even more importantly, unit testing.
I'm currently setting up something similar to this. It's an app that does server-side rendering. It has the server-side code, the shared rendering code, and the client-side code.
Webpack solves a LOT of problems with application development. Handling assets properly is very difficult, and webpack makes it straightforward.
Build systems are complicated, I'd love to see something that handles the same problems as webpack but somehow manages to avoid the required configuration.
I don't feel defensive, honestly build systems are boring to me so I'm not that passionate about it. What I meant was that its simple relative to what it could be.
Yes, build systems are complex, because people need features, even if you personally don't need them. Webpack doesn't offer many ways to do the same thing; it just simply has a lot of features. Whenever we get enough tooling around ES6 modules to match it (or come close), I'll gladly switch.
You'll see a fuller example later. I'd love to see a matching set up using systemjs/jspm. You could convince me to switch.
Good point, I probably should just use that here, but in my project the array actually has a few more elements. I do this because there are a few modules I don't want to ignore for various reasons.
It feels hackier, and there is a downside: you can't alias non-relative modules because they are simply ignored. I've run into situations where I needed to alias something in node_modules because we preprocessed it and put it somewhere else.
I'm trying to boil this down to an easily-digestable list of benefits for server-side development, since I'm completely unfamiliar with webpack. So far I have this:
* Transpiles code that runs in node, not just code that runs in browsers.
* Hot-reloads modules, so I don't have to restart my server a lot.
* Does source maps, presumably which are exposed via tools like node-debug.
I'm also trying to wrap my brain around what webpack is, since I've been thus far conditioned to think of the build runner (e.g. gulp) and the bundle maker (e.g. browserify) as being separate.
The article seems to be saying this, but am I correct to come away thinking of webpack as a "module-aware build runner" that replaces both gulp and browserify (for example)?
It's primarily a bundle maker a la browserify. The main difference is that it stretches the definition of module beyond just javascript. It can seem like a build system because you can set up rules to run a particular filter on a matching set of files. An example: run files ending with .sass through sassc. The difference is that webpack always starts at an entry point and only walks the dependency graph. If you want to include a sass file, you need to `require('foo.sass')` (without assigning it to anything) from your foo.js. It will then inline the resulting CSS into the single output bundle.js file and you'll have to split out the CSS with another plugin if you want it in a different file.
If you're just using grunt/gulp to build assets then using webpack will save you effort/maintenance but if you also need to copy files around, ping servers, kick of CI, or some other side effect then you'll need some shell script or build runner in addition.
36 comments
[ 3.7 ms ] story [ 99.3 ms ] threadPackaging all files into a single one is a side effect that we don't really care about. If you want to build your app with babeljs, you need to compile all your backend files. Who cares what the output is, if it's multiple files or a single file? As long as it's semantically the same (meaning even __dirname and friends work appropriately), it doesn't matter.
But what you get is really powerful build system (much better than hacking one together with gulp). Just look how small my config is, and now you can add babel as a loader for JS files and it just works. And you get to use the exact same infrastructure for the frontend.
Webpack also handles sourcemaps flawlessly, and you get tons of other stuff like http://webpack.github.io/docs/hot-module-replacement.html.
For example, you get hashed filenames (for far-future cache expiration in the browser) for free (no manifests or runtime reconciliation of names to assets necessary).
I second this. (Disclaimer: I wrote React Hot Loader.)
Webpack's live reloading system is not browser-specific, does not depend on attaching debuggers or doing anything else invasive.
All it does is represent module cache as (id) -> (function) map and give you the tools to “handle” module updates, as if modules were Observables and you subscribed to “new versions” of them. If update is unhandled, it bubbles.
This is what allows Hot Module Replacement to work for React components, CSS and Markdown files, and even classes on backend.
What I'd like to see is for webpack to add features from Pants like self-bootstrapping executables (PEX) or run tests based on which part of the code was affected by a commit. For the executable part, I guess Docker kind of solve that issue. See http://pantsbuild.github.io/ for more info
To be continued :)
In 2015, we have ES6 modules now. Instead of define/require, we have import/export and it is standards based now, which is nice.
For systems that do not support ES6 syntax directly, this is provided today with tools like SystemJS [1] and jspm [2]. SystemJS is great because it supports all of the module formats for backwards compatibility. jspm is great because it doesn't matter where you grab your dependencies from (npm/github/bower/etc).
I agree with the authors comment about gulpfiles being hacky and not very DRY (don't repeat yourself). That said, his examples felt very hacked together as well, there is too much programming in there. Do I copy that build file across every new project I create?
gulpfiles are great because they provide extra functionality that is missing, like only re-transpiling files that change. For large projects this can really be a time saver. webpack has that by running a separate server process, complicated! Projects like gulp-helpers [3] try to bring a tiny bit of sanity and re-usability to gulpfiles by making things a bit more DRY and configuration based. It is just an example of one way to do things, but hopefully you see my point.
[1] https://github.com/systemjs/systemjs [2] http://jspm.io/ [3] https://github.com/lookfirst/gulp-helpers
Wouldn't using something like Babel remove that issue?
The problem is supporting dependencies. You need something that can load everything, which is the functionality that SystemJS provides.
The infrastructure is the important piece, not the module syntax. Webpack provides this infrastructure, and it's easy to provide it for ES6 modules as well.
For example: how do I hot reload modules? How do I eval code inside a module? Webpack allows you to do all of this, and is more advanced than anything out there. SystemJS and jspm are nice but I still find webpack to support way more features.
What do you mean "hacked together"? Look at how small my config is! Do you know how much you get from that small config? The only thing hacky is the `node_modules` hack, and as far as I know, you'd have to do something similar with anything else (I don't see anyone using SystemJS/jspm on the backend).
Also, re-transpiling files that change? Just fire up the watcher (`webpack --watch`) and webpack automatically does this...
That's what makes SystemJS appealing; the infrastructure is the ES6 (now WhatWG) Loader Specification; a spec that browsers will be implementing. So you don't have to worry about learning yet-another-module-loader like you do when jumping from requirejs -> browserify -> webpack -> whatever's next trends.
For hot module replacement, sure, it gets a little more complex. You add another plugin and another entry point, that's all.
I disagree that build systems need to be complex. They get complex because people try to invent too many different ways of doing things instead of working towards standards. webpack is a prime example of that.
I'd love to see a full demo seed example of your ideal build system. Something that includes hot code swapping and even more importantly, unit testing.
Webpack solves a LOT of problems with application development. Handling assets properly is very difficult, and webpack makes it straightforward.
Build systems are complicated, I'd love to see something that handles the same problems as webpack but somehow manages to avoid the required configuration.
Yes, build systems are complex, because people need features, even if you personally don't need them. Webpack doesn't offer many ways to do the same thing; it just simply has a lot of features. Whenever we get enough tooling around ES6 modules to match it (or come close), I'll gladly switch.
You'll see a fuller example later. I'd love to see a matching set up using systemjs/jspm. You could convince me to switch.
posted March 16, 2015.
Same as '.bin' === x?
I use the following regexp: /^[a-z\-0-9]+$/
Any reason to get the full module list over just using this regexp?
But that works too!
The article seems to be saying this, but am I correct to come away thinking of webpack as a "module-aware build runner" that replaces both gulp and browserify (for example)?
If you're just using grunt/gulp to build assets then using webpack will save you effort/maintenance but if you also need to copy files around, ping servers, kick of CI, or some other side effect then you'll need some shell script or build runner in addition.