【问题标题】:Using TypeScript with Dojo - import/export issues将 TypeScript 与 Dojo 一起使用 - 导入/导出问题
【发布时间】:2016-08-23 08:24:45
【问题描述】:

在我工作的公司中,我们正在使用 Dojo 框架,最近我开始推动将它与 TypeScript 一起使用。 我环顾四周,发现了这篇关于这个主题的精彩文章,你可以在这里找到它: https://gregwiechec.com/2016/01/creating-dojo-widget-in-typescript/

此解决方案的最后两行是:

var exp = _declare("alloy.editors.StringListTs", [_Widget, _TemplatedMixin, _WidgetsInTemplateMixin, _CssStateMixin, _ValueRequiredMixin], new StringList());

export = exp;

我遵循相同的模式并且效果很好,除了 2 个我似乎无法找到好的可靠解决方案的问题: 1.如果看解决方法,调用dojo的declare方法时,创建的类需要实例化(这是因为dojo看的是属性而不是原型)。 2. 更成问题的问题是,我导出的是 dojo 声明的对象,而不是它自己的类。当您尝试导入类(打字稿导入)时,这是有问题的,即使我将变量 exp 声明为类类型,我也会收到一条错误消息,指出我要导入的内容没有构造函数。

【问题讨论】:

    标签: import typescript dojo export


    【解决方案1】:

    我遇到了同样的问题,对我来说是一个转译器问题。

    TL;DR 如果您使用 import * as WidgetName from '<path>' 语法导入某些内容并且不在 js 中使用 WidgetName(就像您对模板中的小部件所做的那样),则转译器赢了不要导入它。请改用import '<path>'


    长答案:这是我第一次使用 TypeScript,同样,我正在将一个 dojo 项目转换为 TypeScript。希望能帮助到更多的人,我会放几个步骤来帮助我正确导入模块。

    步骤 0dojoConfig 包

    在 dojoConfig 上定义你自己的包是行不通的,必须使用相对路径来引用模块。

    要清楚,用这个例子:

    dojoConfig = {
        ...
        packages : [ { name : "myproject",    location : "js/myproject" },
                     { name : "dojo",  location : dojoBase+"dojo"   }, 
                     { name : "dijit", location : dojoBase+"dijit" },
                     { name : "dojox", location : dojoBase+"dojox"  } ]
    };
    

    不可能使用import * as WidgetName from 'myproject/WidgetName' 方法让小部件相互导入,而是您必须使用import * as WidgetName from './WidgetName'(注意'.' 与'myproject')。

    第 1 步:导入 dojo 声明(据我所知,不是强制性的)

    我依赖节点,我使用npm install dojo-typings --save-dev 提取了 dojo-typing。在files 属性中,我指定了[ "src/js/**/*.ts", "src/js/**/*.js", "node_modules/dojo-typings/dojo/1.11/index.d.ts", "node_modules/dojo-typings/dojo/1.11/modules.d.ts", "node_modules/dojo-typings/dijit/1.11/index.d.ts", "node_modules/dojo-typings/dijit/1.11/modules.d.ts" ]

    第 2 步:使用转译器上的正确选项:

    {
        "target": "es5",
        "allowJs": true,
        "module": "amd",
        "moduleResolution": "classic",
        "noImplicitUseStrict" : true
    },
    

    noImplicitUseStrict 解决了错误 dojo/parser::parse() 错误 TypeError: 'caller', 'callee', and 'arguments' properties may not be access on strict mode functions 或 arguments 对象的调用给他们allowJs 允许我将 TypeScript 和原生 dojo 混合在一起。

    第 3 步:使用导出返回

    这是一个非常小的模块示例,它不需要/导入任何东西,而只导出一个log 方法(文件将是“toast.ts”):

    const log  = function(message) { 
        window['dojo'].publish("mainTopic",
                [{
                    message: "<span style='font-size: 12px;'>" + message +"</span>",
                    type: 'info',
                    duration: 3000
                }]
            );
    }
    
    export { log }
    

    为了完整起见,在纯 Dojo 中,您会编写类似(文件将是 'toast.js'):

    define([ ],
    
            function(){
    
        var log = function(message) {
            dojo.publish("mainTopic",
                    [{
                        message: "<span style='font-size: 12px;'>" + message +"</span>",
                        type: 'info',
                        duration: 3000
                    }]
                );
        };
    
        return { log : log };
    
    });
    

    第 4 步:重写您的小部件并正确导入

    我使用了一个 Main 小部件,它包含所有主体,这里是 Main.ts 的内容:

    /// <amd-dependency path="dojo/text!./Main.html" name="template" />
    declare var template: string;
    
    import * as _Widget from 'dijit/_Widget';
    import * as _TemplatedMixin from 'dijit/_TemplatedMixin';
    import * as _WidgetsInTemplateMixin from 'dijit/_WidgetsInTemplateMixin';
    import * as dojoDeclare from 'dojo/_base/declare';
    
    import './MyVanillaJavascriptWidget';
    import './MyModule';
    import 'dojox/widget/Toaster';
    
    import toast = require('./utility/toast');
    
    export default dojoDeclare("mm.Main", [ _Widget, _TemplatedMixin, _WidgetsInTemplateMixin ], {
        templateString : template,
    });
    

    有不同类型的导入:

    1. 第一个是我最苦恼的一个,为了模板
    2. import * as ... 是我在课堂上使用的一系列 dojo 对象
    3. import '&lt;path&gt;' 用于我在模板中使用 data-dojo-type 声明的小部件
    4. import name = require('&lt;path&gt;') 是另一种需要模块的方式

    为了完整起见,这将是原始 Main.js 文件:

    define([ "dijit/_Widget", "dijit/_TemplatedMixin", "dijit/_WidgetsInTemplateMixin",
             "dojo/_base/declare", "dojo/text!./Main.html",
             "dojox/widget/Toaster", "./MyVanillaJavascriptWidget", "./MyModule"
             ],
    
        function(   _Widget, _TemplatedMixin, _WidgetsInTemplateMixin, declare, mainTemplate, toast) {
    
        return declare("mm.Main", [ _Widget, _TemplatedMixin, _WidgetsInTemplateMixin ], {
    
            templateString : mainTemplate,
    
        });
    
    });
    

    结论:缺少构造函数很可能来自您导入模块的方式,检查转译代码帮助我了解问题所在。要成功导入,需要在各处保持一定的准确性(以上所有步骤都应提供概述)。


    我仍在转换我的项目(可能会出现其他问题),但我希望这也有助于其他尝试将 TypeScript 与 Dojo 一起使用的可怜人!

    【讨论】:

      猜你喜欢
      • 1970-01-01
      • 2020-11-17
      • 2015-07-24
      • 2017-03-16
      • 2019-05-07
      • 2022-10-04
      • 2017-12-22
      • 1970-01-01
      相关资源
      最近更新 更多