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.json
的main
字段中链接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.js
和window.$
是扩展插件如预期。
将此添加到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;