Ext JS 6应用程序Build后出现“c is not a constructor return new c(a[0])”的处理

概述

在对Ext JS 6的应用程序打包后,时不时会出现以下错误:

由于是压缩后出现的错误,要进行调试也无从下手,因而这个错误会令新手手足无措,不知道是怎么回事。

错误原因

造成该错误的主要原因是要创建的类在打包时没有包含在包内,又或者是类名错误造成的。我遇到的一个比较典型的错误就是在requires中使用了Ext.MessageBox而不是Ext.window.MessageBox,就会出现该错误。

解决办法

虽然知道该错误是由于类名造成的,但苦于无法知道是那个文件中的requires出现的问题,因而要解决这个问题也很棘手,不过主要有足够耐心,还是能解决的。

该错误出现的地方是在应用程序ext\packages\core\src\class目录下的ClassManager.js文件中的getInstantiator方法内,代码如下:

getInstantiator: function(length) {
    var instantiators = this.instantiators,
        instantiator,
        i,
        args;

    instantiator = instantiators[length];

    if (!instantiator) {
        i = length;
        args = [];

        for (i = 0; i < length; i++) {
            args.push(‘a[‘ + i + ‘]‘);
        }

        instantiator = instantiators[length] = new Function(‘c‘, ‘a‘, ‘return new c(‘ + args.join(‘,‘) + ‘)‘);
        //<debug>
        instantiator.name = "Ext.create" + length;
        //</debug>
    }

    return instantiator;
},

错误中的代码就是由“instantiator=”这句代码(文件的895行)自动生成的。这段代码的主要作用是创建一个新的类实例并返回该实例,而当该类不存在或类名错误的时候,因为创建不了类的实例,就会出现错误。

出现问题的地方已经找到,但要解决问题,不能在这里,因为在该函数内要查找是那个类出现错误,也很困难,因为调用该类的时候传递给该类的可能是一个空的类名,因而,需要在调用该方法时去查。

通过在ClassManager.js文件中搜索getInstantiator,会发现在create方法内调用了该方法,代码如下:

create: function () {
    var name = arguments[0],
        nameType = typeof name,
        args = arraySlice.call(arguments, 1),
        cls;

    if (nameType === ‘function‘) {
        cls = name;
    } else {
        if (nameType !== ‘string‘ && args.length === 0) {
            args = [name];
            if (!(name = name.xclass)) {
                name = args[0].xtype;
                if (name) {
                    name = ‘widget.‘ + name;
                }
            }
        }

        //<debug>
        if (typeof name !== ‘string‘ || name.length < 1) {
            throw new Error("[Ext.create] Invalid class name or alias ‘" + name +
                            "‘ specified, must be a non-empty string");
        }
        //</debug>

        name = Manager.resolveName(name);
        cls = Manager.get(name);
    }

    // Still not existing at this point, try to load it via synchronous mode as the last resort
    if (!cls) {
        //<debug>
        //<if nonBrowser>
        !isNonBrowser &&
        //</if>
        Ext.log.warn("[Ext.Loader] Synchronously loading ‘" + name + "‘; consider adding " +
             "Ext.require(‘" + name + "‘) above Ext.onReady");
        //</debug>

        Ext.syncRequire(name);

        cls = Manager.get(name);
    }

    //<debug>
    if (!cls) {
        throw new Error("[Ext.create] Unrecognized class name / alias: " + name);
    }

    if (typeof cls !== ‘function‘) {
        throw new Error("[Ext.create] Singleton ‘" + name + "‘ cannot be instantiated.");
    }
    //</debug>

    return Manager.getInstantiator(args.length)(cls, args);
},

注意最后一句,可以看到调用getInstantiator方法,传递了两个参数,而第一参数,根据上面的代码可知道这就是类名或类自身,这时候,一般通过在return语句上面添加“console.log(cls)”就可知道是那个类出现问题了。

特殊情况是cls为空的时候,就不知道错误出在哪里了。这时候,就需要在return语句前添加debugger语句,在调用该方法时,在浏览器进入调试状态来查了。其实这是一个很烦人的过程,因为类的创建过程都会调用该方法,因而这个需要耐心,一直等到错误出现的时候。而且这个过程可能要重复一次才行,因为错误是在debugger后产生,你需要记录的是这个错误是在什么时候产生,这个很重要。

当知道错误是在什么时候发生了,就可以在debugger进入调试状态的时候,在浏览器的调试工具中,查看栈信息,以确定那个类调用了该方法造成的错误,从而知道错误是产生在那个类。知道了错误在那个类,就好办了,用排除法就可以很容易知道是那个地方出问题了。

以上步骤修改代码后,都要build一次再调试。

由于该错误一时很难还原,栈调试无法以图片显示,在此深表遗憾,如果有需要,可加群391747779进行咨询。

BTY:貌似在最新版的Sencha CMD中已消除了该错误。

时间: 2024-08-24 22:06:03

Ext JS 6应用程序Build后出现“c is not a constructor return new c(a[0])”的处理的相关文章

将Ext JS 5应用程序导入Web项目以及实现本地化

