Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

Avoid bundling lib dependencies with webpack + handlebars loader

I'm writing a library using handlebars templates and I want to use Webpack to bundle it. I'm using handlebars-loader so that I can require and precompile the templates.

However I don't want handlebars (nor handlebars/runtime) to be included in my compiled library and thus, I would like to set them as externals.

Here is my config file:

module.exports = {
    context: __dirname + '/src',
    entry: './index.js',
    output: {
        path: __dirname + '/dist',
        filename: 'stuff.js',
        libraryTarget: 'umd',
        library: 'Stuff'
    },
    externals: [{
        'handlebars/runtime': {
            root: 'Handlebars',
            amd: 'handlebars.runtime',
            commonjs2: 'handlebars/runtime',
            commonjs: 'handlebars/runtime'
        }
    }],
    module: {
        loaders: [
            { test: /\.handlebars$/, loader: 'handlebars-loader' }
        ]
    }
};

Unfortunately it doesn't work and handlebars-loader still makes handlebars/runtime to be bundled...

I believe it is because I do not require handlebars/runtime directly, rather it is required in the code added by the loader.

Is there a way to mark it as external?

Edit: I know I need handlebars/runtime to compile my template. But as I am building a library, I want it to be provided by the user of the library instead of being included. This way, if my user is also using Handlebars, the library is not loaded twice. I believe it is good practice for libraries to avoid bundling any dependency (it is something we see much too often in my humble opinion).

like image 244
Quentin Roy Avatar asked Mar 30 '15 14:03

Quentin Roy


1 Answers

The handlebars-loader's team helped me solve this issue.

The problem is that handlebars-loader, by default, loads handlebars' runtime using an absolute path. However, it is possible to use the runtime argument of the handlebar loader to specify a different path for handlebars' runtime. It is then possible to set this path as external.

This is working:

module.exports = {
    context: __dirname + '/src',
    entry: './index.js',
    output: {
        path: __dirname + '/dist',
        filename: 'stuff.js',
        libraryTarget: 'umd',
        library: 'Stuff'
    },
    externals: [{
        'handlebars/runtime': {
            root: 'Handlebars',
            amd: 'handlebars/runtime',
            commonjs2: 'handlebars/runtime',
            commonjs: 'handlebars/runtime'
        }
    }],
    module: {
        loaders: [
            { test: /\.handlebars$/, loader: 'handlebars-loader?runtime=handlebars/runtime' }
        ]
    }
};
like image 200
Quentin Roy Avatar answered Oct 18 '22 22:10

Quentin Roy