without tag queryselector getelementsbyclass example jquery angularjs webpack

tag - Webpack: cómo hacer angular la autodetección jQuery y usarla como angular.element en lugar de jqLite?



document queryselector angular element (5)

!!Actualizar

Aparentemente, todavía necesita usar los valores comunes de commonJs necesarios para angular en el ejemplo de ES6.

import $ from "jquery" window.$ = $; window.jQuery = $; var angular = require("angular");

a continuación está la respuesta original

Quiero proponer una solución más fácil. Simplemente haga que jQuery sea una ventana global para que angular pueda reconocerlo:

var $ = require("jquery") window.$ = $; window.jQuery = $; var angular = require("angular");

o en su caso ( FUERA DE FECHA ):

import $ from "jquery" window.$ = $; window.jQuery = $; import angular from "angular";

Espero que esto ayude :)

Estoy usando Webpack para construir un proyecto Angular 1.4. El proyecto hace uso de varios plugins jQuery, que están envueltos en directivas angulares. Esas directivas usan internamente el elemento angular.element , lo que probablemente implica que angular.element es el jQuery real, no jqLite.

Quiero angular para detectar automáticamente jQuery y usarlo en lugar de jqLite. Intenté solicitar jquery localmente en mi módulo de punto de entrada app.js : require(''jquery'') y exponer jQuery globalmente con require(expose?$!expose?jQuery!jquery) .

Aún así, haga lo que haga, angular.element refiere a jqLite.

Mi investigación dio como resultado varios hallazgos:

  1. Incluso cuando se importa como un módulo CommonJS, Angular se asigna a una variable global window.angular , por lo que no necesito expose con Webpack: ¿Angular se asigna a `window.angular` globalmente, cuando se carga como módulo CommonJS? .
  2. ProviderPlugin no parece hacer el truco: no expone jQuery al espacio de nombres global; en cambio, para cada módulo que depende del nombre global jQuery, inserta require(''jquery'') en él. No estoy 100% seguro, pero parece que Angular no accede directamente a jQuery desde el espacio de nombres global, sino que trata de acceder a window.jQuery en la función bindJQuery , por lo que este enfoque no ayuda: exponer jQuery a un objeto de ventana real con Webpack .
  3. Por la misma razón que ProviderPlugin, imports-loader parece inadecuado: Angular quiere window.jQuery , no solo jQuery .
  4. Con expose-loader , jquery lo hace al objeto ventana. Mi problema fue que Babel eleva todas sus importaciones a la parte superior del módulo en el código resultante. Por lo tanto, aunque require(expose?jquery!jquery) antes de la import angular from "angular" en los archivos de origen, en bundle require("angular") está en la parte superior del archivo, antes de jquery, por lo que cuando se importa Angular, jquery aún no está disponible. Me pregunto cómo usar los cargadores Webpack con la sintaxis de importación ECMA6.
  5. Hubo una sugerencia para usar la sintaxis de import lugar de require sintaxis con jquery: import "jquery" o import $ from "jquery" , no require(jquery) : (Petr Averyanov: Cómo usar la sintaxis de los cargadores Webpack (imports / exports / expone) con ECMAScript 6 importaciones? ). El código fuente de jquery está envuelto con un contenedor especial , que identifica cómo se requiere jquery (con AMD / require, CommonJS o globalmente con la instrucción <script> ). Basado en eso, establece un argumento especial noGlobal para jquery fabric y crea window.jQuery o no, basado en el valor de noGlobal . A partir de jquery 2.2.4, al import "jquery" noGlobal === true y window.jQuery no se crea. IIRC, algunas versiones anteriores de jquery no reconocían la import como import CommonJS y agregaban la import archivos jquery al espacio de nombres global, lo que permitía que angular lo usara.

Detalles: aquí está mi 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" }); });


En su caso, es mejor usar ProvidePlugin . Simplemente agregue estas líneas a la configuración de su paquete web en la sección de complementos y jquery estará disponible en su aplicación:

new webpack.ProvidePlugin({ "$": "jquery", "jQuery": "jquery" })


Hay este artículo japonés . Quiero utilizar jQuery not jQLite en webpack + AngularJS que parece hablar sobre el mismo problema (aún no sé japonés). Utilicé Google para traducir al inglés, los créditos van a cither para esta buena respuesta.

