Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

Include only jquery slim in webpack build?

How do I include only jquery slim in my webpack build?

Right now, I'm including jquery like this and it is working fine, but I don't want to load the entire library..

webpack.config.js

module.exports = {
...
 module: {
  rules: [
   ...
    {
        test: require.resolve('jquery'),
        use: [{
            loader: 'expose-loader',
            options: 'jQuery'
        },
        {
            loader: 'expose-loader',
            options: '$'
         }]
    }
  ]
  ...
  plugins: [
   new webpack.ProvidePlugin({
        $: 'jquery',
        jQuery: 'jquery'
    })
  ]
 }

}

I couldn't find offical jquery-slim package in npm, so I guess the idea is to install the whole jquery package and only use what I want from there, but I wasn't able to find how to do that.

like image 814
mirta Avatar asked Feb 14 '19 09:02

mirta


2 Answers

jquery-slim.js is shipped within the npm package of jquery.
It's in node_modules/jquery/dist/jquery-slim.js.

So all you need to do is direct the loader and the plugin to the jquery.slim.js path:

module.exports = {
...
 module: {
  rules: [
   ...
    {
        test: require.resolve('jquery/dist/jquery.slim'),
        use: [{
            loader: 'expose-loader',
            options: 'jQuery'
        },
        {
            loader: 'expose-loader',
            options: '$'
         }]
    }
  ]
  ...
  plugins: [
   new webpack.ProvidePlugin({
        $: 'jquery/dist/jquery.slim',
        jQuery: 'jquery/dist/jquery.slim'
    })
  ]
 }

}
like image 63
Ramy Ben Aroya Avatar answered Nov 20 '22 23:11

Ramy Ben Aroya


There is a jquery-slim package in npm but it's not official, so i don't recommend using it.

npm versions of jQuery already included jquery-slim (source code, source maps, and minified versions). When you install it from npm it can be found on

ls node_modules/jquery/dist/jquery.slim.*

I found that the easiest and more secure way to import slim, specially if you don't need jQuery to be a global, is use an alias. In Webpack@4:

resolve: {
    alias: {
        // "jquery/dist/jquery.js" or "jquery/dist/jquery.slim.js"
        jquery: "jquery/dist/jquery.slim.js",
    }
},

In fact I always use the alias, because by accident you can end with two jQuery versions in your bundle if someone is messing up with paths.

For example when using (without an alias)

import $ from "jquery/dist/jquery.slim.js"
import "bootstrap"

Webpack will put both versions in the bundle, because Bootstrap will require just "jquery".

To use the alias nothing special is need:

import $ from "jquery";

Very Roughly speaking. When Webpack tries to import "jquery" module, first will loot at the alias, and if that "name" exists the alias value will be used. If not, it will go to node_modules/jquery, read the main property of the package.json that points out to dist/jquery.js and puts that file/module in the $ name.

The alias are used (afaik) always before other method resolution, so you can use it with the ProvidePlugin or exposes-loader.

By the way:

  • For many cases you don't need special configuration for libraries depending on jQuery. Nowadays, most of then, like Bootstrap, will work out of the box
  • I don't think that use exposes-loader at the same time that ProvidePlugin is need, or even that is a good idea.

expose-loader, expose the module as global variable. So each time "$" or name exposed is not found in the local context, it will be searched at the global context(window) in the browser.

ProvidePlugin, "cheats" or "fakes" the libraries. Each time "$" is not found in the context, Webpack will replace it with (something like) require("jquery"). This does not expose the variable as global but will work for most of the cases.

As previously said, ProvidePlugin will use the alias, so this config will use de js file specified in the alias.

plugins: [
    new webpack.ProvidePlugin({
        // use all aliases or only what you need. 
        "$": "jquery",
        "jQuery": "jquery",
        "window.$": "jquery",
    }),
]

If you don't want to use expose-loader, but need jQuery as global doing it in your own code in the "entry script" is also fine:

import $ from "jquery";

window.$ = window.jQuery = $;
like image 35
Francisco Puga Avatar answered Nov 20 '22 22:11

Francisco Puga