我正在使用Webpack构建Angular 1.4项目。该项目使用了多个jQuery插件,这些插件被包装到angular指令中。这些指令在内部使用angular.element
,可能暗示angular.element是真正的jQuery,而不是jqLite。
我想要angular自动检测jQuery并使用它代替jqLite。我试图在本地需要的jquery我的入口点模块app.js
:require('jquery')
并与全球范围内暴露的jQuery require(expose?$!expose?jQuery!jquery)
。
无论如何,我所做的都是angular.element
指jqLite。
我的研究得出了一些发现:
- 即使当作为CommonJS模块导入时,Angular也会将自己分配给全局变量
window.angular
,所以我不需要expose
Webpack:当作为CommonJS模块加载时,Angular是否会将自己分配给全局的`window.angular`吗?。 - ProviderPlugin似乎无法解决问题:它不会将jQuery公开给全局名称空间;相反,对于依赖于全局名称jQuery的每个模块,它都会插入
require('jquery')
其中。我不确定100%,但是看起来Angular不会jQuery
直接从全局名称空间访问,而是尝试window.jQuery
在bindJQuery
函数中访问,因此这种方法无济于事:使用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尚不可用。我想知道如何将Webpack加载程序与ECMA6导入语法一起使用。 - There was a suggestion to use
import
syntax instead ofrequire
syntax with jquery:import "jquery"
orimport $ from "jquery"
, notrequire(jquery)
: (Petr Averyanov: How to use Webpack loaders syntax ( imports/exports/expose) with ECMAScript 6 imports?). jquery source code is wrapped with a special wrapper, which idenitifies how jquery is required (with AMD/require, CommonJS or globally with<script>
statement). Based on that it sets a special argumentnoGlobal
for jquery fabric and either createswindow.jQuery
or not, based on the value ofnoGlobal
. As of jquery 2.2.4, uponimport "jquery"
noGlobal === true
andwindow.jQuery
is not created. IIRC, some older versions of jquery didn't recognizeimport
as CommonJS import and addedimport
ed jquery to global namespace, which allowed angular to use it.
Details: here's my 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"
});
});
从john-reilly获得了这个答案:
webpack angular和jquery的神秘案例
bob-sponge的答案不太正确-Provide插件实际上是在其处理的模块上进行文本替换,因此我们需要提供
window.jQuery
(而不仅仅是angular所寻求的)jQuery
。