Él proporciona cuatro formas de resolver esto:

  1. Asignar directamente a la ventana (no muy bueno)

    window.jQuery = require(''jquery''); var angular = require(''angular''); console.log(angular.element(''body'')); //[body, prevObject: jQuery.fn.init[1], context: document, selector: "body"]

  2. Usa el expose-loader (vale, pero no tan genial)

    npm install --saveDev expose-loader

    webpack.config.js

    module.exports = { entry: "./index", output: { path: __dirname, filename: "bundle.js" }, module: { loaders: [{ test: ///jquery.js$/, loader: "expose?jQuery" }] } };

    uso:

    require(''jquery''); var angular = require(''angular''); console.log(angular.element(''body'')); //[body, prevObject: jQuery.fn.init[1], context: document, selector: "body"]

  3. Use expose-loader (mejor)

    npm install --saveDev expose-loader

    webpack.config.js

    module.exports = { entry: "./index", output: { path: __dirname, filename: "bundle.js" }, module: { loaders: [{ test: ///angular/.js$/, loader: "imports?jQuery=jquery" }, { test: ///jquery.js$/, loader: "expose?jQuery" }] } };

    uso:

    var angular = require(''angular''); console.log(angular.element(''body'')); //[body, prevObject: jQuery.fn.init[1], context: document, selector: "body"]

  4. Use ProvidePlugin (Mejor solución)

    Esto es en realidad lo mismo que la respuesta aceptada por los studds aquí

    module.exports = { entry: "./index", output: { path: __dirname, filename: "bundle.js" }, plugins: [ new webpack.ProvidePlugin({ "window.jQuery": "jquery" }) ], };

    uso:

    var angular = require(''angular''); console.log(angular.element(''body'')); //[body, prevObject: jQuery.fn.init[1], context: document, selector: "body"]

Pensé en compartir esto aquí ya que teníamos exactamente el mismo problema. Usamos la solución expose-loader en nuestro proyecto con éxito. Supongo que el ProvidePlugin que inyecta jquery directamente en la window también es una buena idea.


Obtuve esta respuesta de john-reilly :
El misterioso caso de webpack angular y jquery

La respuesta de bob-sponge no es del todo correcta: el plugin Provide está haciendo un reemplazo de texto en los módulos que procesa, por lo que debemos proporcionar window.jQuery (que es lo que angular busca) y no solo jQuery .

En su webpack.config.js necesita agregar la siguiente entrada a sus complementos:

new webpack.ProvidePlugin({ "window.jQuery": "jquery" }),

Esto utiliza el paquete web ProvidePlugin y, en el punto de webpackification (© 2016 John Reilly), todas las referencias en el código de window.jQuery serán reemplazadas por una referencia al módulo de paquete web que contiene jQuery. Así que cuando mires el archivo incluido verás que el código que verifica el objeto de la window para jQuery ha convertido en esto:

jQuery = isUndefined(jqName) ? __webpack_provided_window_dot_jQuery : // use jQuery (if present) !jqName ? undefined : // use jqLite window[jqName]; // use jQuery specified by `ngJq`

Está bien; webpack le proporciona a Angular jQuery sin dejar una variable jQuery en la window . Neat ¿eh?


Por lo tanto, doy mi solución, que en realidad es una combinación de la respuesta de @BobSponge y los consejos / comentarios de @Bob. Así que nada original, simplemente mostrando lo que funciona para mí (en un proyecto que no usa Babel / ES6, BTW) y tratando de explicar por qué funciona ...

El truco (final) es utilizar el cargador de exposición .

Como se explica en su página, tenemos que poner module.loaders . module.loaders :

{ test: require.resolve("jquery"), loader: "expose?$!expose?jQuery" },

Además, en la lista de plugins , tengo:

new webpack.ProvidePlugin( { $: ''jquery'', jQuery: ''jquery'', _: ''lodash'', // [...] some other libraries that put themselves in the global scope. //angular: ''angular'', // No, I prefer to require it everywhere explicitly. }),

que realmente encuentra las ocurrencias globales de estas variables en el código, y las requiere en variables locales para cada módulo. Facilita la migración de un proyecto existente (de RequireJS a Webpack) como lo hago ... Creo que podemos prescindir de este complemento si prefiere ser explícito en sus importaciones.

Y, lo que es más importante (creo), en el punto de entrada de la aplicación, los requiero en el orden en que los quiero. En mi caso, hice un paquete de proveedores, así que ese es el orden en este paquete.

require(''jquery''); require(''lodash''); // [...] var angular = require(''angular''); // Use the angular variable to declare the app module, etc.

Webpack agregará las bibliotecas al paquete relevante en el orden en que ve las necesidades (a menos que use un complemento / cargador que las reordene). Pero las importaciones están aisladas (sin pérdida global), por lo que Angular no pudo ver la biblioteca jQuery. De ahí la necesidad de expose . (Intenté window.jQuery = require(''jquery''); lugar, pero no funcionó, tal vez es demasiado tarde.)