Webpack:如何使角度自动检测jQuery并将其用作angular.element而不是jqLit​​e?

前端之家收集整理的这篇文章主要介绍了Webpack:如何使角度自动检测jQuery并将其用作angular.element而不是jqLit​​e?前端之家小编觉得挺不错的,现在分享给大家,也给大家做个参考。
我正在使用Webpack构建一个Angular 1.4项目。该项目使用几个jQuery插件,它们被包装成角度指令。这些指令在内部使用angular.element,这可能意味着angular.element是真正的jQuery,而不是jqLit​​e。

我想要角度来自动检测jQuery并使用它而不是jqLit​​e。我试图在我的入口点模块app.js:require(‘jquery’)中本地要求jquery,并用require(exposed?$!public?jQuery!jquery)来全局公开jQuery。

不管怎么说,angular.element是指jqLit​​e。

我的研究结果产生了几个发现:

>即使作为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"
      });
});

解决方法

john-reilly得到这个答案:
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 the window object for jQuery 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 a jQuery variable onto the window. Neat huh?

原文链接:https://www.f2er.com/jquery/181900.html

猜你在找的jQuery相关文章