【问题标题】:How do you setup a require.js config with typescript?如何使用 typescript 设置 require.js 配置?
【发布时间】:2014-02-06 09:14:02
【问题描述】:

好的,我已经阅读了很多关于此的问题和答案,其中很多都是垃圾。

我有一个非常简单的问题。我该如何做相当于这个:

require.config({
    paths: {
        "blah": '/libs/blah/blah',
    }
}); 
require(['blah'], function(b) {
    console.log(b); 
});

在打字稿中?

这不起作用:

declare var require;
require.config({
    paths: {
        "blah": '/libs/blah/blah',
    }
});
import b = require('blah');
console.log(b);

s.ts(8,1): error TS2071: Unable to resolve external module ''blah''.
s.ts(8,1): error TS2072: Module cannot be aliased to a non-module type.
error TS5037: Cannot compile external modules unless the '--module' flag is provided.

使用 --module 标志编译,使用虚拟 blah.ts shim 编译,但输出为:

define(["require", "exports", 'blah'], function(require, exports, b) {
    require.config({
        paths: {
            "blah": '/libs/blah/blah'
        }
    });

    console.log(b);
});

看起来可能可行,但实际上不行,require.config require 块中,它是在 它已经需要之后设置的。

所以!到目前为止,我已经以 this 作为解决方案:

class RequireJS {

    private _r:any = window['require'];

    public config(config:any):void {
        this._r['config'](config);
    }

    public require(reqs:string[], callback:any):void {
        this._r(reqs, callback);
    }
}

var rjs = new RequireJS();
rjs.config({
    paths: {
        "jquery": '/libs/jquery/jquery',
        "slider": '/js/blah/slider'
    }
});

rjs.require(['slider'], function(slider) {
    console.log(slider);
});

这看起来很糟糕。

所以要清楚,在相互依赖的模块内部,这种事情工作得非常好:

import $ = require('jquery');
export module blah {
   ...
}

我只需要一种正确的方法在顶层设置 requirejs 配置,以便各种命名模块的导入路径正确。

(...这主要是因为第 3 方依赖项是使用 bower 解决的,并安装在 /lib/blah 中,因为我为其定义所拥有的 shim 文件位于 src/deps/blah.d .ts,所以将生成的模块文件移动到站点上的/js/后默认导入路径不正确)

注意。我在这里提到了 jquery,但问题是 not jquery 不能作为 AMD 模块工作;我有一个垫片 jquery.ts.d 文件。这里的问题是 requirejs 路径。

【问题讨论】:

标签: requirejs typescript


【解决方案1】:

如果你想将import 用于 javascript 模块,你需要告诉 typescript ,

declare var require;
require.config({
    paths: {
        "blah": '/libs/blah/blah',
    }
});

// Important, place in an external.d.ts: 
declare module 'blah'{
   // your opportunity to give typescript more information about this js file
   // for now just stick with "any"
   var mainobj:any;
   export = mainobj;
}

import b = require('blah');
console.log(b);

或者你可以简单地做:

var b = require('blah'); 它应该也可以工作

【讨论】:

  • 嗯...你读过我的问题吗?如果您在同一个文件中有一个 import 语句,它将被包装在一个模块中。您的示例仅在顶级文件(调用 require.config 的位置)没有导入语句时才有效。然而,它是 top level fileneeds import 语句,这就是重点(否则 import b = require('blah') 将如何被调用?)请参阅上面我的问题上面的位,上面写着“看起来它可能有效,但实际上没有,require.config 在 require 块内,它是在已经需要它之后设置的。”
【解决方案2】:

昨天我在我的博客-http://edcourtenay.co.uk/musings-of-an-idiot/2014/11/26/typescript-requirejs-and-jquery 上写了一个解决这个确切问题的方法:

TL;DR - 创建一个配置文件 config.ts,类似于:

requirejs.config({
    paths: {
        "jquery": "Scripts/jquery-2.1.1"
    }
});

require(["app"]);

并确保您的 RequireJS 入口点指向新的配置文件:

<script src="Scripts/require.js" data-main="config"></script>

您现在可以在 TypeScript 文件中使用 $ 命名空间,只需使用

import $ = require("jquery")

希望对你有帮助

【讨论】:

  • "找不到外部模块'jquery'"
  • 是的,我们一直在为所有库使用类似的解决方案。你仍然可以使用相对路径来导入你自己的模块,require 和 typescript 都会理解这一点。
【解决方案3】:

这篇文章已有 3 年历史,在使用 Typescript 时进行了很多更改。无论如何,在网上搜索后,对 TS 文档进行了一些研究——这些人做得很好,我发现了一些可以提供帮助的东西。 所以这可以适用于最新的TS(2.2.1) 你可能知道你可以使用

npm install --save @types/jquery

对你的第 3 方 JS 库做同样的事情,比如 require 现在你需要定义你的 TypeScript 编译器必须做什么以及如何做,所以创建一个 tsconfig.json 文件,其中包含:

// tsconfig.json file
{
   "compilerOptions": {
   "allowJs": true,
   "baseUrl": "./Scripts",//Same as require.config
   "module": "amd",
   "moduleResolution": "Node",//to consider node_modules/@types folders
   "noImplicitAny": false,
   "target": "es5", // or whatever you want
   "watch": true
}

现在,让我们专注于 require 的配置

// require-config.ts
declare var require: any;
require.config({
   baseUrl: "./Scripts/",
   paths: {
      "jquery": "vendor/jquery/jquery.x.y.z"
      // add here all the paths your want
      // personnally, I just add all the 3rd party JS librairies I used
      // do not forget the shims with dependencies if needed...
   }
});

到目前为止一切顺利 现在专注于您用 TS 编写的模块,该模块将使用 jquery,并且位于 Scripts/Module 文件夹中:

// module/blah.ts
/// <amd-module name="module/blah" />
import $ = require("jquery");
export function doSomething(){
    console.log("jQuery version :", $.version);
}

所以这个答案看起来和 Ed Courtenay 的一样,不是吗? 和 user210757 提到它不起作用! 它没有!如果您在控制台中输入tsc -w --traceResolution,您会看到 tsc 找不到任何 jquery 定义。 假设您之前通过这样做启动了npm install --save @types/jquery,以下是缓解方法,在名为node_modules\@types 的文件夹中,您应该获得 jquery 的 TS 定义

  • 选择 jquery 子文件夹中的 package.json 文件

  • 寻找 "main" 属性

  • 将其设置为 "jquery",与您在 require.config 中使用的别名相同 完成了!您的模块将被编译为

     define("module/blah", ["require", "exports", "jquery"], function (require, exports, $) {
        "use strict";
        Object.defineProperty(exports, "__esModule", { value: true });
        function doSomething() {
          console.log("jQuery version:", $.fn.jQuery);
        }
        exports.doSomething = doSomething;
     });
    

我觉得那个 JS 代码不错! 我只是不喜欢我们的模块依赖项列表 "require""exports",这听起来像是一个 TS 问题,但无论如何它都能正常工作!

【讨论】:

  • 如果你绝对想用 requireJS 写你的 require-config.ts 而不是写“declare var require:any;” ,你只需要使用这个终端命令:“npm install -S @types/requireJS”然后在你的require-config.ts文件中添加3slash指令:“/// ”跨度>
猜你喜欢
  • 2013-01-28
  • 1970-01-01
  • 2014-05-28
  • 2012-11-19
  • 1970-01-01
  • 1970-01-01
  • 2021-12-26
  • 2020-09-09
相关资源
最近更新 更多