在Ext JS 5,使用了新的脚本和样式加载方式,这对于将应用程序导入到Web项目中产生了点小麻烦.而对于本地化文件的导入,也采用了新的方式,本文将一一解答这些问题. 将Ext JS 5应用程序导入Web项目 在Ext JS 5,会使用bootstrap.js来加载应用程序脚本和样式,而bootstrap.js是根据Bootstrap.json来加载样式文件和脚本的.问题就在这个Bootstrap.json文件上,如果是使用IIS的Web项目,首先会碰到的问题是Web服务器不允许下载JSON文件

将Ext JS 5应用程序导入Web项目中

将Ext JS 5应用程序导入Web项目中 相关资料: http://docs.sencha.com/extjs/5.1/getting_started/welcome_to_extjs.html 效果图: 工程目录结构图:   准备资料: 先到官网上下载ext-5.1.0-gpl.zip然后解压,官网上的我看到buy我就没敢下载了,嘻嘻也可以到csdn上去找http://cdn.sencha.com/ext/gpl/ext-5.1.0-gpl.zip,本来想传上去的,可是说70m太大了不让传,

【翻译】在Ext JS 5应用程序中如何使用路由

原文:How to Use Routing in Your Ext JS 5 Apps 简介 Ext JS 5是一个重要的发布版本,它提供了许多新特性来创建丰富的.企业级的Web应用程序.MVVM和双向数据绑定为开发人员承担了大量的繁重工作.在Ext JS 5种,另一个新特性就是路由,它可以在控制器内轻松的管理历史记录.前进和后退按钮是每个浏览器都会拥有的公共用户接口,现在,使用Ext JS 5在单页面应用程序中处理导航变得相当简单了. Ext JS 5路由 在Ext JS,已经可以使用Ext.

(已解决)sublime text 写程序build后提示can&#39;t find &#39;__main__&#39; module in &#39; &#39;

问题描述: 在sublime text里写最简单的python语句hello world: print  ('hello world') 回车build后出错如下图: 解决办法: 这个问题的原因说起来很幼稚,就是因为没有保存文件.所以只需要保存                       一下文件,再回来build即可. 参考文献:http://stackoverflow.com/questions/14330411/sublime-text2-python-error-message-usr-

将Ext JS 6应用程序导入Web项目

由于Ext JS 6包含了Sencha Touch,因而在应用程序结构有了些改变,Ext JS 5的方法已经不适用于新版本了.经过研究,发现6导入Web项目要比5简单. 下面来说说导入的过程. 使用Sencha Cmd创建应用程序 创建Web项目 在Web项目创建脚本目录,如scripts,直接访问路径为http://域名/scripts 将创建的应用程序目录下的文件和目录全部复制到scripts目录下 将应用程序下的Index.html目录复制到scripts目录的上一层目录,也就是能通过..

在Ext JS 5应用程序中如何使用路由

简介 Ext JS 5是一个重要的发布版本,它提供了许多新特性来创建丰富的.企业级的Web应用程序.MVVM和双向数据绑定为开发人员承担了大量的繁重工作.在Ext JS 5种,另一个新特性就是路由,它可以在控制器内轻松的管理历史记录.前进和后退按钮是每个浏览器都会拥有的公共用户接口,现在,使用Ext JS 5在单页面应用程序中处理导航变得相当简单了. Ext JS 5路由 在Ext JS,已经可以使用Ext.util.Histroy类来处理历史记录的变化,但在Ext JS 5,这个处理变得更容易

【翻译】Ext JS——高效的编码风格指南

原文:ExtJS - Efficient coding style guide 作者:Raja 切勿使用"new"关键字:在Ext JS中,使用"new"关键字来创建一个组件或类的实例是一种错误的做法,因为这没有遵循组件的生命周期.应该使用Ext.create方法来创建对象,例如: 错误: var obj = new Ext.panel.Panel(); 正确: var obj = Ext.create('Ext.panel.Panel'); 初始化直接量:不要直接

eclipse安装EXT JS插件

下载EXT JS插件安装程序 下载网址:http://download.csdn.net/detail/kevingao/9066383 双击spket-1.6.23.jar启动安装程序,按提示操作 选择安装eclipse 插件,并指定eclipse的安装目录,如下图所示: 在MyEclipse中,点击Window-Preferences-Spket-JavaScript Profiles-New,输入名称,点击OK 点击Add  Library,选择ExtJS,点击OK 点击Add  Fold

[020]Sencha Ext JS 6.0使用教程2

本节主要以典型例子介绍如何用Sencha Ext JS6.0进行项目开发 入门阶段总是比较难的,掌握了基本操作步骤,使用方法,架构思维,开发起来还是满顺利,开心的,自己又能掌握一门新技术,又能进步,主要还是学习能力上的提升,慢慢掌握如何从零开始接触一门新东西.新技术.IT方面的技术更新还是满快的,必须跟上时代的步伐,还能不被大浪淹没.好了废话不多说,对于程序员代码还是最有说服力. 1,基本命令: 生产新项目:sencha –sdk {sdk的路径名} generate app {应用名称} {应