Rohan Büchner
Rohan Büchner

Reputation: 5393

Import jQuery Plugin. Angular 2 & Webpack

This is turning out to be more frustrating than I expected.

I've figured out how to include things like jQuery and bootstrap in my Webpack build process. But one of the 3rd party angular directives I've added require a specific jQuery plugin to be available on the global $ scope... for the life of me I cant find a simple clear example of how to do this.

This is the error code I keep getting:

Error: Error in ./SomeComponent class SomeComponent - inline template:5:32 caused by: $(...).selectize is not a function

I've seen examples of using script-loader, expose-loader, using resolve with an alias set, I've tried them all... but I don't seem to be having much luck as I'm new to Webpack, and I've probably managed to confuse myself more than anything in the last 2 days. I think I'm mixing different solutions, which might be adding to the chaos.

I've read through this post a few times, and it only explains how to load, jQuery itself... but not a jQuery plugin.

(some code excluded for brevity)

webpack.config.js

module.exports = {
  module: {
    loaders: [
      {
        test: /bootstrap-sass[\/\\]assets[\/\\]javascripts[\/\\]/,
        use: 'imports-loader?jQuery=jquery'
      },
      {
        test: require.resolve('selectize'),
        use: 'expose-loader?$!expose?selectize'
      }
    ]
  },
  plugins: [
    new webpack.ProvidePlugin({
      $: "jquery",
      jquery: "jquery",
      "window.jQuery": "jquery",
      jQuery:"jquery"
    }),
  resolve: {
    alias: {
      'selectize': path.resolve(
        __dirname,
        '../selectize/dist/js/selectize.min.js'
      )
    },
    extensions: [
      '.webpack.js',
      '.web.js',
      '.js',
      '.ts'
    ]
  },
  entry: {
    vendor: [
       ..
    ],
    main: `./${conf.path.src('index')}`
  }
};

app.ts

import 'script-loader!selectize';

Thus my question:

How do I load a 3rd party jQuery plugin in an Angular 2 application making use of a Webpack 2 module loader / build process.

Upvotes: 1

Views: 1358

Answers (2)

Rohan Büchner
Rohan Büchner

Reputation: 5393

I've managed to partially solve this using alias

webpack.config.js

 resolve: {
    alias: {
      selectize$: path.join(__dirname, '../node_modules/selectize'),
      // this can also be a path to an actual js file if you so choose
    }
  },

The above allows you to do this within whichever component you're working in:

import 'selectize';

then this within your template markup for the component:

<ng-selectize [config]="config" [options]="options"></ng-selectize>

The only problem I still have is how to serve the stylesheets in a similair fashion / include them in my vendor CSS bundle "automagically". For the time being I've copied the styles across, but will update this answer once I've figured it out.

Upvotes: 0

Tim Lewis
Tim Lewis

Reputation: 136

In our senario we had a external js file that needed to be added to the global scope. It wasn't in an npm package so we just included it directly. We achieved this as follows:

webpack.config.js

plugins: [
  ...
    new ProvidePlugin({
      $: "jquery",
      jQuery: "jquery"
    }),
  ...
]

main.browser.ts

P.S. main.browser.ts is a webpack entrypoint

require('expose?$!expose?jQuery!jquery');
require('../path_to_asset/selectize/dist/js/selectize.min.js');

We have a specific folder for all our assets like images, external js, etc.

Upvotes: 1

Related Questions