我可以使用 ES6/2015 模块导入在 'global' 范围内设置引用吗?
Can I use an ES6/2015 module import to set a reference in 'global' scope?
我有这种情况,我试图导入一个现有的库,我将其称为 troublesome
(使用 Webpack/Babel FWIW)并且它具有对 jQuery
的全局引用在其中我试图使用模块语法来解决。
我已成功将 jquery 导入模块的 'local' 范围,通过:
import jQuery from 'jquery'
所以我尝试了:
import jQuery from 'jquery'
import 'troublesome'
但也许不足为奇,我从 troublesome.js
得到了 jQuery is not a function
之类的东西
我也试过这个:
System.import('jquery')
.then(jQuery => {
window.jQuery = jQuery
})
import 'troublesome'
但是,事实证明 System.import
是所谓的 'module-loader' 规范的一部分,它是从 es6/2015 规范中提取出来的,因此没有提供由巴别塔。有一个 poly-fill,但 Webpack 无论如何都无法管理通过调用 System.import
完成的动态导入。
但是...如果我像这样调出 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
中解决,一切都很好,
但我更愿意避免脚本标记路由,因为 webpack 不管理这些。
任何人都可以推荐一个像样的策略来处理这种情况吗?
更新
在@TN1ck 的一些指导下,我最终能够使用 imports-loader
确定一个以 Webpack 为中心的解决方案
此解决方案的配置如下所示:
//...
module: {
loaders: [
//...
{
test: require.resolve('troublesome'),
loader: "imports?jQuery=jquery,$=jquery"
}
]
}
将 jQuery
导入到您的模块中不会使其可用于 'troublesome'
。相反,您可以为 'troublesome'
创建一个薄包装模块,它提供 jQuery
和任何其他所需的 "globals".
麻烦-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';
我在使用 jspm 和 dygraphs 时遇到了类似的问题。我解决它的方法是使用动态加载,就像您尝试使用 System.import
一样,但重要的部分是在 promise onfulfillment 处理程序中再次使用 System.import
链式加载每个连续的 "part" (然后)设置全局命名空间变量后。在我的场景中,我实际上必须在 then
个处理程序之间分隔几个导入步骤。
它不适用于 jspm 的原因,以及它对您不起作用的原因可能是 import ... from ...
语法在任何代码之前求值,而且肯定在 System.import
之前求值哪个异步。
在你的情况下,它可以像这样简单:
import jQuery from 'jquery';
window.jQuery = jQuery;
System.import('troublesome').then(troublesome => {
// Do something with it...
});
另请注意,System
模块加载器建议已被排除在最终的 ES6 规范之外,new loader spec 正在起草中。
填充模块是可行的方法:http://webpack.github.io/docs/shimming-modules.html
我从页面引用:
插件提供插件
这个插件使一个模块在每个模块中都可以作为变量使用。仅当您使用变量时才需要该模块。
示例:使 $ 和 jQuery 在每个模块中可用,而无需编写 require("jquery")
。
new webpack.ProvidePlugin({
$: "jquery",
jQuery: "jquery",
"window.jQuery": "jquery"
})
要将它与您的 webpack-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
}
对于 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's there if something wrong
//window.$ = $;//probably not needed but it's there if something wrong
然后就可以正常使用了
var text = $('<div />').text('hello world!!!').text();
console.log(text);
希望对您有所帮助。
- 运行
npm install import-loader
.
- 将
import 'troublesome'
替换为 import 'imports?jQuery=jquery,$=jquery!troublesome
。
在我看来,这是解决您问题的最简单方法。它类似于您在问题 @TN1ck 中写的答案,但没有更改您的 webpack 配置。更多阅读,请参阅:https://github.com/webpack/imports-loader
Shimming 很好,有多种方法可以解决这个问题,但根据我的回答 ,最简单的实际上只是恢复使用 require 来加载需要全局依赖的库 -然后只需确保您的 window。赋值在 require 语句之前,它们都在你的其他导入之后,你的顺序应该保持原样。该问题是由 Babel 提升导入引起的,因此它们都在任何其他代码之前执行。
我有这种情况,我试图导入一个现有的库,我将其称为 troublesome
(使用 Webpack/Babel FWIW)并且它具有对 jQuery
的全局引用在其中我试图使用模块语法来解决。
我已成功将 jquery 导入模块的 'local' 范围,通过:
import jQuery from 'jquery'
所以我尝试了:
import jQuery from 'jquery'
import 'troublesome'
但也许不足为奇,我从 troublesome.js
jQuery is not a function
之类的东西
我也试过这个:
System.import('jquery')
.then(jQuery => {
window.jQuery = jQuery
})
import 'troublesome'
但是,事实证明 System.import
是所谓的 'module-loader' 规范的一部分,它是从 es6/2015 规范中提取出来的,因此没有提供由巴别塔。有一个 poly-fill,但 Webpack 无论如何都无法管理通过调用 System.import
完成的动态导入。
但是...如果我像这样调出 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
中解决,一切都很好,
但我更愿意避免脚本标记路由,因为 webpack 不管理这些。
任何人都可以推荐一个像样的策略来处理这种情况吗?
更新
在@TN1ck 的一些指导下,我最终能够使用 imports-loader
确定一个以 Webpack 为中心的解决方案此解决方案的配置如下所示:
//...
module: {
loaders: [
//...
{
test: require.resolve('troublesome'),
loader: "imports?jQuery=jquery,$=jquery"
}
]
}
将 jQuery
导入到您的模块中不会使其可用于 'troublesome'
。相反,您可以为 'troublesome'
创建一个薄包装模块,它提供 jQuery
和任何其他所需的 "globals".
麻烦-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';
我在使用 jspm 和 dygraphs 时遇到了类似的问题。我解决它的方法是使用动态加载,就像您尝试使用 System.import
一样,但重要的部分是在 promise onfulfillment 处理程序中再次使用 System.import
链式加载每个连续的 "part" (然后)设置全局命名空间变量后。在我的场景中,我实际上必须在 then
个处理程序之间分隔几个导入步骤。
它不适用于 jspm 的原因,以及它对您不起作用的原因可能是 import ... from ...
语法在任何代码之前求值,而且肯定在 System.import
之前求值哪个异步。
在你的情况下,它可以像这样简单:
import jQuery from 'jquery';
window.jQuery = jQuery;
System.import('troublesome').then(troublesome => {
// Do something with it...
});
另请注意,System
模块加载器建议已被排除在最终的 ES6 规范之外,new loader spec 正在起草中。
填充模块是可行的方法:http://webpack.github.io/docs/shimming-modules.html
我从页面引用:
插件提供插件
这个插件使一个模块在每个模块中都可以作为变量使用。仅当您使用变量时才需要该模块。
示例:使 $ 和 jQuery 在每个模块中可用,而无需编写 require("jquery")
。
new webpack.ProvidePlugin({
$: "jquery",
jQuery: "jquery",
"window.jQuery": "jquery"
})
要将它与您的 webpack-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
}
对于 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's there if something wrong
//window.$ = $;//probably not needed but it's there if something wrong
然后就可以正常使用了
var text = $('<div />').text('hello world!!!').text();
console.log(text);
希望对您有所帮助。
- 运行
npm install import-loader
. - 将
import 'troublesome'
替换为import 'imports?jQuery=jquery,$=jquery!troublesome
。
在我看来,这是解决您问题的最简单方法。它类似于您在问题 @TN1ck 中写的答案,但没有更改您的 webpack 配置。更多阅读,请参阅:https://github.com/webpack/imports-loader
Shimming 很好,有多种方法可以解决这个问题,但根据我的回答