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

Могу ли я использовать импорт модуля ES6/2015 для задания ссылки в глобальной области?

У меня есть такая ситуация, когда я пытаюсь импортировать существующую библиотеку, которую я буду называть troublesome (используя Webpack/Babel FWIW), и у нее есть глобальная ссылка на jQuery в ней, которую я пытаюсь решить используя синтаксис модуля.

Я успешно импортировал jquery в "локальную" область модуля, используя:

import jQuery from 'jquery'

поэтому я попробовал:

import jQuery from 'jquery'    
import 'troublesome'

но, возможно, не удивительно, что я получил что-то вроде jQuery is not a function, отброшенное назад из troublesome.js

Я тоже пробовал это:

System.import('jquery')
.then(jQuery => {
    window.jQuery = jQuery
})
import 'troublesome'

но, оказывается, что System.import является частью так называемого "модуля-загрузчика", который извлекается из спецификации es6/2015, поэтому он не предоставляется Babel. Существует poly-fill, но Webpack не сможет управлять динамическим импортом, выполненным с помощью вызовов System.import в любом случае.

но... если я вызову файлы script в index.html, например:

<script src="https://code.jquery.com/jquery-2.1.4.min.js"></script>
<script src="https://cdnjs.cloudflare.com/ajax/libs/troublesome/troublesome.js"></script>
<script src="the-rest-of-my-js.js"></script>

ссылка на jQuery разрешена в troublesome.js, и все хорошо, но я бы предпочел избежать маршрута тега script, поскольку веб-пакет не справляется с этим.

Можно ли рекомендовать достойную стратегию для решения таких сценариев?

Обновление

с некоторыми рекомендациями от @TN1ck, я в конечном итоге смог идентифицировать одно решение, ориентированное на Webpack, используя imports-loader

Конфигурация для этого решения выглядит примерно так:

  //...
  module: {
    loaders: [
      //...
      {
        test: require.resolve('troublesome'),
        loader: "imports?jQuery=jquery,$=jquery"
      }
    ]
  }
4b9b3361

Ответ 1

Модули похудения - это путь: http://webpack.github.io/docs/shimming-modules.html

Я цитирую со страницы:

плагин ProvidePlugin

Этот плагин делает модуль доступным как переменную в каждом модуле. Модуль требуется, только если вы используете переменную.

Пример. Сделать $и jQuery доступными в каждом модуле без записи require("jquery").

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

Чтобы использовать это с помощью своего webpack-config, просто добавьте этот объект в массив, называемый плагинами в config:

// the plugins we want to use 
var plugins = [
   new webpack.ProvidePlugin({
      $: "jquery",
      jQuery: "jquery",
      "window.jQuery": "jquery"
   })
];

// this is your webpack-config
module.exports = {
    entry: ...,
    output: ...,
    module: ...,
    plugins: plugins
}

Ответ 2

Для es6/2015 я сделал следующее.

import {jsdom} from 'jsdom';
import jQuery from 'jquery';
var window = jsdom(undefined, {}).defaultView;
var $ = jQuery(window);
//window.jQuery = $; //probably not needed but it there if something wrong
//window.$ = $;//probably not needed but it there if something wrong

Затем вы можете использовать его как обычно

var text = $('<div />').text('hello world!!!').text();
console.log(text);

Надеюсь, что это поможет.

Ответ 3

Импорт jQuery в ваш модуль не делает его доступным для 'troublesome'. Вместо этого вы можете создать тонкий оберточный модуль для 'troublesome', который предоставляет jQuery и любые другие требуемые "глобальные переменные".

хлопотно-module.js:

// Bring jQuery into scope for troublesome.
import jQuery from 'jquery';
// Import any other 'troublesome'-assumed globals.

// Paste or have build tool interpolate existing troublesome.js code here.

Затем в вашем коде вы сможете

import 'troublesome-module';

Ответ 4

У меня была аналогичная проблема с использованием jspm и dygraphs. То, как я решил, это использовать динамическую загрузку, как вы пытались использовать System.import, но важная часть заключалась в том, чтобы последовательно загружать каждую последовательную "часть" с помощью System.import снова внутри обработчика onfulfillment (затем) после установки глобальной переменной пространства имен, В моем сценарии я фактически должен был иметь несколько шагов импорта, разделенных между обработчиками then.

Причина, по которой он не работал с jspm, и, вероятно, почему это не сработало для вас, так это то, что синтаксис import ... from ... оценивается перед любым кодом и определенно перед System.import, который из async.

В вашем случае это может быть просто:

import jQuery from 'jquery';

window.jQuery = jQuery;
System.import('troublesome').then(troublesome => {
 // Do something with it...
});

Также обратите внимание, что рекомендация по загрузке модуля System была оставлена ​​вне окончательной спецификации ES6, и разрабатывается новая спецификация загрузчика.

Ответ 5

  • запустите npm install import-loader.
  • замените import 'troublesome' на import 'imports?jQuery=jquery,$=jquery!troublesome.

По-моему, это самое простое решение вашего вопроса. Это похоже на ответ, который вы написали в своем вопросе @TN1ck, но не изменяя конфигурацию вашего веб-пакета. Подробнее читайте здесь: https://github.com/webpack/imports-loader

Ответ 6

Успокойление - это хорошо, и есть разные способы решения этой проблемы, но согласно моему ответу здесь, проще всего просто вернуться к использованию, требующему для загрузки библиотека, которая требует глобальной зависимости, - тогда просто убедитесь, что у вас окно. назначение до этого требует утверждения, и они оба после вашего другого импорта, и ваш заказ должен оставаться в соответствии с назначением. Проблема вызвана тем, что Babel поднимает импорт таким образом, что все они выполняются перед любым другим кодом.