Skip to content

Instantly share code, notes, and snippets.

@OliverJAsh
Created October 28, 2014 11:34
Show Gist options
  • Star 11 You must be signed in to star a gist
  • Fork 0 You must be signed in to fork a gist
  • Save OliverJAsh/bcc676e381a06dbb3be0 to your computer and use it in GitHub Desktop.
Save OliverJAsh/bcc676e381a06dbb3be0 to your computer and use it in GitHub Desktop.
webpack experiment and comparison against jspm

webpack: http://webpack.github.io/ jspm: http://jspm.io/

Nice introduction presentation: http://peerigon.github.io/presentations/2014-07-09-MNUG-webpack/

The watch seems intelligent in that it might be tracing the dependency graph. In my test case it seems to, at least. AMD and CommonJS modules are supported out of the box. In my test I was unable to get es6-loader working (see commit in link below).

Unlike jspm, it's not a registry. Instead it resolves dependencies from node_modules (i.e. npm) by default (like browserify), although according to this tutorial it's trivial to configure which directories the module resolver should read from.

My test:

  • "foo depends on bar"
  • "foo depends on bar depends on x" (transitive dependency)

Both cases seemed to work with no problems. See my commit log: https://github.com/OliverJAsh/webpack-experiment/commits/master

You can configure webpack to recognise other files types (e.g. LESS, ES6) and do things with them (compile, load them (e.g. applying some CSS styles to the page)) with what they call "loaders". I quickly stumbled across a problem with this infrastructure: given "foo depends on bar depends on baz", where "baz" is an ES6 module, ideally "bar" should contain the configuration for handling its ES6 dependency (by configuring the es6-loader). In webpack however, all of the loaders must be defined by the consumer – they are not defined at the module level. So, the consumer of "foo" needs to know that "bar" contains an ES6 module ("baz"), and they must configure webpack to use the es6-loader.

IIRC, the above problem doesn't happen with jspm’s plugins. jspm-cli creates a config.js file for the consumer by traversing the dependency graph, at which point it will add the plugin as a path (because the plugin is defined as a dependency, e.g. https://github.com/guardian/developers-site/blob/56d25a69600e9bb67ddff8f56aaa7e23011647ba/package.json#L25). Therefore, the consumer is never concerned about the nature of transitive dependencies – they just work because jspm automatically aggregates all dependency and plugin information into config.js.

Generally speaking, I prefer the idea of polyfilling the future’s technology instead of writing hacks for today’s technology. Whilst webpack supports ES6 modules, it's not harnessing the ES6 Module Loader. I'm biased, but from my experience with webpack and jspm so far, I would say jspm is definitely much more intuitive, standard compliant, and well thought out.

@zigomir
Copy link

zigomir commented Jan 10, 2015

Thanks for the writeup!

@waltfy
Copy link

waltfy commented Mar 10, 2015

Great writeup. I very much agree with your findings and have been through a similar experience myself.

@mattdesl
Copy link

In webpack however, all of the loaders must be defined by the consumer – they are not defined at the module level.

This was one of my concerns when I first evaluated webpack. The proposed solution (Concord) looks tremendously complex.

@rauschma
Copy link

I found webpack quite straightforward to use. This is my webpack.config.js:

    var path = require('path');
    module.exports = {
        entry: './es6/main.js',
        output: {
            path: __dirname,
            filename: 'bundle.js'
        },
        module: {
            loaders: [
                { test: path.join(__dirname, 'es6'),
                  loader: 'babel-loader' }
            ]
        }
    };

That is, ./es6 contains all my ES6 code and I install external (ES5) code via npm. All my ES6 files have the file name extension .js and are unaware that a loader is involved.

Details: http://www.2ality.com/2015/04/webpack-es6.html

@limscoder
Copy link

Since ES5 is a subset of ES6, you can use an ES6 module loader for ALL .js files. However, you may still want to exclude modules for build speed reasons. Webpack's config is pretty simple for including and excluding paths that loaders apply to.

It only really makes sense for webpack config to be applied to the top consumer. If each module had it's own config, you'd run into problems: what if one module packages React, and another marks it as external, what if one module includes css requires and another uses the extract text plugin, what if one module uses esnext and another uses babel?

@capaj
Copy link

capaj commented Sep 5, 2015

@rauschma yes, it is not very hard for trivial web development. But as soon as we are doing anything even a bit more complex-like developing a library, webpack shotcomings start to show and slow us down.

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment