pipe理webpack中的jQuery插件依赖

我在我的应用程序中使用了Webpack,在这个应用程序中,我创build了两个入口点 – 所有JavaScript文件/代码的bundle.js,以及jQuery和React等所有库的vendor.js。 我该怎么做才能使用jQuery作为依赖的插件,我也想在vendor.js中使用它们? 如果这些插件有多个依赖关系呢?

目前我试图在这里使用这个jQuery插件 – https://github.com/mbklein/jquery-elastic 。 Webpack文档提到了providePlugin和imports-loader。 我用providePlugin,但仍然是jQuery对象不可用。 这里是我的webpack.config.js看起来像 –

var webpack = require('webpack'); var bower_dir = __dirname + '/bower_components'; var node_dir = __dirname + '/node_modules'; var lib_dir = __dirname + '/public/js/libs'; var config = { addVendor: function (name, path) { this.resolve.alias[name] = path; this.module.noParse.push(new RegExp(path)); }, plugins: [ new webpack.ProvidePlugin({ $: "jquery", jquery: "jQuery", "windows.jQuery": "jquery" }), new webpack.optimize.CommonsChunkPlugin('vendors', 'vendors.js', Infinity) ], entry: { app: ['./public/js/main.js'], vendors: ['react','jquery'] }, resolve: { alias: { 'jquery': node_dir + '/jquery/dist/jquery.js', 'jquery.elastic': lib_dir + '/jquery.elastic.source.js' } }, output: { path: './public/js', filename: 'bundle.js' }, module: { loaders: [ { test: /\.js$/, loader: 'jsx-loader' }, { test: /\.jquery.elastic.js$/, loader: 'imports-loader' } ] } }; config.addVendor('react', bower_dir + '/react/react.min.js'); config.addVendor('jquery', node_dir + '/jquery/dist/jquery.js'); config.addVendor('jquery.elastic', lib_dir +'/jquery.elastic.source.js'); module.exports = config; 

但是尽pipe如此,它仍然在浏览器控制台中引发错误:

未捕获的ReferenceError:未定义jQuery

同样,当我使用imports-loader时,它会抛出一个错误,

要求没有定义“

在这一行:

 var jQuery = require("jquery") 

不过,我可以使用相同的插件,而不是将其添加到我的vendors.js文件中,而是以正常的AMD方式来请求它,因为我包含了其他JavaScript代码文件,

 define( [ 'jquery', 'react', '../../common-functions', '../../libs/jquery.elastic.source' ],function($,React,commonFunctions){ $("#myInput").elastic() //It works }); 

但这不是我想要做的,因为这意味着jquery.elastic.source.js与bundle.js中的JavaScript代码捆绑在一起,并且我希望所有的jQuery插件都位于vendors.js包中。 那么我怎么去实现呢?

您已经混合了不同的方法如何包含传统的供应商模块。 这是我如何解决它:

1.优先考虑未分类的CommonJS / AMD

大多数模块在package.jsonmain字段中链接dist版本。 虽然这对于大多数开发者来说是有用的,但对于webpack来说,最好还是使用src版本,因为webpack可以更好地优化依赖关系(例如使用DedupePlugin )。

 // webpack.config.js module.exports = { ... resolve: { alias: { jquery: "jquery/src/jquery" } } }; 

但是,在大多数情况下, dist版本也可以正常工作。


2.使用ProvidePlugin注入隐式全局variables

大多数遗留模块依赖于特定全局variables的存在,比如jQuery插件在$jQuery 。 在这种情况下,您可以configurationwebpack,每次遇到全局$标识符时,都会预先安装var $ = require("jquery")

 var webpack = require("webpack"); ... plugins: [ new webpack.ProvidePlugin({ $: "jquery", jQuery: "jquery" }) ] 

3.使用imports-loader来configurationthis

一些遗留模块依赖于this window对象。 当模块在CommonJS上下文中等于module.exports时被执行,这就成了一个问题。 在这种情况下,你可以使用imports-loader来覆盖this

运行npm i imports-loader --save-dev然后

 module: { loaders: [ { test: /[\/\\]node_modules[\/\\]some-module[\/\\]index\.js$/, loader: "imports-loader?this=>window" } ] } 

imports-loader也可以用来手动注入各种variables。 但是在大多数情况下, ProvidePlugin对于隐式全局variables更有用。


4.使用imports-loader禁用AMD

有支持不同模块样式的模块,比如AMD,CommonJS和legacy。 但是,大多数情况下,他们首先检查define ,然后使用一些古怪的代码来导出属性。 在这些情况下,可以通过设置define = false来帮助强制CommonJSpath。

 module: { loaders: [ { test: /[\/\\]node_modules[\/\\]some-module[\/\\]index\.js$/, loader: "imports-loader?define=>false" } ] } 

5.使用脚本加载器来全局导入脚本

如果你不关心全局variables,只想让遗留脚本工作,你也可以使用脚本加载器。 它在全局上下文中执行模块,就像通过<script>标记包含它们一样。


6.使用noParse来包含较大的dists

如果没有AMD / CommonJS版本的模块,并且想要包含dist ,则可以将该模块标记为noParse 。 然后webpack将只包含模块而不parsing它,这可以用来提高构build时间。 这意味着任何需要AST的function,如ProvidePlugin ,都不能工作。

 module: { noParse: [ /[\/\\]node_modules[\/\\]angular[\/\\]angular\.js$/ ] } 

为了全局访问jquery,存在几个选项。 在我最近的webpack项目中,我想全局访问jquery,所以我添加了以下内容到我的插件声明:

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

这意味着可以通过全局引用$和jQuery从JavaScript源代码中访问jquery。

当然,你还需要通过npm安装jquery:

 $ npm i jquery --save 

对于这种方法的工作示例,请随时在github上分发我的应用程序

我不知道我是否理解你正在做什么,但我不得不使用jQuery插件,需要jQuery在全局上下文(窗口),我把以下放入我的entry.js

 var $ = require('jquery'); window.jQuery = $; window.$ = $; 

我只需要任何我想要的jqueryplugin.min.jswindow.$是扩展插件如预期。

将此添加到webpack.config.js中的插件数组中

 new webpack.ProvidePlugin({ 'window.jQuery': 'jquery', 'window.$': 'jquery', }) 

那么通常需要jquery

 require('jquery'); 

如果痛苦持续让其他脚本看到它,尝试明确地把它放在全局上下文中(在条目js中)

 window.$ = jQuery; 

这适用于webpack 3:

在webpack.config.babel.js文件中:

 resolve: { alias: { jquery: "jquery/src/jquery" }, .... } 

并使用ProvidePlugin

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

我尝试了一些提供的答案,但没有一个似乎工作。 然后我试了这个:

 new webpack.ProvidePlugin({ 'window.jQuery' : 'jquery', 'window.$' : 'jquery', 'jQuery' : 'jquery', '$' : 'jquery' }); 

似乎工作,无论我使用的是哪个版本

我find的最佳解决scheme是:

https://github.com/angular/angular-cli/issues/5139#issuecomment-283634059

基本上,您需要在typings.d.ts中包含一个虚拟variables,从您的代码中删除任何“从$ jquery导入*”,然后手动为您的SPA html添加一个标记到jQuery脚本。 这样,webpack将不会在你的方式,你应该能够在你的脚本中访问相同的全局jQueryvariables。

当Webpack 3.8.1和以下版本公开$jQuery作为全局variables时,我得到了很好的工作。

安装jQuery作为项目依赖项。 您可以省略@3.2.1来安装最新版本或指定其他版本。

 npm install --save jquery@3.2.1 

configurationWebpack为我们加载和公开jQuery。

 // webpack.config.js const webpack = require('webpack') module.exports = { entry: [ // entry bits ], output: { // output bits }, module: { rules: [ // any other rules { // Exposes jQuery for use outside Webpack build test: require.resolve('jquery'), use: [{ loader: 'expose-loader', options: 'jQuery' },{ loader: 'expose-loader', options: '$' }] } ] }, plugins: [ // Provides jQuery for other JS bundled with Webpack new webpack.ProvidePlugin({ $: 'jquery', jQuery: 'jquery' }) ] } 

编辑:有时你想简单地使用webpack作为一个简单的web项目模块打包 – 保持自己的代码组织。 以下解决scheme适用于那些仅仅希望外部库在模块内部按预期工作的用户,而不需要花费大量时间进入webpack设置。 (在-1之后编辑)

如果您还在苦苦挣扎,或想避免外部configuration/附加webpack插件configuration,请快速且简单地(es6)解决scheme:

 <script src="cdn/jquery.js"></script> <script src="cdn/underscore.js"></script> <script src="etc.js"></script> <script src="bundle.js"></script> 

在模块里面:

 const { jQuery: $, Underscore: _, etc } = window;