2

As title says I'm developing an Angular 2 application using typescript, jquery and webpack (to dist js and css files).

From a controller, when I need to access jquery ($) I have to always import it like:

var $: JQueryStatic = require('jquery');

at the top of each controller which need jQuery functions.

For more information, here is my webpack.config file:

const path = require('path');
const webpack = require('webpack');
const ExtractTextPlugin = require('extract-text-webpack-plugin');
const merge = require('webpack-merge');

module.exports = (env) => {
    const extractCSS = new ExtractTextPlugin('vendor.css');
    const isDevBuild = !(env && env.prod);
    const sharedConfig = {
        stats: { modules: false },
        resolve: { extensions: ['.js'] },
        module: {
            rules: [
                { test: /\.(png|woff|woff2|eot|ttf|svg)(\?|$)/, use: 'url-loader?limit=100000' },
                { test: /jquery-mousewheel/, loader: "imports-loader?define=>false&this=>window" },
                { test: /malihu-custom-scrollbar-plugin/, loader: "imports-loader?define=>false&this=>window" }
            ]
        },
        entry: {
            vendor: [
                '@angular/common',
                '@angular/compiler',
                '@angular/core',
                '@angular/flex-layout',
                '@angular/http',
                '@angular/material',
                '@angular/platform-browser',
                '@angular/platform-browser-dynamic',
                '@angular/router',
                '@angular/platform-server',
                'angular2-universal',
                'angular2-universal-polyfills',
                'bootstrap',
                //'bootstrap/dist/css/bootstrap.css',
                'es6-shim',
                'es6-promise',
                'font-awesome/css/font-awesome.css',
                'event-source-polyfill',
                'hammerjs',
                'jquery',
                'jquery-mousewheel',
                'malihu-custom-scrollbar-plugin',
                'malihu-custom-scrollbar-plugin/jquery.mCustomScrollbar.css',
                'swiper',
                'swiper/dist/css/swiper.css',
                'zone.js',
            ]
        },
        output: {
            publicPath: '/dist/',       // Specifies the public URL address of the output files when referenced in a browser
            filename: '[name].js',      // Specifies the name of each output file on disk
            library: '[name]_[hash]'    // Export the bundle as library with that name
        },
        plugins: [
            new webpack.ProvidePlugin({ $: 'jquery', jQuery: 'jquery', jquery: 'jquery', Hammer: "hammerjs/hammer" }), // Maps these identifiers to the jQuery package (because Bootstrap expects it to be a global variable)
            new webpack.ContextReplacementPlugin(/\@angular\b.*\b(bundles|linker)/, path.join(__dirname, './ClientApp')), // Workaround for https://github.com/angular/angular/issues/11580
            new webpack.IgnorePlugin(/^vertx$/) // Workaround for https://github.com/stefanpenner/es6-promise/issues/100
        ]
    };

    const clientBundleConfig = merge(sharedConfig, {
        output: { path: path.join(__dirname, 'wwwroot', 'dist') },
        module: {
            rules: [
                { test: /\.css(\?|$)/, use: extractCSS.extract({ use: 'css-loader' }) }
            ]
        },
        plugins: [
            extractCSS,
            new webpack.DllPlugin({
                path: path.join(__dirname, 'wwwroot', 'dist', '[name]-manifest.json'),
                name: '[name]_[hash]'
            })
        ].concat(isDevBuild ? [] : [
            new webpack.optimize.UglifyJsPlugin()
        ])
    });

    const serverBundleConfig = merge(sharedConfig, {
        target: 'node',
        resolve: { mainFields: ['main'] },
        output: {
            path: path.join(__dirname, 'ClientApp', 'dist'),
            libraryTarget: 'commonjs2',
        },
        module: {
            rules: [{ test: /\.css(\?|$)/, use: ['to-string-loader', 'css-loader'] }]
        },
        entry: { vendor: ['aspnet-prerendering'] },
        plugins: [
            new webpack.DllPlugin({
                path: path.join(__dirname, 'ClientApp', 'dist', '[name]-manifest.json'),
                name: '[name]_[hash]'
            })
        ]
    });

    return [clientBundleConfig, serverBundleConfig];
}

Is there a way to not have to do that declaration each time?

Thanks in advance

1
  • 1
    You always have to import or declare external objects you are using in each component. You can have webpack bundle it, but external objects still have to be declared or imported in each component. Commented Feb 22, 2017 at 14:37

1 Answer 1

3

Yes, you can do this, if you update plugins in your webpack.config.js in this way:

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

do not forget before install necessary dependencies:

npm install jquery --save
npm install @types/jquery --save-dev
Sign up to request clarification or add additional context in comments.

1 Comment

My webpack already contains those statements and I've already installed jquery and @types/jquery. See my webpack.config file in my updated question please.

Your Answer

By clicking “Post Your Answer”, you agree to our terms of service and acknowledge you have read our privacy policy.

Start asking to get answers

Find the answer to your question by asking.

Ask question

Explore related questions

See similar questions with these tags.