使用Typescript和RequireJS导入jqueryui

时间:2016-02-11 17:11:53

标签: jquery jquery-ui typescript requirejs

我一直无法正常运行jQueryUI。在我尝试添加jQueryUI之前,单独使用jQuery就可以了。

使用下面的代码,我目前得到" TypeError:jQuery不是一个函数(...)"在chrome中,这很奇怪,考虑到jquery在require.config文件中被标记为依赖项。

从.ts到.js的编译没有错误。

initApp.ts:

/// <reference path="../../../typings/jqueryui/jqueryui.d.ts"/>
import * as jQuery from "jquery"; //Works completely fine
import * as jQueryUI from "jquery-ui"; //Can't even find the module unless
                                       //d.ts file is modified

编译为js:

define(["require", "exports", "jquery-ui"], function (require, exports, jQuery) {...}

jqueryui.d.ts:

/// <reference path="../jquery/jquery.d.ts"/>
declare module JQueryUI { <unmodified code>}

//Added this declare

declare module "jquery-ui" {
  export = jQuery;
}

Require.config.js:

require.config({
    baseUrl: "./components/",
    paths: {
        "jquery": "./javascripts/lib/jquery-2.1.4",
        "jquery-ui": "./javascripts/lib/jquery-ui",
        "go": "./javascripts/lib/go-debug"
    },
    shim: {
        "jquery": {
          exports: "jQuery",
        },
        "jquery-ui": {
            //exports: "jQuery", //Adding this line doesn't fix the problem
            deps: ["jquery"],
        }
    },
});
require(["./javascripts/initApp"]);

目录树:

typings/
    jquery/
        jquery.d.ts
    jqueryui/
        jqueryui.d.ts
web/
    components/
        javascripts/
            lib/
                jquery-2.1.4.js
                jquery-ui.js
                require.js
            initApp.js
            initApp.ts
            require.config.js

指向完整d.ts文件的链接:

https://github.com/DefinitelyTyped/DefinitelyTyped/blob/master/types/jquery/index.d.ts(jquery V3.3)

https://github.com/DefinitelyTyped/DefinitelyTyped/blob/master/types/jqueryui/index.d.ts(QueryUI V1.12)

非常感谢任何帮助

4 个答案:

答案 0 :(得分:5)

那么会发生的是你有jQuery哪个有导出,jQueryUi导入jQuery,增加它,然后导出$.widget而不是$。

这就是为什么,正如我认为你已经指出的那样,

import * as jQuery from 'jquery-ui';

是有问题的。

当你继续注意时,

import jQueryUi from 'jquery-ui';

不起作用,因为jQueryUi从未在位置使用,因此它被编译器省略了,这实际上非常有用,如果棘手的行为可以产生许多异步加载场景更容易。

您需要的是一种告诉TypeScript执行库导入的方法,无论它是否实际使用,也就是说,我们正在导入它的副作用。

幸运的是,TypeScript有一个导入形式,而后者又来自ECMAScript

import 'jquery-ui';

应该这样做,你现在不应该为jQuery提供垫片(不要引用我的话,我的AMD生锈了。)

所以你应该只需要以下内容。

import $ from 'jquery';
// typescript will not remove this as the point of this syntax is: import for mutations!
import 'jquery-ui';

您不需要修改require.config(....),但我可能会误读它。

另外,请注意jquery-ui declarations,你可能应该更新(你的链接由于包重组而死了)没有声明导出并引用jQuery作为一个糟透了并且混淆了多版本的 .d.ts 场景,但不应该在你的情况下产生实际的运行时差异。

答案 1 :(得分:0)

我的初步解决方法曾经嵌入到我的问题正文中。我将其作为满足StackOverflow编辑指南的答案。

Aluan的回答直接回答了我在这个街区提出的一些问题。

我可以通过编辑已编译的javascript来手动修复错误,以包含“jquery”和“jquery-ui”模块,并将它们分配给变量:

  

define([“require”,“exports”,“ jquery ”,“ jquery-ui ”],函数(require,exports, jQuery < / strong>, jQueryUI ){...}

但是,我希望typescript编译器自动执行此操作,或类似于将jquery-ui和jquery设置为我文件的依赖项。

TypeScript获取声明的模块名称,并将该字符串编译为AMD define()函数的依赖项参数。因此,TypeScript定义d.ts文件必须使用在require.config.js中表示我的库的相同字符串来声明模块

只需拥有import语句就不会触发TypeScript编译器的任何操作。无论哪个变量(在这种情况下为foo),模块/库中的属性都需要至少调用一次,并且不能与该范围内的任何现有变量冲突。

之前,我使用过这一行:

  

从“jquery-ui”

导入*作为jQuery

这占用了'jQuery'变量名,因此,jQuery函数不再能够分配给该变量名,导致错误:“jQuery不是函数(...)”

由于jquery-ui只是扩展了jQuery库,我从不需要调用它。但编译器对我来说过于聪明,并决定不将jquery-ui实际编译为我的define(...)中的依赖项。一旦我意识到这个问题,这很容易解决。

最终代码

initApp.ts

/// <reference path="../../../typings/jqueryui/jqueryui.d.ts"/>
import * as jQueryUI from "jquery-ui";
import uiVar from "./uiVariables";
jQueryUI

编译为js:

  

define([“require”,“exports”,“jquery-ui”],function(require,exports,jQueryUI){...}

require.config.js

require.config({
    baseUrl: "./components/",
    paths: {
        "jquery": "./javascripts/lib/jquery-2.1.4",
        "jquery-ui": "./javascripts/lib/jquery-ui",
        "go": "./javascripts/lib/go-debug"
    }
});
require(["./javascripts/app"]);

答案 2 :(得分:0)

我在GitHub上制作了一个小例子,用于使用带有ES 6模块的TypeScript 2和带有自定义插件的JQuery / JQuery UI,我希望这会有所帮助: https://github.com/lgrignon/typescript-es6-jquery

答案 3 :(得分:0)

我也遇到了这个问题。在阅读了其中几个问题的答案相当混乱之后,我想出了以下内容:

包括每个文件顶部的引用路径将解决此问题。无需其他更改。 TS只需要知道在哪里可以找到描述所有可用功能的定义文件。在每个文件中包含直接引用可以解决这个问题:

/// <reference path="/typings/jquery.d.ts"/>
/// <reference path="/typings/someotherlibrary.d.ts"/>

我无法提及其他方法来正确解决。 (我认为我只是愚蠢,但代码中可能存在错误或API中的语法更改)如果要解决大量文件,这种方法可能不是最佳解决方案。