Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

Shimming a package with webpack

There's a javascript file that I need to use in my project as a dependency. It doesn't have a github repository, it's not on bower, or npm, it just lives here.

http://a.klaviyo.com/media/js/learnmarklet.js

I can install it with bower with:

bower install http://a.klaviyo.com/media/js/learnmarklet.js --save

I know that it will then live in my project at:

./bower_components/learnmarklet/index.js

And I know it attaches a variable called _learnq to the global window object.

What I want is simply this.

var _learnq = require("klaviyo")

I need to alias klaviyo something like this.

{
  "klaviyo": "./bower_components/learnmarklet/index.js"
}

And "shim" an export of the _learnq variable like this.

{
  "klaviyo": "_learnq"
}

How can I do this with webpack?

This is what i've tried, this is what my webpack.config.js looks like.

module.exports = {
  resolve:{
    alias:{
      "klaviyo": "./bower_components/learnmarklet/index.js"
    }
  },
  externals: {
    klaviyo: "_learnq"
  }
}
like image 694
ThomasReggi Avatar asked Mar 12 '15 18:03

ThomasReggi


People also ask

What is shimming in webpack?

The webpack compiler can understand modules written as ES2015 modules, CommonJS or AMD. However, some third party libraries may expect global dependencies (e.g. $ for jQuery ). The libraries might also create globals which need to be exported.

Does webpack automatically minify?

Webpack v4+ will minify your code by default in production mode .

Can webpack improve performance?

Code Splitting. Code splitting is a feature provided by webpack to split your code into multiple bundles which can be used on-demand. Code splitting results in reduced bundle size which can help us in improving the load time, hence, improving the performance.


1 Answers

In your example, your code will kind of conflict, the externals basically says

require('klaviyo')

should be rewritten to

window._learnq

and the alias says

require('klaviyo')

basically does

require('./bower_components/learnmarklet/index.js')

What I would recommend is this:

module.exports = {
  resolve:{
    alias:{
      // Make it so that 'require' finds the right file.
      "klaviyo": "./bower_components/learnmarklet/index.js"
    }
  },
  module: {
    loaders: [{
      // Rewrite the file so that it exports the window global.
      test: __dirname + '/bower_components/learnmarklet/index.js',
      loader: 'exports?window._learnq'
    }]
  }
}

You's need to npm install exports-loader as well.

like image 137
loganfsmyth Avatar answered Oct 16 '22 20:10

loganfsmyth