angular.element
,可能意味着angular.element是真正的jQuery,而不是jqLite。我希望Angular能够自动检测到jQuery并使用它,而不是jqLite。我尝试在我的入口模块
app.js
中本地引用jQuery:require('jquery')
,并通过require(expose?$!expose?jQuery!jquery)
将jQuery全局暴露。无论我做什么,
angular.element
都指向jqLite。
我的研究得出了几个发现:
- 即使作为CommonJS模块导入,Angular也会将自己分配给全局变量
window.angular
,因此我不需要使用Webpack来expose
它:当作为CommonJS模块加载时,Angular是否将其自己分配给全局变量`window.angular`?。 - ProviderPlugin似乎行不通:它不会将jQuery暴露到全局命名空间;相反,对于每个依赖于全局名称jQuery的模块,它会在其中插入
require('jquery')
。我不是100%确定,但看起来 Angular 不直接从全局命名空间访问jQuery
,而是尝试在bindJQuery
函数中访问window.jQuery
,因此这种方法没有帮助:如何在Webpack中将jQuery暴露给真正的Window对象。 - 由于和ProviderPlugin一样的原因,
imports-loader
似乎不适合:Angular想要的是window.jQuery
,而不仅仅是jQuery
。 - 使用
expose-loader
,jQuery会出现在window对象中。我的问题在于Babel将所有导入置于模块的顶部,在结果代码中。因此,虽然require(expose?jquery!jquery)
在源文件中在import angular from "angular"
之前,但是在捆绑时require("angular")
在文件顶部,在jquery之前,因此在导入Angular时,jquery尚不可用。我想知道如何使用带有ECMA6导入语法的Webpack加载程序。 - 有建议使用
import
语法而不是require
语法与jquery一起使用:import "jquery"
或import $ from "jquery"
,而不是require(jquery)
:(Petr Averyanov: 如何在ECMAScript 6导入中使用Webpack加载程序语法(imports/exports/expose)?)。jquery源代码包装在一个特殊的包装器中,它识别jquery如何被需要(使用AMD/require,CommonJS还是全局<script>
语句)。基于这个,它为jquery工厂设置一个特殊的参数noGlobal
,根据noGlobal
的值创建或不创建window.jQuery
。截至jquery 2.2.4,import "jquery"
后noGlobal === true
,并且window.jQuery
不会创建。我IRC,一些旧版本的jquery没有将import
识别为CommonJS导入,并将import
的jquery添加到全局命名空间中,这使得angular可以使用它。
细节:这是我的
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"
});
});