Подтвердить что ты не робот

Webpack ProvidePlugin vs externals?

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

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

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

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

Спасибо

4b9b3361

Ответ 1

Это возможно: вы можете включать библиотеки с <script> (т.е. использовать библиотеку из 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 в 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: Сделать глобальными vars доступными как модуль
  • ProvidePlugin: Сделать модули доступными как свободные переменные внутри модулей

Ответ 2

Приятно заметить, что если вы используете 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',
    })
  ]
};

теперь в index.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;

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

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

Ответ 3

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

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

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

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

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

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, History и момент глобально доступным внутри и снаружи этого пакета и связать эти библиотеки поставщиков с файлом main.js script и всеми его require d.

Кроме того, полезно использовать эту технику:

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

который использует Bower, будет смотреть файл main в каждом пакете require d package.json. В приведенном выше примере History.js не имеет указанного файла main, поэтому необходим путь к файлу.