如何在webpack中导入jquery

12

我在使用 Webpack 时,使用 jQuery 出现了问题。

我的代码:

const path = require('path');
const webpack = require('webpack');
const CleanWebpackPlugin = require('clean-webpack-plugin');
const ExtractTextPlugin = require("extract-text-webpack-plugin");
const UglifyJsPlugin = require('uglifyjs-webpack-plugin');
const CompressionPlugin = require("compression-webpack-plugin");

module.exports = {
    entry: {
        vendor: [
            './src/main/webapp/js/vendor/jquery-3.3.1.min.js',
            // './src/main/webapp/js/vendor/fs.js',
            './src/main/webapp/js/vendor/google-adsense.js',
            './src/main/webapp/js/vendor/jquery.menu-aim.min.js',
            './src/main/webapp/js/vendor/jquery.touchSwipe.min.js',
        ],
        app: './src/main/assets/js/desktop/app.js',
        mobile: './src/main/assets/js/mobile/app.js',
        touch: './src/main/assets/js/touch/app.js',
    },
    module: {
        rules: [{
                test: /\.js$/,
                exclude: /(node_modules|bower_components)/,
                use: {
                    loader: 'babel-loader',
                    options: {
                        presets: ['@babel/preset-env']
                    }
                }
            },
            {
                test: require.resolve('jquery'),
                loader: 'expose-loader?jQuery!expose-loader?$'
            }
        ],
    },
    plugins: [
        // new CleanWebpackPlugin(['src/main/webapp/assets']),
        new webpack.optimize.CommonsChunkPlugin({
            name: 'common' // Specify the common bundle's name.
        }),
        new UglifyJsPlugin({
            test: /\.js$/,
            sourceMap: process.env.NODE_ENV === "development"
        }),
        new webpack.ProvidePlugin({
            $: "jquery",
            jQuery: "jquery"
        })
    ],
    output: {
        filename: '[name].js',
        path: path.resolve(__dirname, './src/main/webapp/js')
    }
};

当上述代码编译时,控制台会抛出以下错误:

vendor.js:1 Uncaught ReferenceError: webpackJsonp未定义 at vendor.js:1

并且当我尝试使用它时

externals: {
  jquery: 'jQuery'
}

它扔

vendor.js:1 Uncaught ReferenceError: jQuery is not defined
    at Object.231 (vendor.js:1)
    at o (common.js:1)
    at Object.228 (vendor.js:1)
    at o (common.js:1)
    at window.webpackJsonp (common.js:1)
    at vendor.js:1

我在我的核心JS文件中使用了jQuery:import $ from 'jquery'。我做错了什么?需要帮助,谢谢。


