Pregunta ¿Webpack ProvidePlugin vs Externals?


Estoy explorando la idea de usar Webpack con Backbone.js.

He seguido la guía de inicio rápido y tengo una idea general de cómo funciona Webpack, pero no tengo claro cómo cargar la biblioteca de dependencias como jquery / backbone / underscore.

Deberían cargarse externamente <script> o es esto algo que Webpack puede manejar como shim de RequireJS?

De acuerdo con la webpack doc: módulos de ajuste, ProvidePlugin y externals parece estar relacionado con esto (por lo que es bundle! cargador en alguna parte) pero no puedo imaginar cuándo usarlo.

Gracias


75
2018-04-26 01:39


origen


Respuestas:


Es posible: puede incluir bibliotecas con <script> (es decir, para usar una biblioteca de un CDN) o incluirlos en el paquete generado.

Si lo cargas a través de <script> etiqueta, puedes usar externals opción para permitir escribir require(...) en tus módulos

Ejemplo con la biblioteca de CDN:

<script src="https://code.jquery.com/jquery-git2.min.js"></script>

// the artifial module "jquery" exports the global var "jQuery"
externals: { jquery: "jQuery" }

// inside any module
var $ = require("jquery");

Ejemplo con la biblioteca incluida en el paquete:

copy `jquery-git2.min.js` to your local filesystem

// make "jquery" resolve to your local copy of the library
// i. e. through the resolve.alias option
resolve: { alias: { jquery: "/path/to/jquery-git2.min.js" } }

// inside any module
var $ = require("jquery");

los ProvidePlugin puede mapear módulos a variables (gratuitas). Entonces podrías definir: "Cada vez que uso la variable (gratuita) xyz dentro de un módulo que usted (paquete web) debe configurar xyz a require("abc")"

Ejemplo sin ProvidePlugin:

// You need to require underscore before you can use it
var _ = require("underscore");
_.size(...);

Ejemplo con ProvidePlugin:

plugins: [
  new webpack.ProvidePlugin({
    "_": "underscore"
  }) 
]

// If you use "_", underscore is automatically required
_.size(...)

Resumen:

  • Biblioteca de CDN: uso <script> etiqueta y externals opción
  • Biblioteca del sistema de archivos: incluya la biblioteca en el paquete. (Tal vez modificar resolve opciones para encontrar la biblioteca)
  • externals: Hacer vars globales disponibles como módulo
  • ProvidePlugin: Haga que los módulos estén disponibles como variables libres dentro de los módulos

139
2018-04-29 19:58



Algo bueno de notar es que si usas el ProvidePlugin en combinación con el externals propiedad que le permitirá tener jQuery pasado en el cierre del módulo webpack sin tener que explícitamente require eso. Esto puede ser útil para refactorizar código heredado con una gran cantidad de archivos diferentes haciendo referencia $.

//webpack.config.js
module.exports = {
  entry: './index.js',
  output: { 
    filename: '[name].js' 
  },
  externals: {
    jquery: 'jQuery'
  },
  plugins: [
    new webpack.ProvidePlugin({
      $: 'jquery',
    })
  ]
};

ahora en index.js

console.log(typeof $ === 'function');

tendrá una salida compilada con algo así como pasado a continuación en el webpackBootstrap cierre:

/******/ ([
/* 0 */
/***/ function(module, exports, __webpack_require__) {

    /* WEBPACK VAR INJECTION */(function($) {
        console.log(typeof $ === 'function');

    /* WEBPACK VAR INJECTION */}.call(exports, __webpack_require__(1)))

/***/ },
/* 1 */
/***/ function(module, exports, __webpack_require__) {

    module.exports = jQuery;

/***/ }
/******/ ])

Por lo tanto, puedes ver eso $ está haciendo referencia a la ventana / global jQuery del CDN, pero se está pasando al cierre. No estoy seguro de si esta es la funcionalidad prevista o un hack de la suerte, pero parece funcionar bien para mi caso de uso.


21
2018-06-02 04:18



Sé que esta es una publicación anterior, pero pensé que sería útil mencionar que el gestor de script de webpack también puede ser útil en este caso. De los documentos de la carpeta web:

"script: Ejecuta un archivo JavaScript una vez en contexto global (como en la etiqueta script), no se analiza".

http://webpack.github.io/docs/list-of-loaders.html

https://github.com/webpack/script-loader

Esto me pareció particularmente útil al migrar procesos de compilación más antiguos que combinan los archivos del proveedor JS y los archivos de la aplicación. Una palabra de advertencia es que el gestor de scripts parece funcionar solo por sobrecarga require() y no funciona tan lejos como puedo decir al ser especificado dentro de un archivo webpack.config. Aunque, muchos argumentan que la sobrecarga requirees una mala práctica, puede ser bastante útil para concatar el script del vendedor y de la aplicación en un paquete y, al mismo tiempo, exponer JS Globals que no tienen que incluirse en paquetes adicionales de webpack. Por ejemplo:

require('script!jquery-cookie/jquery.cookie');
require('script!history.js/scripts/bundled-uncompressed/html4+html5/jquery.history');
require('script!momentjs');

require('./scripts/main.js');

Esto haría que $ .cookie, History y moment globalmente estén disponibles dentro y fuera de este paquete, y agrupe estas libs de proveedores con el script main.js y todo lo que es required archivos.

Además, útil con esta técnica es:

resolve: {
  extensions: ["", ".js"],
  modulesDirectories: ['node_modules', 'bower_components']
},
plugins: [
  new webpack.ResolverPlugin(
    new webpack.ResolverPlugin.DirectoryDescriptionFilePlugin("bower.json", ["main"])
   )
]

que está usando Bower, mirará el main archivo en cada required libraries package.json. En el ejemplo anterior, History.js no tiene un main archivo especificado, por lo que la ruta al archivo es necesaria.


11
2018-01-25 22:14