javascript 如何在 webpack 中导入 jquery
声明:本页面是StackOverFlow热门问题的中英对照翻译,遵循CC BY-SA 4.0协议,如果您需要使用它,必须同样遵循CC BY-SA许可,注明原文地址和作者信息,同时你必须将它归于原作者(不是我):StackOverFlow
原文地址: http://stackoverflow.com/questions/48579518/
Warning: these are provided under cc-by-sa 4.0 license. You are free to use/share it, But you must attribute it to the original authors (not me):
StackOverFlow
How to import jquery in webpack
提问by batgerel.e
I have a problem with jquery when i using it on webpack. My code:
我在 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')
}
};
When above code compiles , console throws this error
当上面的代码编译时,控制台抛出这个错误
vendor.js:1 Uncaught ReferenceError: webpackJsonp is not defined at vendor.js:1
vendor.js:1 未捕获的 ReferenceError:webpackJsonp 未在 vendor.js:1 中定义
And when i try to use this
当我尝试使用它时
externals: {
jquery: 'jQuery'
}
It throws
它抛出
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
And i using jquery in my core js file import $ from 'jquery'.
What did i do wrong ? any help ? Thank you.
我在我的核心 js 文件中使用 jquery import $ from 'jquery'。我做错了什么 ?有什么帮助吗?谢谢你。
回答by Joshua Barnett
So there are few themes in your webpack.config.js, some of which conflict. Just going to list them so I can better understand what I think you are trying to achieve.
所以你的 主题很少webpack.config.js,其中一些是冲突的。只是要列出它们,以便我可以更好地了解我认为您要实现的目标。
Theme 1
主题一
You have an entry called vendorthat is clearly referencing a minified jQuery library you have presumably downloaded and placed in the directory specified.
您有一个名为的条目vendor,该条目显然引用了您可能已下载并放置在指定目录中的缩小的 jQuery 库。
Theme 2
主题2
You also have an expose-loaderthat is essential exposing the jquerylibrary from its node_modulesprobably listed in the dependenciesof your package.json.
您还有一个expose-loader很重要的功能是将jquery库从其node_modules可能列在dependencies您的package.json.
This makes the jqueryin the node_modulesavailable as $and jQueryin the global scope of the page where your bundle is included.
这使得jquery在node_modules现有的$和jQuery在包括捆绑软件页面全局范围。
Theme 3
主题 3
You also have included the ProvidePluginwith configuration for jQuery.
您还包含了ProvidePluginjQuery的with 配置。
The ProvidePluginis supposed to inject dependencies into the scope of your module code, meaning you do not need to have import $ from 'jquery'instead $and jQuerywill already be available in all of your modules.
在ProvidePlugin应该依赖注入你的模块代码的范围,这意味着你不需要拥有import $ from 'jquery',而不是$和jQuery将已经在所有可用模块。
Conclusion
结论
From what I have gathered I thinkyou're trying to bundle jQuery from the static file at ./src/main/webapp/js/vendor/jquery-3.3.1.min.jsin a vendor bundle.
从我收集的信息来看,我认为您正在尝试将 jQuery 从静态文件./src/main/webapp/js/vendor/jquery-3.3.1.min.js中的一个供应商捆绑包中捆绑。
You are then trying to expose the libraries in the vendor bundle to the global scope (jQuery).
然后,您尝试将供应商包中的库公开到全局范围 (jQuery)。
Then also have your application code able to import jQuery from what is made available by the vendor bundle in the global scope.
然后还让您的应用程序代码能够从全局范围内的供应商包提供的内容中导入 jQuery。
Answer
回答
So if that is what you are doing you need to do the following things.
因此,如果这就是您正在做的事情,您需要做以下事情。
Firstly, check in your package.jsonfiles dependenciesfor jquery. If its there you want to remove it, there's no need for it if you're going to use your jquery-3.3.1.min.jsfile instead to provide jQuery to your application.
首先,检查您的package.json文件dependencies以获取jquery. 如果您想删除它,那么如果您打算使用您的jquery-3.3.1.min.js文件来为您的应用程序提供 jQuery ,则不需要它。
Secondly, change your testof the expose-loaderto trigger when it sees your jquery-3.3.1.min.jsfile in your entries, not resolve it from the jquerydependency from your node_modules.
其次,你的改变test的expose-loader,以触发,当它看到你的jquery-3.3.1.min.js文件在你的项目,从没有解决它jquery依赖从你的node_modules。
This regex pattern should do the trick.
这个正则表达式模式应该可以解决问题。
{
test: /jquery.+\.js$/,
use: [{
loader: 'expose-loader',
options: 'jQuery'
},{
loader: 'expose-loader',
options: '$'
}]
}
Thirdly, remove the ProvidePluginif you're going to import the library explicitly with import $ from 'jquery'you do not need it.
第三,ProvidePlugin如果您要显式导入import $ from 'jquery'您不需要的库,请删除它。
Lastly, you need to tell webpack when it sees an import for jqueryit can resolve this from window.jQueryin the global scope. You can do this with the externals configuration you already referenced.
最后,你需要告诉 webpack 当它看到一个导入时jquery它可以window.jQuery在全局范围内解决这个问题。您可以使用已引用的外部配置来执行此操作。
externals: {
jquery: 'jQuery'
}
With all these changes you should end up with a webpack.config.jsfile that looks like this.
通过所有这些更改,您应该最终得到一个如下所示的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'
}
};
I hope that does not just give you the answer but enough explanation as to where you were going wrong.
我希望这不仅仅是给你答案,而是足够解释你哪里出错了。

