Могу ли я использовать импорт модуля 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"
}
]
}
Ответы
Ответ 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 поднимает импорт таким образом, что все они выполняются перед любым другим кодом.