webpack and jQuery: Include only the parts you need
Recently I decided to try out webpack as a replacement for Browserify, and it didn’t disappoint! Out-of-the-box, webpack even support’s AMD, so RequireJS-based libraries can be used as-is. This got me thinking, jQuery switched to RequireJS a while back for their source code and build process, so I questioned:
Could webpack be used to load individual jQuery modules?
As web technologies advance, it is getting harder to justify loading large frameworks, even one a powerful and flexible as jQuery. A while back, jQuery made it possible to build custom builds of jQuery, but this solution is not very flexible and requires extra maintenance. It would be great if there was a way to only package modules you are using, and dynamically discard the bloat of unused functionality.
With webpack, I’m happy to say this is possible!
However, there are a few hoops to jump through, so I’ve assembled this tutorial.
This tutorial assumes basic knowledge of Node, NPM, and webpack and how to use them. If there tools are unfamiliar to you, you should start there.
Step 1: Initialize Your Project
First we need a project to work with. For sake of example I will initialize a Node.js project in a folder jquery-tutorial using the default settings.
$ npm init This utility will walk you through creating a package.json file. It only covers the most common items, and tries to guess sane defaults.
See `npm help json` for definitive documentation on these fields and exactly what they do.
Use `npm install <pkg> --save` afterwards to install a package and save it as a dependency in the package.json file.
Press ^C at any time to quit. name: (jquery-tutorial) version: (1.0.0) description: entry point: (index.js) test command: git repository: keywords: author: license: (ISC) About to write to .../jquery-tutorial/package.json:
Now we need to install our dependencies, such as jQuery.
Dependency 1: jquery
This is easy, just install jQuery through NPM. In this tutorial, I will use the default latest version, but a different version can be specified.
1 2 3 4 5
$ npm install --save-dev jquery npm WARN package.json firstname.lastname@example.org No description npm WARN package.json email@example.com No repository field. npm WARN package.json firstname.lastname@example.org No README data email@example.com node_modules/jquery
Dependency 2: sizzle
The jQuery package will not install this itself, and since the vast-majority of jQuery depends on jQuery’s Sizzle selector engine, you will probably want to install this. Again, I am using the latest version.
1 2 3 4 5
$ npm install --save-dev sizzle npm WARN package.json firstname.lastname@example.org No description npm WARN package.json email@example.com No repository field. npm WARN package.json firstname.lastname@example.org No README data email@example.com node_modules/sizzle
Dependency 3: amd-define-factory-patcher-loader
At this point, you are probably wondering what the heck that is, and why you need it. In a nutshell, one of jQuery’s source files is not compatible with spec-compliant AMD loaders. In RequireJS’s define implementation, the factory argument is optional, a quirk one of jQuery’s modules has come to depend on. I have an open pull request for this issue on the jQuery GitHub repository, however it has not yet been merged (update: my code has been merged, but it will not be available in the core until jQuery 3.0.0). As a solution for these instances, I created this webpack loader, so these problem files can be fixed on-the-fly. More on how to use this loader below.
1 2 3 4 5 6 7 8
$ npm install --save-dev amd-define-factory-patcher-loader npm WARN package.json firstname.lastname@example.org No description npm WARN package.json email@example.com No repository field. npm WARN package.json firstname.lastname@example.org No README data email@example.com node_modules/amd-define-factory-patcher-loader ├── firstname.lastname@example.org ├── email@example.com └── firstname.lastname@example.org (email@example.com, firstname.lastname@example.org, email@example.com, firstname.lastname@example.org, email@example.com)
Step 3: webpack config file
In order to use the loader, we are going to need to specify which files need transforming in our config file. Here is the file we will use in this tutorial, which will take care of the problematic jquery/src/selector.js file by passing it through the loader.
In order to load the jQuery core, all we need is the following code.
var $ = require('jquery/src/core');
However, by itself the jQuery core does not do much. You are going to need to include some of the other modules. All the modules use the same jQuery object, so it is unnecessary to set the to a variable. See the following examples:
Example 1: append
This example will append a new element to the body element.
1 2 3 4 5
var $ = require('jquery/src/core'); require('jquery/src/core/init'); require('jquery/src/manipulation');
Compiled with the webpack command, using the --display-modules argument, we can see the modules that get bundled.
Depending on the features you want to use, you are going to have to determine which jQuery modules are necessary. Depending on the feature, jQuery may be rather silent about the failure. Looking though the jQuery source files can help with this.