使用 WebPack + TypeScript 定义导入的外部模块

Posted

技术标签:

【中文标题】使用 WebPack + TypeScript 定义导入的外部模块【英文标题】:Defining an imported external module with WebPack + TypeScript 【发布时间】:2015-08-07 02:44:42 【问题描述】:

我正在尝试使用 TypeScript 和一些外部库设置 WebPack,但遇到了一些问题。

我正在导入 jQuery 的 src 版本,以便让 WebPack 选择所需的模块(这是让 Boostrap-SASS 加载器工作所必需的),所以我在我的 TS 中导入这样的库:

import jquery = require( 'jquery/src/jquery.js' );

编译时,这会引发错误cannot find external module 'jquery/src/jquery'。如果我创建一个手动 .d.ts 文件来定义库,如下所示:

declare module "jquery/src/jquery"

然后编译器工作,但警告:

cannot invoke an expression whose type lacks a call signature

或者,如果我将导入行更改为

var jquery = require( 'jquery/src/jquery' );

(我认为这是一个 CommonJS 样式的导入?)然后一切编译(和运行)都很好。所以,问题:

有没有更好的方法来使用 WebPack 要求/包含源文件? 什么是定义模块以使其不缺少调用信号的正确方法? 我应该担心使用 var 而不是 import 还是只要它有效就继续使用它吗?

我刚刚开始使用 WebPack,所以我完全有可能在做一些愚蠢的事情。如果有请指正!

编辑:

当我在思考如何表达这个问题时,我想到了:

declare module "jquery/src/jquery"  export = $; 

这似乎让我可以使用“import...” - 但这是处理这个问题的好方法吗?

编辑 2:

在下面回复@basarat 的回答(我的评论有点长,没有换行符):

我已经在使用来自 distinctlyTyped 的 jquery def,但它本身不起作用,因为我需要的模块是 "jquery/src/jquery" 而不仅仅是 “jQuery”。如果我使用“jquery”,则会加载 jquery 的已编译 dist 版本,这不适用于 Bootstrap 加载器。

所以我认为declare module "jquery/src/jquery" export = $; 是对现有定义的扩展,但使用了我需要从中加载它的路径。

【问题讨论】:

Tom,我正在努力解决同样的问题 - 我似乎无法找到如何在 webpack/TypeScript 构建中正确包含第三方代码(如 jQuery 等)的好来源。您愿意分享更多您的解决方案吗? @JasonBrubaker 我在下面添加了我的解决方案作为答案。希望对您有所帮助! 【参考方案1】:

import jquery = require('jquery/src/jquery.js');

请改用 jquery 的明确类型定义:https://github.com/borisyankov/DefinitelyTyped/blob/master/jquery/jquery.d.ts#L3158-L3160,它已经允许您执行 import jquery = require('jquery')

【讨论】:

谢谢 - 我已经在使用这个定义了。我已通过回复更新了我的问题。【参考方案2】:

为了回答我自己的问题,这就是我最终要做的。

注意,我不知道这是否是实现这一目标的“正确”方式(我怀疑不是),所以我愿意接受任何有更好答案的人!

在我的 TS 定义文件 tsd.d.ts 我有绝对类型的 jQuery 定义:

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

但仅靠编译器从 node_modules 文件夹中获取 jQuery 源文件是不够的。

所以我添加了更进一步的 tsd.d.ts:

declare module "jquery/src/jquery"

    export = $;

编译器现在可以找到 jQuery 源文件。

我还必须为 WebPack 编译器编辑其中一个 jQuery 源文件才能很好地使用它:selector.js 默认情况下不包含工厂函数,而 WebPack 需要一个在场。

有一个loader that says it fixes this,但我无法让它工作,所以我只是将 selector.js 中的代码更改为:

define([ "./selector-sizzle" ], function());

这一切都让人觉得有点老套……但它让我克服了这个特殊的障碍。

【讨论】:

以上是关于使用 WebPack + TypeScript 定义导入的外部模块的主要内容,如果未能解决你的问题,请参考以下文章

webpack+typescript入门实例

使用 WebPack + TypeScript 定义导入的外部模块

使用源映射和 webpack 调试 typescript

从0开始的TypeScriptの五:webpack打包typescript

从0开始的TypeScriptの五:webpack打包typescript

Webpack 中 Typescript 的源映射(使用 webpack-dev-server 时看不到源映射)