我想要角度来自动检测jQuery并使用它而不是jqLite。我试图在我的入口点模块app.js:require(‘jquery’)中本地要求jquery,并用require(exposed?$!public?jQuery!jquery)来全局公开jQuery。
不管怎么说,angular.element是指jqLite。
我的研究结果产生了几个发现:
>即使作为CommonJS模块导入,Angular也将自身赋值给一个全局变量window.angular,所以我不需要用Webpack:Does Angular assign itself to `window.angular` globally,when loaded as CommonJS module?来公开它。
> ProviderPlugin似乎没有办法:它不会将jQuery暴露给全局命名空间;相反,对于依赖于全局名称jQuery的每个模块,它会在其中插入require(‘jquery’)。我不是100%肯定的,但是看起来Angular不直接从全局命名空间访问jQuery,而是尝试在bindJQuery函数中访问window.jQuery,所以这种方法没有帮助:Expose jQuery to real Window object with Webpack。
>由于与ProviderPlugin相同的原因,导入加载器似乎不合适:Angular需要window.jQuery,而不仅仅是jQuery。
>使用exposed-loader,jquery使它到窗口对象。我的问题是,Babel将所有的导入提升到最终的代码中的模块的顶部。因此,虽然require(exposed?jquery!jquery)在源文件中从“角度”导入之前有所不同,但是在“jQuery”之前,bundle require(“angular”)位于文件的顶部,所以在Angular被导入时, jquery尚不可用。我想知道如何使用带有ECMA6导入语法的Webpack加载器。
>建议使用导入语法,而不是需要使用jquery语法:import“jquery”或从“jquery”导入$,而不需要(jquery):(Petr Averyanov:How to use Webpack loaders syntax ( imports/exports/expose) with ECMAScript 6 imports?)。 jquery源代码是wrapped with a special wrapper,它识别了jquery的需要(使用AMD / require,CommonJS或全球使用< script>语句)。基于此,它为jquery fabric设置了一个特殊参数noGlobal,并且基于noGlobal的值创建window.jQuery。截至jquery 2.2.4,导入“jquery”noGlobal === true和window.jQuery未创建。 IIRC,一些较旧版本的jquery不能识别导入为CommonJS导入,并将导入的jquery添加到全局命名空间,这允许有角度使用它。
详细信息:这里是我的app.js:
'use strict'; require("expose?$!expose?jQuery!jquery"); require("metisMenu/dist/metisMenu"); require("expose?_!lodash"); require("expose?angular!angular"); import angular from "angular"; import "angular-animate"; import "angular-messages"; import "angular-resource"; import "angular-sanitize"; import "angular-ui-router"; import "bootstrap/dist/css/bootstrap.css"; import "font-awesome/css/font-awesome.css"; import "angular-bootstrap"; require("../assets/styles/style.scss"); require("../assets/fonts/pe-icon-7-stroke/css/pe-icon-7-stroke.css"); // Import all html files to put them in $templateCache // If you need to use lazy loading,you will probably need // to remove these two lines and explicitly require htmls const templates = require.context(__dirname,true,/\.html$/); templates.keys().forEach(templates); import HomeModule from "home/home.module"; import UniverseDirectives from "../components/directives"; angular.module("Universe",[ "ngAnimate","ngMessages","ngResource","ngSanitize","ui.router","ui.bootstrap",HomeModule.name,UniverseDirectives.name,]) .config(function($urlRouterProvider,$locationProvider,$stateProvider){ // $urlRouterProvider.otherwise('/'); // $locationProvider.html5Mode(true); $stateProvider .state('test',{ url: "/test",template: "This is a test" }); });
解决方法
The mysterious case of webpack angular and jquery
bob-sponge的答案是不正确的 – 提供插件实际上是对其进行处理的模块进行文本替换,所以我们需要提供window.jQuery(这是什么有意义的),而不仅仅是jQuery。
In your
webpack.config.js
you need to add
the following entry to your plugins:
new webpack.ProvidePlugin({ "window.jQuery": "jquery" }),
This uses the webpack 07003 and,at the point of
webpackification (© 2016 John Reilly) all references in the code to
window.jQuery will be replaced with a reference to the webpack module
that contains jQuery. So when you look at the bundled file you’ll see
that the code that checks thewindow
object forjQuery
has become
this:
jQuery = isUndefined(jqName) ? __webpack_provided_window_dot_jQuery : // use jQuery (if present) !jqName ? undefined : // use jqLite window[jqName]; // use jQuery specified by `ngJq`
That’s right; webpack is providing Angular with jQuery whilst still
not placing ajQuery
variable onto thewindow
. Neat huh?