@JordiCastilla 上面的链接没有解决我的问题。我还在这里苦恼 :(. 有什么建议吗? - batgerel.e
你检查了所有的帖子吗?在我看来,你可能错过了npm i jquery --save或者链接问题中定义的其他小部分。 - Jordi Castilla
我试过使用npm install jquery --savenpm update等命令。 - batgerel.e
1
你如何“使用”jQuery? - Aluan Haddad
显示剩余6条评论
1个回答

20

你的webpack配置文件中有几个主题存在冲突。我会将它们列出来,以便更好地理解你尝试实现的目标。

主题1

你有一个名为vendor的入口,明显引用了一个已压缩jQuery库,你可能已经下载并放置在指定的目录中。

主题2

你还有一个expose-loader,它从node_modules中暴露了jquery库,并且可能在你的package.jsondependencies列表中。

这使得node_modules中的jquery在页面的全局作用域中作为$jQuery可用。

主题3

你还包括了ProvidePlugin,其中包含了jQuery的配置。

ProvidePlugin应该将依赖注入到模块代码的范围内,这意味着你不需要写import $ from 'jquery',而是可以在所有模块中直接使用$jQuery

结论

从我的了解中我认为你正在尝试从./src/main/webapp/js/vendor/jquery-3.3.1.min.js静态文件中打包jQuery到一个供应商包中。

然后你试图将供应商包中的库暴露到全局作用域(即jQuery)中。

最后,使你的应用程序代码能够从在全局作用域中提供的供应商包中导入jQuery。

答案

所以如果这就是你要做的事情,你需要执行以下步骤:

首先,在你的package.json文件的dependencies中检查是否有jquery。如果有,你可以将其删除,因为如果你使用jquery-3.3.1.min.js文件来提供jQuery,则不需要它。

其次,将expose-loadertest更改为当看到你的入口中的jquery-3.3.1.min.js文件时触发匹配,而不是从node_modules中解析jquery依赖关系。

这个正则表达式模式应该就能解决问题。

{
  test: /jquery.+\.js$/,
  use: [{
      loader: 'expose-loader',
      options: 'jQuery'
  },{
      loader: 'expose-loader',
      options: '$'
  }]
}

第三,如果你使用 import $ from 'jquery' 显式地导入库,则需要删除 ProvidePlugin

最后,你需要告诉 webpack 当它看到对 jquery 的导入时,可以从全局范围内的 window.jQuery 解析它。你可以通过已引用的 externals 配置来实现这一点。

externals: {
  jquery: 'jQuery'
}

按照这些更改,你应该最终得到一个看起来像这样的webpack.config.js文件。

const path = require('path');
const webpack = require('webpack');
const CleanWebpackPlugin = require('clean-webpack-plugin');
const ExtractTextPlugin = require("extract-text-webpack-plugin");
const UglifyJsPlugin = require('uglifyjs-webpack-plugin');
const CompressionPlugin = require("compression-webpack-plugin");

module.exports = {
    entry: {
        vendor: [
            './src/main/webapp/js/vendor/jquery-3.3.1.min.js',
            // './src/main/webapp/js/vendor/fs.js',
            './src/main/webapp/js/vendor/google-adsense.js',
            './src/main/webapp/js/vendor/jquery.menu-aim.min.js',
            './src/main/webapp/js/vendor/jquery.touchSwipe.min.js',
        ],
        app: './src/main/assets/js/desktop/app.js',
        mobile: './src/main/assets/js/mobile/app.js',
        touch: './src/main/assets/js/touch/app.js',
    },
    module: {
        rules: [{
                test: /\.js$/,
                exclude: /(node_modules|bower_components)/,
                use: {
                    loader: 'babel-loader',
                    options: {
                        presets: ['@babel/preset-env']
                    }
                }
            },
            {
                test: /jquery.+\.js$/,
                use: [{
                    loader: 'expose-loader',
                    options: 'jQuery'
                },{
                    loader: 'expose-loader',
                    options: '$'
                }]
            }
        ],
    },
    plugins: [
        // new CleanWebpackPlugin(['src/main/webapp/assets']),
        new webpack.optimize.CommonsChunkPlugin({
            name: 'common' // Specify the common bundle's name.
        }),
        new UglifyJsPlugin({
            test: /\.js$/,
            sourceMap: process.env.NODE_ENV === "development"
        })
    ],
    output: {
        filename: '[name].js',
        path: path.resolve(__dirname, './src/main/webapp/js')
    },
    externals: {
        jquery: 'jQuery'
    }
};

我希望这不仅仅给你答案,还足够解释你犯了哪些错误。


非常感谢。现在我明白我到底做错了什么。这解决了我的问题! :) - batgerel.e
太好了,很高兴能帮到你! :) - jshbrntt
1
现在为了将jQuery导入Rails应用程序,一个人必须做所有这些事情吗?这是什么鬼? - Mark Boulder
3
@MarkBoulder,有许多种方法可以剥皮,但都是错误的 ;) - jshbrntt
1
你可能需要使用以下代码替代原有的代码:{loader: "expose-loader", options: { exposes: ["$", "jQuery"] }},并将其作为 test: /jquery.+\.js$/use 的唯一项。详情请参见 https://github.com/dao42/rails-template/issues/29。 - Raffi

网页内容由stack overflow 提供, 点击上面的
可以查看英文原文,
原文链接