我想要角度来自动检测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.jsyou 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 thewindowobject forjQueryhas 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 ajQueryvariable onto thewindow. Neat huh?