Webpack ProvidePlugin vs externals?

Я изучаю идею использования Webpack С костяк.js.

я следовал руководству быстрого запуска и имею общее представление о том, как работает Webpack, но мне неясно, как загрузить библиотеку зависимостей, такую как jquery / backbone / underscore.

должны ли они быть загружены извне с <script> или это то, что Webpack может обрабатывать, как прокладка RequireJS?

по словам webpack doc: shimming modules, ProvidePlugin и externals Кажется, связано с этим (так что bundle! загрузчик где-то), но я не могу понять, когда какую использовать.

спасибо

3 ответов


это возможно: вы можете включить библиотеки с <script> (i. e. использовать библиотеку из CDN) или включить их в сгенерированный пакет.

если вы загрузите его через <script> тег, вы можете использовать externals возможность разрешить писать require(...) в ваши модули.

пример с библиотекой из 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");

пример с библиотекой, включенной в комплект:

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");

на ProvidePlugin можно сопоставить модули (свободные) переменные. Так вы может определить: "каждый раз, когда я использую (свободную) переменную xyz внутри модуля вы (webpack) должны установить xyz to require("abc")."

пример без ProvidePlugin:

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

пример ProvidePlugin:

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

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

резюме:

  • библиотека из CDN: используйте <script> и тег externals опции
  • библиотека из файловой системы: включите библиотеку в комплект. (Возможно, изменить resolve опции для поиска библиотека)
  • externals: сделайте global vars доступным в качестве модуля
  • ProvidePlugin: сделайте модули доступными как свободные переменные внутри модулей

что-то круто отметить, что если вы используете ProvidePlugin в сочетании с externals свойство это позволит вам иметь jQuery передано в закрытие модуля webpack без явного require его. Это может быть полезно для рефакторинга устаревшего кода с большим количеством различных файлов, ссылающихся $.

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

сейчас в индексе.js

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

будет иметь скомпилированный вывод с чем-то вроде ниже, переданным в webpackBootstrap закрытие:

/******/ ([
/* 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;

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

таким образом, вы можете видеть, что $ ссылается на global / window jQuery из CDN, но передается в закрытие. Я не уверен, что это предназначенная функциональность или удачный хак, но, похоже, хорошо работает для моего случая использования.


Я знаю, что это старый пост, но подумал, что было бы полезно упомянуть, что загрузчик сценариев webpack может быть полезен и в этом случае. Из документов webpack:

"script: выполняет файл JavaScript один раз в глобальном контексте (как в теге скрипта), требует не анализируются."

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

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

я нашел это особенно полезно при переносе старых процессов сборки, которые объединяют файлы поставщиков JS и файлы приложений вместе. Слово предупреждения заключается в том, что загрузчик скриптов, похоже, работает только через перегрузку require() и не работает, насколько я могу судить, будучи указанным в webpack.конфигурационный файл. Хотя, многие утверждают, что перегрузка require это плохая практика, это может быть очень полезно для конкатирования поставщика и скрипта приложения в одном пакете и в то же время подвергая JS Globals, которые не должны быть переложены в дополнение пакеты webpack. Например:

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

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

это сделает $.cookie, история и момент глобально доступны внутри и вне этого пакета и связывают эти свободы поставщика с основным.JS скрипт и все это requireфайлов.

кроме того, полезно с этой техникой является:

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

который использует Bower, посмотрит на в каждом элементе requireD пакет библиотек.формат JSON. В приведенном выше примере история.js не имеет указывать путь к файлу необходимо.