【问题标题】:Typescript + RequireJS compiler error on loading plugin加载插件时 Typescript + RequireJS 编译器错误
【发布时间】:2016-04-28 12:05:34
【问题描述】:

在编写 Typescripts 应用程序时,我使用 RequireJS 加载模块(我使用 Visual Studio 2015)。

我可以轻松地从我自己编写的 .ts 类中加载几乎所有模块,使用它们键入的 .d.ts 文件从外部库中加载。

但我的问题从我想为 jquery 加载插件的地方开始。

我正在使用库的类型文件,但逻辑上 .d.ts 文件中没有模块定义,因为它只是 jquery 的插件。

我已经遵循了从RequireJS website 加载 shim 库的建议,如下所示:

requirejs.config({
baseUrl: "Scripts",
paths: {
    "jquery": "jquery-2.2.3",
    "jquery.pjax": "jquery.pjax"
},
shim:
{
    "jquery.pjax":
    {
        deps: ["jquery"],
        exports: "jQuery.fn.pjax"
    }
}
});
require(["app"]);

并根据RequireJS website

shim 配置仅设置代码关系。要加载属于或使用 shim 配置的模块,需要正常的 require/define 调用。单独设置 shim 不会触发代码加载。

现在,以下两种方法都不能加载插件(即使将 jquery.pjax.d.t 移动到 jquery.pjax.js 旁边):

import * as pjax from "jquery.pjax";

import pjax = require("jquery.pjax");

import pjax = require("./jquery.pjax");

import pjax = require("jquery.pjax.js");

import pjax = require("./jquery.pjax.js");

编译器报错Cannot find module "jquery.pjax"File C:/foo/bar/jquery.pjax.d.ts is not a module

只要存在上述任何代码,app.ts 就不会被编译,当我删除它们时,插件不会被加载。

关于我在 app.ts 文件中使用了多个导入并且还会有更多导入,我更喜欢使用 import Foo = require("foo")import * as Foo from "foo" 模块加载样式,而不是手动编写 AMD 定义函数。

我也在使用 Nuget 包管理,我不喜欢手动编辑/移动外部 .d.ts 或 .js 文件。

谁能帮我解决这个问题?

【问题讨论】:

    标签: typescript requirejs


    【解决方案1】:

    如果您希望能够调用 require("jquery.pjax"),那么要么需要定义一个真正的 TypeScript 模块并且可以使用该名称找到它,要么需要在某处声明它:declare module "jquery.pjax"

    我认为您的选择是:

    • 在 RequireJ 之外完全加载 jQuery(例如,在页面中包含带有纯脚本标签的 jQuery 和 jQuery.pjax,并在全局范围内使用它们)。这就是您所拥有的 .d.ts 文件希望您执行的操作,因为 jQuery.pjax 实际上根本不是 RequireJS 模块(这就是您必须使用 shim 配置的原因)
    • 在你的代码库中添加一个模块声明并说服 TypeScript 它是一个真正的 RequireJS 模块。这可以在您现有的 jquery.pjax .d.ts 定义中,也可以在单独的文件中独立,如果这对您来说更容易的话。然后你可以要求这个。请注意,如果您需要它并且不引用它,TypeScript 不会实际输出依赖项,因此您需要对它的虚假引用。
    • 在 TypeScript 的模块系统之外手动使用 RequireJS 加载它。对于像这样的插件生态系统,我通常在我的 RequireJS 路径中给真正的库命名为“raw-libraryname”,然后自己创建一个新的“libraryname.ts”,它会引入原始库和插件,是否需要任何设置,并返回结果(其他人可以正常依赖)。例如:

      // Require config:
      requirejs.config({
          baseUrl: "Scripts",
          paths: {
              "raw-jquery": "jquery-2.2.3", // only plugins depend on this
              "jquery.pjax": "jquery.pjax",
              "jquery": "lib-wrappers/jquery" // everything else uses this which
                                              // includes all your plugins
          },
          shim:
          {
              "jquery.pjax":
              {
                  deps: ["raw-jquery"]
                  // I don't think you need an exports here.
                  // Anybody who wants this should be using it from jQuery.
              }
          }
      });   
      
      
      
      // in lib-wrappers/jquery.ts
      define(["raw-jquery", "jquery.pjax"], function ($) {
          // RequireJS guarantees that this line is run before anything that
          // depends on jQuery, and after both jQuery & any plugins above are loaded
          return $;
      });
      

      这确保了其他一切都可以通过 RequireJS 继续使用 jQuery,同时仍然保证非 requirejs 模块 (jquery.pjax) 在尝试从 jQuery 使用它之前准备好并加载。

    【讨论】:

    • 嗯,这是一个非常全面的答案。现在确认为答案。谢谢。 :)
    • 我确实回答了类似的问题,使用肯定类型检查这个stackoverflow.com/questions/21179144/…,蒂姆是对的!
    猜你喜欢
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 2016-01-02
    • 1970-01-01
    • 2019-07-08
    • 1970-01-01
    • 2016-04-02
    • 2013-03-23
    相关资源
    最近更新 更多