timetofly
timetofly

Reputation: 3077

How to make "require('jquery')" automatically load with many jquery plugins/extensions in webpack?

There are a number of plugins I want jquery to automatically have. In a regular site I would simply include jquery and the script in order. How do I accomplish this with webpack? Assume there is no npm package for the plugins and I just want to load them from files.

Upvotes: 2

Views: 812

Answers (1)

Dwayne Crooks
Dwayne Crooks

Reputation: 2857

I will assume the following directory structure:

project
  |- app
  |   |- vendor
  |   |    |- plugins
  |   |    |    |- plugin-1.js
  |   |    |    |- plugin-2.js
  |   |    |    |- ...
  |   |    |
  |   |    |- jquery.js
  |   |
  |   |- jquery-with-plugins.js
  |   |- main.js
  |
  |- js
  |   |- bundle.js
  |
  |- webpack.config.js
  |- package.json
 ...

And here are the contents of the key files:

// app/jquery-with-plugins.js
require('vendor/jquery');
req = require.context('vendor/plugins', true, /\.js$/);
req.keys().forEach(function (plugin) {
  req(plugin);
});

module.exports = jQuery;

// app/main.js
var $ = require('jquery');

$(function () {
  $('.selector-1').use_plugin_1();
  $('.selector-2').use_plugin_2();
});

// webpack.config.js
var path = require('path');

module.exports = {
  context: path.join(__dirname, 'app'),
  entry: './main',
  output: {
    path: path.join(__dirname, 'js'),
    filename: 'bundle.js'
  },
  module: {
    loaders: [
      {
        test: /\.js$/,
        include: [
          path.join(__dirname, 'app/vendor')
        ],
        loader: 'script'
      }
    ]
  },
  resolve: {
    alias: {
      'jquery$': path.join(__dirname, 'app/jquery_with_plugins'),
      'vendor': path.join(__dirname, 'app/vendor')
    }
  },
  extensions: ['', '.js']
};

// package.json
{
  "name": "temp",
  "version": "0.0.0",
  "private": true,
  "scripts": {
    "build": "webpack --progress --colors"
  },
  "devDependencies": {
    "node-libs-browser": "^0.5.0",
    "script-loader": "^0.6.1",
    "webpack": "^1.9.4"
  }
}

Every JavaScript file in the app/vendor directory has been configured to load with the script-loader and hence will be executed in the global context. In app/jquery-with-plugins.js I first load jQuery and then every plugin so by the time I export jQuery (N.B. I don't have to export jQuery since it's already globally exposed but I think it's better to use CommonJS modules from here on out.) every plugin would already be attached to the jQuery object.

I've aliased jquery to refer to app/jquery-with-plugins.js (see the resolve.alias config) and hence I can require jQuery with all the plugins by simply doing require('jquery'). Even better, to be able to add a plugin and use it immediately you just need to add it to app/vendor/plugins. An example of that is shown in app/main.js

Finally, everything can be bundled to js/bundle.js by running npm run build.

Upvotes: 2

Related Questions