简体   繁体   中英

Angular 2 + Typescript + jQuery + webpack: $ not defined

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

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

The technical post webpages of this site follow the CC BY-SA 4.0 protocol. If you need to reprint, please indicate the site URL or the original address.Any question please contact:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM