34

我有这种情况,我试图导入一个现有的库,我将调用它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

但是...如果我像这样调用 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"
      }
    ]
  }
4

6 回答 6

16

匀场模块是要走的路:http ://webpack.github.io/docs/shimming-modules.html

我从页面引用:

插件提供插件

这个插件使一个模块在每个模块中都可以作为变量使用。仅当您使用该变量时才需要该模块。

示例:使 $ 和 jQuery 在每个模块中都可用,而无需编写require("jquery").

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

要将它与您的 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
}
于 2015-07-06T19:01:35.300 回答
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'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);

希望这可以帮助。

于 2015-11-10T11:54:17.777 回答
0

导入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';
于 2015-07-05T20:05:10.483 回答
0

我在使用 jspm 和 dygraphs 时遇到了类似的问题。我解决它的方法是像您尝试使用的那样使用动态加载,但重要的部分是在设置全局命名空间变量后,在 promise onfulfillment 处理程序(然后)中再次System.import使用链式加载每个连续的“部分” 。System.import在我的场景中,我实际上必须在then处理程序之间分离几个导入步骤。

它不能与 jspm 一起使用的原因,以及它对您也不起作用的原因可能是import ... from ...语法在任何代码之前进行评估,并且肯定在System.importasync 之前评估。

在您的情况下,它可能很简单:

import jQuery from 'jquery';

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

另请注意,System模块加载器建议已被排除在最终的 ES6 规范之外,并且正在起草新的加载器规范。

于 2015-07-05T21:11:57.637 回答
0
  1. 运行npm install import-loader
  2. 替换import 'troublesome'import 'imports?jQuery=jquery,$=jquery!troublesome.

在我看来,这是您问题的最简单的解决方案。它类似于您在问题@TN1ck 中写的答案,但不会更改您的 webpack 配置。更多阅读请参见:https ://github.com/webpack/imports-loader

于 2016-11-23T01:06:18.010 回答
0

匀场很好,有多种方法可以解决这个问题,但根据我在这里的回答,最简单的实际上只是恢复使用 require 来加载需要全局依赖的库 - 然后只需确保你的窗口。赋值在 require 语句之前,并且它们都在您的其他导入之后,并且您的排序应保持预期。该问题是由 Babel 提升导入引起的,因此它们都在任何其他代码之前执行。

于 2016-11-28T14:37:16.237 回答