javascript 我可以使用 ES6/2015 模块导入在“全局”范围内设置引用吗?
声明:本页面是StackOverFlow热门问题的中英对照翻译,遵循CC BY-SA 4.0协议,如果您需要使用它,必须同样遵循CC BY-SA许可,注明原文地址和作者信息,同时你必须将它归于原作者(不是我):StackOverFlow
原文地址: http://stackoverflow.com/questions/31197220/
Warning: these are provided under cc-by-sa 4.0 license. You are free to use/share it, But you must attribute it to the original authors (not me):
StackOverFlow
Can I use an ES6/2015 module import to set a reference in 'global' scope?
提问by tony_k
I have this situation where I am trying to import an existing library, which I'll call troublesome
(using Webpack/Babel FWIW) and it has a global reference to jQuery
in it which i am trying to resolve using module syntax.
我有这种情况,我试图导入一个现有的库,我将调用它troublesome
(使用 Webpack/Babel FWIW)并且它有一个全局引用jQuery
,我试图使用模块语法解决它。
I have successfully imported jquery into the 'local' scope of a module, via:
我已经成功地将 jquery 导入到模块的“本地”范围内,通过:
import jQuery from 'jquery'
so I tried:
所以我试过:
import jQuery from 'jquery'
import 'troublesome'
but perhaps not surprisingly, I get something like jQuery is not a function
kicked back from troublesome.js
但也许并不奇怪,我得到了一些像被jQuery is not a function
踢回来的东西troublesome.js
I have tried this as well:
我也试过这个:
System.import('jquery')
.then(jQuery => {
window.jQuery = jQuery
})
import 'troublesome'
but, it turns out that System.import
is part of the, so-called, 'module-loader' spec, which was pulled from the es6/2015 spec, so it isn't provided by Babel. There is a poly-fill, but Webpack wouldn't be able to manage dynamic imports accomplished via calls to System.import
anyway.
但是,事实证明这System.import
是所谓的“模块加载器”规范的一部分,该规范是从 es6/2015 规范中提取的,因此它不是由 Babel 提供的。有一个poly-fill,但 Webpack 无论如何都无法管理通过调用完成的动态导入System.import
。
but... if I call out the script files in index.html like so:
但是...如果我像这样调用 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>
the reference to jQuery
is resolved in troublesome.js
and things are good,
but I would prefer to avoid the script tag route as webpack doesn't manage those.
对 的引用jQuery
已解决troublesome.js
,一切都很好,但我更愿意避免使用脚本标记路由,因为 webpack 不管理这些路由。
Can anyone recommend a decent strategy for dealing with scenarios like this?
谁能推荐一个像样的策略来处理这样的场景?
update
更新
with some guidance from @TN1ck, I was eventually able to identify one Webpack-centric solution, using the imports-loader
在@TN1ck 的一些指导下,我最终能够使用imports-loader确定一个以Webpack 为中心的解决方案
The configuration for this solution looks something like this:
此解决方案的配置如下所示:
//...
module: {
loaders: [
//...
{
test: require.resolve('troublesome'),
loader: "imports?jQuery=jquery,$=jquery"
}
]
}
采纳答案by TN1ck
Shimming modules is the way to go: http://webpack.github.io/docs/shimming-modules.html
垫片模块是要走的路:http://webpack.github.io/docs/shimming-modules.html
I quote from the page:
我从页面引用:
plugin ProvidePlugin
插件提供插件
This plugin makes a module available as variable in every module. The module is required only if you use the variable.
该插件使模块可用作每个模块中的变量。仅当您使用变量时才需要该模块。
Example: Make $ and jQuery available in every module without writing require("jquery")
.
示例:无需编写require("jquery")
.
new webpack.ProvidePlugin({
$: "jquery",
jQuery: "jquery",
"window.jQuery": "jquery"
})
To use this with your webpack-config just add this object to an array called plugins in the config:
要在 webpack-config 中使用它,只需将此对象添加到配置中名为 plugins 的数组中:
// 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
}
回答by Val
For es6/2015 I done the following.
对于 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
Then you can use it as normal
然后就可以正常使用了
var text = $('<div />').text('hello world!!!').text();
console.log(text);
Hope this helps.
希望这可以帮助。
回答by thisissami
- run
npm install import-loader
. - replace
import 'troublesome'
withimport 'imports?jQuery=jquery,$=jquery!troublesome
.
- 跑
npm install import-loader
。 - 替换
import 'troublesome'
为import 'imports?jQuery=jquery,$=jquery!troublesome
.
In my opinion, this is the simplest solution to your question. It is similar to the answer you wrote in your question @TN1ck, but without altering your webpack config. For more reading, see: https://github.com/webpack/imports-loader
在我看来,这是解决您问题的最简单方法。它类似于您在问题@TN1ck 中写的答案,但不更改您的 webpack 配置。更多阅读请参见:https: //github.com/webpack/imports-loader
回答by Ben Logan
Shimming is fine and there are various ways of resolving this, but as per my answer here, the simplest is actually just to revert to using require for the loading of the library that requires the global dependency - then just make sure your window. assignment is before that require statement, and they are both after your other imports, and your ordering should remain as intended. The issue is caused by Babel hoisting imports such that they all get executed before any other code.
Shimming 很好,有多种方法可以解决这个问题,但根据我在此处的回答,最简单的方法实际上只是恢复使用 require 来加载需要全局依赖项的库 - 然后确保您的 window. 赋值在那个 require 语句之前,它们都在你的其他导入之后,你的排序应该保持原样。该问题是由 Babel 提升导入导致的,因此它们都在任何其他代码之前执行。
回答by Noah Freitas
Importing jQuery
into your module does not make it available for 'troublesome'
. Instead, you could create a thin wrapper module for 'troublesome'
that provides jQuery
and any other required "globals".
导入jQuery
您的模块不会使其可用于'troublesome'
. 相反,您可以'troublesome'
为该提供者jQuery
和任何其他所需的“全局变量”创建一个瘦包装器模块。
troublesome-module.js:
麻烦的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.
Then in your code you should be able to
然后在您的代码中,您应该能够
import 'troublesome-module';
回答by Amit
I've had a similar issue using jspm and dygraphs. The way i solved it was to use dynamic loading like you attempted using System.import
but the important part was to chain-load each consecutive "part" using System.import
again inside the promise onfulfillment handler (then) after setting the global namespace variable. In my scenario I actually had to have several import steps separated between then
handlers.
我在使用 jspm 和 dygraphs 时遇到了类似的问题。我解决它的方法是使用动态加载,就像您尝试使用的那样,System.import
但重要的部分是System.import
在设置全局命名空间变量后,在 promise onfulfillment 处理程序(then)中再次使用链式加载每个连续的“部分” 。在我的场景中,我实际上必须在then
处理程序之间分离几个导入步骤。
The reason it didn't work with jspm, and probably why it didn't work for you as well is that the import ... from ...
syntax is evaluated before any code, and definitely before System.import
which of async.
它不适用于 jspm 的原因,以及它对您不起作用的原因可能是import ... from ...
语法在任何代码之前进行评估,并且绝对在System.import
async之前。
In your case it could be as simple as:
在您的情况下,它可能很简单:
import jQuery from 'jquery';
window.jQuery = jQuery;
System.import('troublesome').then(troublesome => {
// Do something with it...
});
Also note that the System
module loader recommendation has been left out of the final ES6 specification, and a new loader specis being drafted.
另请注意,System
模块加载器推荐已被排除在最终 ES6 规范之外,并且正在起草新的加载器规范。