【问题标题】:Importing jqueryui with Typescript and RequireJS使用 Typescript 和 RequireJS 导入 jqueryui
【发布时间】:2016-02-11 17:11:52
【问题描述】:

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

使用下面的代码,我目前在 chrome 中得到“TypeError: jQuery is not a function(...)”,这很奇怪,考虑到 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)

任何帮助将不胜感激

【问题讨论】:

  • 我已删除您添加到问题中的解决方案。本网站的编辑做法是,必须将解决方案作为答案发布,以便人们可以独立从问题中对解决方案进行投票。所以你应该发布你的解决方案作为答案。您可以返回问题的编辑历史,找到添加解决方案的编辑,单击“源”按钮,复制源并将其粘贴到答案表单中。最多需要 2 分钟。

标签: jquery jquery-ui typescript requirejs


【解决方案1】:

所以发生的情况是你有一个导出的 jQuery,以及导入 jQuery、扩充它的 jQueryUi,然后导出 $.widget 而不是 $。

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

import * as jQuery from 'jquery-ui';

有问题。

如你所说,

import jQueryUi from 'jquery-ui';

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

您需要一种方法告诉 TypeScript 执行库的导入,而不管它是否实际使用,也就是说,我们导入它是为了它的副作用。

幸运的是,ECMAScript 有一个专门为此场景提供的导入表单。通过写作

import 'jquery-ui';

您表示您依赖 'jquery-ui' 的副作用。

此外,这些天你不需要 jQuery 的垫片(不要引用我的话,我的 AMD 生锈了)。

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

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

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

另外,请注意jquery-ui declarations,您可能应该更新它(由于包重组,您的链接已失效)没有声明导出并将 jQuery 引用为全局,这会导致多版本 .d .ts 场景,但不应在您的情况下产生实际的运行时差异。

【讨论】:

  • 当我尝试import $ from 'jquery'import * as $ from "jquery" 时,我得到Module jquery has no default export 的错误。我在这里还缺少另一件吗?我需要从npmjs.com/package/@types/jqueryui 编辑我的导入吗?
  • @azulBonnet 你需要在 TypeScript 中使用--allowSyntheticDefaultImports。如果失败,请改用import $ = require('jquery');,但永远不要永远使用import * as $ from 'jquery';
  • 谢谢@Aluan,但似乎我无法工作。使用require,我收到require cannot be used when targeting ECMAScript6 or higher 的警告。但也许我的tsconfig.json 是一些完全不同的设置:{ "compilerOptions": { "outDir": "./wwwroot/build/", "noImplicitAny": false, "noEmitOnError": true, "removeComments": false, "sourceMap": true, "target": "es6", "module": "amd", "moduleResolution": "node", "allowSyntheticDefaultImports": true }, "exclude": [ "node_modules", "wwwroot" ] }
  • 那么你的堆栈的一部分是旧的/损坏的。无论如何,--module--target 不一样。
  • @AluanHaddad 您能否详细说明为什么永远不应使用import * as $ from 'jquery' 或提供链接?我有兴趣了解更多信息。
【解决方案2】:

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

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

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

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

【讨论】:

    【解决方案3】:

    我最初的解决方法曾经嵌入到我的问题正文中。我将其转发为符合 StackOverflow 编辑指南的答案。

    阿銮的回答直接回答了我在这个板块提出的一些问题。


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

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

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

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

    仅使用 import 语句不会触发 TypeScript 编译器的任何操作。无论从模块/库中导入哪个变量(在本例中为 foo),都需要至少调用一次,并且不能与该范围内的任何现有变量冲突。

    早些时候,我使用了这一行:

    从“jquery-ui”导入 * 作为 jQuery

    这占用了'jQuery'变量名,因此无法再将jQuery函数分配给该变量名,导致错误:“jQuery is not a function(...)”

    由于 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"]);
    

    【讨论】:

    • 你试过import 'jquery-ui';吗?导入不会使用模块格式“AMD”或任何其他格式删除。
    【解决方案4】:

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

    【讨论】:

    • 在 JQuery 和 JQueryUI 中使用 Typescript 需要 Babel 吗?
    • @azulBonnet 不,不是
    猜你喜欢
    • 2016-05-04
    • 1970-01-01
    • 2019-05-20
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 2013-09-09
    • 2022-07-20
    • 2019-10-22
    相关资源
    最近更新 更多