使用 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 定义导入的外部模块
从0开始的TypeScriptの五:webpack打包typescript