I'm using Webpack to build an Angular 1.4 project. The project makes use of several jQuery plugins, which are wrapped into angular directives. Those directives internally use angular.element
, probably implying that angular.element is the real jQuery, not jqLite.
I want angular to auto-detect jQuery and use it instead of jqLite. I tried to require jquery locally in my entry point module app.js
: require('jquery')
and to expose jQuery globally with require(expose?$!expose?jQuery!jquery)
.
Still, whatever I do, angular.element
refers to jqLite.
My research resulted in several findings:
- Even when imported as a CommonJS module, Angular assigns itself to a global variable
window.angular
, so I don't need to expose
it with Webpack: Does Angular assign itself to `window.angular` globally, when loaded as CommonJS module?.
- ProviderPlugin doesn't seem to do the trick: it doesn't expose jQuery to global namespace; instead, for every module that depends on global name jQuery, it inserts
require('jquery')
in it. I'm not 100% sure, but looks like Angular doesn't access jQuery
from global namespace directly, instead, it tries to access window.jQuery
in bindJQuery
function, so this approach doesn't help: Expose jQuery to real Window object with Webpack.
- For the same reason as ProviderPlugin,
imports-loader
seems unfit: Angular wants window.jQuery
, not just jQuery
.
- With
expose-loader
, jquery makes it to the window object. My problem was that Babel hoists all of its imports to the top of module in the resulting code. Hence, although require(expose?jquery!jquery)
was before import angular from "angular"
in source files, in bundle require("angular")
is at the top of the file, before jquery, so by the time Angular is imported, jquery is not yet available. I wonder, how to use Webpack loaders with ECMA6 import syntax.
- There was a suggestion to use
import
syntax instead of require
syntax with jquery: import "jquery"
or import $ from "jquery"
, not require(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 argument noGlobal
for jquery fabric and either creates window.jQuery
or not, based on the value of noGlobal
. As of jquery 2.2.4, upon import "jquery"
noGlobal === true
and window.jQuery
is not created. IIRC, some older versions of jquery didn't recognize import
as CommonJS import and added import
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"
});
});
question from:
https://stackoverflow.com/questions/36065931/webpack-how-to-make-angular-auto-detect-jquery-and-use-it-as-angular-element-in 与恶龙缠斗过久,自身亦成为恶龙;凝视深渊过久,深渊将回以凝视…