Skip to content
New issue

Have a question about this project? # for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “#”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? # to your account

ERROR in xModule is not an NgModule #1

Open
geneeblack opened this issue Mar 1, 2017 · 5 comments
Open

ERROR in xModule is not an NgModule #1

geneeblack opened this issue Mar 1, 2017 · 5 comments

Comments

@geneeblack
Copy link

geneeblack commented Mar 1, 2017

Attempting to run and getting this error 'ERROR in xModule is not an NgModule'

ERROR in Unexpected value 'xModule in /Users/Gene/Documents/src/ExtAngular/ExtTest/node_modules/angular2-extjs/app/x.module.d.ts' imported by the module 'AppModule in /Users/Gene/Documents/src/ExtAngular/ExtTest/src/app/app.module.ts'

ERROR in ./src/main.ts
Module not found: Error: Can't resolve './$$_gendir/app/app.module.ngfactory' in '/Users/Gene/Documents/src/ExtAngular/ExtTest/src'
@ ./src/main.ts 4:0-74
@ multi ./src/main.ts

not sure if this thread is applicable

angular/angular-cli#4447

@ebgutierrez
Copy link

Had the same issue, still waiting for workarounds.

@ivanpaniagua
Copy link

Same issue while try to run the command: ng serve

@mgusmano
Copy link
Owner

mgusmano commented Jun 3, 2017

that is a known issue with the build and it will work fine if you just make a small change to allow it to build again

@kartzum
Copy link

kartzum commented Jun 20, 2017

There is work around (version 0.0.56).

Unfortunately with angular-cli it does not work. Only for custom webpack configuration. See: angular/angular#15890

tsconfig.json

{
	"compilerOptions": {
		"emitDecoratorMetadata": true,
		"experimentalDecorators": true,
		"module": "es2015",
		"target": "es5",
		"moduleResolution": "node",
		"removeComments": true,
		"sourceMap": false,
		"outDir": "./dist",
		"rootDir": ".",
		"baseUrl": ".",
		"noImplicitAny": false,
		"declaration": true,
		"lib": [
			"es2015",
			"dom"
		]
	},
	"files": [
		"./src/index.ts"
	],
	"angularCompilerOptions": {
		"annotateForClosureCompiler": true,
		"strictMetadataEmit": true,
		"flatModuleOutFile": "angular2-extjs.js",
		"flatModuleId": "angular2-extjs"
	}
}

package.json

{
  "name": "angular2-extjs",
  "version": "0.0.56",
  "description": "Ext JS Bridge for Angular2",
  "repository": {
    "type": "git",
    "url": "https://github.com/mgusmano/angular2-extjs.git"
  },
  "main": "./dist/src/index.js",
  "typings": "./dist/src/index.d.ts",
  "module": "./dist/src/angular2-extjs.bundle.js",
  "scripts": {
    "it1": "rm -r dist",
    "it2": "rm -r src",
    "it3": "mkdir src/ && mkdir src/app/",
    "it4": "node all.js",
    "it5": "tsc",
    "it6": "cp -r demo dist/demo/",
    "it7": "npm version patch",
    "it8": "cp README.md dist/ && cp package.json dist/",
    "xxit7": "npm publish",
    "build": "rm -rf lib && tsc",
    "typings": "typings",
    "build:new:clear": "rimraf dist",
    "build:new:build": "npm run it4",
    "build:new:compile": "ngc",
    "build:new:pack": "rollup ./dist/src/angular2-extjs.js -o ./dist/src/angular2-extjs.bundle.js",
    "build:new": "npm run build:new:clear && npm run build:new:build && npm run build:new:compile && npm run build:new:pack"
  },
  "author": "Sencha",
  "license": "MIT",
  "dependencies": {
    "@angular/core": "4.2.1",
    "@angular/common": "4.2.1",
    "@angular/platform-browser": "4.2.1",
    "@angular/compiler-cli": "4.2.1",
    "@angular/compiler": "4.2.1",
    "rxjs": "5.2.0",
    "zone.js": "0.8.4"
  },
  "devDependencies": {
    "typescript": "2.2.1",
    "uglifyjs": "2.4.10",
    "umd": "3.0.1",
    "retyped-extjs-tsd-ambient": "4.2.1-0",
    "rimraf": "2.5.1",
    "rollup": "0.41.6"
  }
}

all.js

var fs = require('fs');
var data = require('./modern-all-classes-flatten.json');
launch(data);

function launch(data) {
    var items = data.global.items;
    var commaOrBlank = "";
    var prefix = "x";
    var dist = "app/";
    var root = "src/";
    var folder = root + dist;
    var tab = "\t";
    var newLine = "\n";
    var imports = "";
    var exports = "";
    var declarations = "";
    var allClasses = "";
    var o = {};
    for (i = 0; i < items.length; i++) {
        o = items[i];
//		console.log(o.name);
        // if (o.alias != undefined) {
        // 	console.log(o.alias);
        // }
        if (o.alias != undefined &&
            o.alias.substring(0, 6) == 'widget' &&
            o.alias.substring(7).indexOf('.') == -1 &&
//				o.alias.substring(7).indexOf('-') == -1 && 
//				o.alias.indexOf('calendar-') == -1 && 
            o.alias.indexOf('actionsheet') == -1 &&
            o.alias.indexOf('audio') == -1 &&
            o.alias.indexOf('axis') == -1 &&
            o.alias.indexOf('carouselindicator') == -1 &&
            o.alias.substring(7).indexOf('item') == -1 &&
            o.alias.substring(7).indexOf('cell') == -1 &&
            o.alias.substring(7).indexOf('column') == -1 &&
            o.alias.substring(7).indexOf('row') == -1 &&
            o.alias.substring(7).indexOf('sparkline') == -1 &&
            o.alias.substring(7).indexOf('pivotconfig') == -1 &&
            o.alias.indexOf(',') == -1)
        {
            if (o.alias.indexOf('calendar-day') != -1) {
//				debugger;
            }

            o.xtype = o.alias.substring(o.alias.indexOf(".") + 1);

            if (o.items != undefined) {
                var sINPUTS = "";
                var sOUTPUTS = "";
                var sOUTPUTNAMES = "";

                var configsArray = o.items.filter(function(obj) {return obj.$type == 'configs';});
                if (configsArray.length == 1) {
                    configsArray[0].items.forEach(function (config, index, array) {
                        sINPUTS = sINPUTS + tab + tab + "'" + config.name + "'" + "," + newLine;
                    });
                    sINPUTS = sINPUTS + tab + tab + "'" + "platformConfig"+ "'" + "," + newLine;
                    sINPUTS = sINPUTS + tab + tab + "'" + "responsiveConfig"+ "'" + "," + newLine;
                    sINPUTS = sINPUTS + tab + tab + "'" + "fitToParent"+ "'" + "," + newLine;
                    sINPUTS = sINPUTS + tab + tab + "'" + "config" + "'" + "" + newLine;
                }

                var eventsArray = o.items.filter(function(obj) {return obj.$type == 'events';});
                if (eventsArray.length == 1) {
                    eventsArray[0].items.forEach(function (event, index, array) {
                        if (event.name == undefined) {
                            var s = event.inheritdoc;
                            event.name = s.substr(s.indexOf('#') + 1);
                        }
                        sOUTPUTS = sOUTPUTS + tab + tab + "{name:'" + event.name + "',parameters:'";
                        sOUTPUTNAMES = sOUTPUTNAMES + tab + tab + "'" + event.name + "'" + "," + newLine;
                        if (event.items != undefined) {
                            event.items.forEach(function (parameter, index, array) {
                                if (index == array.length-1){commaOrBlank= ''} else {commaOrBlank= ','};
                                if (parameter.name == 'this'){ parameter.name = o.xtype };
                                sOUTPUTS = sOUTPUTS + "" + parameter.name + commaOrBlank;
                            });
                        }
                        sOUTPUTS = sOUTPUTS + "'}" + "," + newLine;
                    })
                }
                sOUTPUTS = sOUTPUTS + tab + tab + "{name:'" + "ready" + "',parameters:''}" + "" + newLine;
                sOUTPUTNAMES = sOUTPUTNAMES + tab + tab + "'" + "ready" + "'" + "" + newLine;
                var className =  o.xtype.replace(/-/g, "_")
                allClasses = allClasses + tab + "'" + o.name + "'," + tab + "// xtype='" + className + "'" + newLine;
                fs.writeFile(folder + prefix + '.' + className + '.ts', doClass(o.xtype, sINPUTS, sOUTPUTS, sOUTPUTNAMES, prefix, o.name, className),
                    function(err) {if(err) { return console.log(err); }
                    });

                imports = imports + "import { " + prefix + className + " } from './" + prefix + "." + className + "';" + newLine;
                exports = exports + tab + tab + prefix + className + "," + newLine;
                declarations = declarations + tab + tab + prefix + className + "," + newLine;
            }
        }
    }

    fs.writeFile(folder + prefix + '.' + 'base' + '.ts', doExtBase(prefix),
        function(err) {if(err){return console.log(err);}
        });
    fs.writeFile(folder + prefix + '.' + 'class' + '.ts', doExtClass(prefix),
        function(err) {if(err){return console.log(err);}
        });
    fs.writeFile(folder + prefix + '.ts', doExt(prefix),
        function(err) {if(err){return console.log(err);}
        });
    fs.writeFile(folder + prefix + '.' + 'ngcomponent' + '.ts', doExtNgComponent(prefix),
        function(err) {if(err){return console.log(err);}
        });
    fs.writeFile('demo/misc/' + 'app' + '.js', doAppJS(allClasses),
        function(err) {if(err){return console.log(err);}
        });
    fs.writeFile(root + 'index' + '.ts', doIndex(dist, prefix),
        function(err) {if(err){return console.log(err);}
        });
    exports = exports.substring(0, exports.length - 2); exports = exports + newLine;
    declarations = declarations.substring(0, declarations.length - 2); declarations = declarations + newLine;
    fs.writeFile(folder + prefix + '.' + 'module' + '.ts', doModule(imports, exports, declarations, prefix),
        function(err) {if(err) { return console.log(err); }
        });
}

function doClass(xtype, sINPUTS, sOUTPUTS, sOUTPUTNAMES, prefix, name, className) {
    return `import {Component,ViewChild,ElementRef,ComponentFactoryResolver,ViewContainerRef,forwardRef,ContentChildren,QueryList} from '@angular/core';
import { ${prefix}base } from './${prefix}.base';
// Ext Class - ${name}
export class ${prefix}${className}MetaData {
	public static XTYPE: string = '${xtype}';
	public static INPUTNAMES: string[] = [
${sINPUTS}];
	public static OUTPUTS: any[] = [
${sOUTPUTS}];
	public static OUTPUTNAMES: string[] = [
${sOUTPUTNAMES}];
}
@Component({
  selector: '${prefix}-' + ${prefix}${className}MetaData.XTYPE,
	inputs: ${prefix}${className}MetaData.INPUTNAMES,
	outputs: ${prefix}${className}MetaData.OUTPUTNAMES,
	providers: [{provide: ${prefix}base, useExisting: forwardRef(() => ${prefix}${className})}],
	template: '<template #dynamic></template>'
})
export class ${prefix}${className} extends ${prefix}base {
	constructor(eRef:ElementRef,resolver:ComponentFactoryResolver,vcRef:ViewContainerRef) {
		super(eRef,resolver,vcRef,${prefix}${className}MetaData);
	}
	//@ContentChildren(${prefix}base,{read:ViewContainerRef}) extbaseRef:QueryList<ViewContainerRef>;
	@ContentChildren(${prefix}base,{read: ${prefix}base}) extbaseRef: QueryList<${prefix}base>;
	@ViewChild('dynamic',{read:ViewContainerRef}) dynamicRef:ViewContainerRef;
	ngAfterContentInit() {this.AfterContentInit(this.extbaseRef);}
	ngOnInit() {this.OnInit(this.dynamicRef,${prefix}${className}MetaData);}
}
`;
};

function doAppJS(allClasses) {
    return `Ext.require([
	'plugin.responsive',
	'widget.widgetcell',
	'widget.sparklineline',
	'plugin.grideditable',
	'plugin.gridviewoptions',
	'plugin.pagingtoolbar',
	'plugin.summaryrow',
	'plugin.columnresizing',
	'plugin.pivotconfigurator',
	'axis.numeric',
	'axis.category',
	'Ext.chart.series.Series',
	'series.bar',
	'series.pie',
${allClasses}]);
`
}

function doIndex(dist, prefix) {
    return `export * from './${dist}${prefix}.module'
export * from './${dist}${prefix}.class'
`
}


function doModule(imports, exports, declarations, prefix) {
    return `import { NgModule } from "@angular/core";
import { ${prefix} } from './${prefix}';
import { ${prefix}ngcomponent } from './${prefix}.ngcomponent';
import { ${prefix}class } from './${prefix}.class';
${imports}
@NgModule({
	exports: [
		${prefix},
		${prefix}ngcomponent,
${exports} ],
	declarations: [
		${prefix},
		${prefix}ngcomponent,
${declarations} ]
})
export class ${prefix}Module { }
	`
}

function doExtBase(prefix) {
    return `/// <reference path="../../node_modules/retyped-extjs-tsd-ambient/ExtJS.d.ts" />
import {AfterContentInit,AfterViewInit,Attribute,Component,ComponentFactory,ComponentRef,ComponentFactoryResolver,ContentChildren,
	ElementRef,EventEmitter,OnInit,QueryList,Type,ViewChild,ViewContainerRef
} from '@angular/core';

export class ${prefix}base{
	public extjsObject: any;
	private rootElement: any;
	private listeners = {};
	private xtype: string;
	private inputs: any;
	//private nofit: any;

	constructor(
		private myElement: any, 
		private componentFactoryResolver: ComponentFactoryResolver, 
		private viewContainerRef: ViewContainerRef, 
		private metaData: any
		) {
		this.xtype = metaData.XTYPE;
		this.inputs = metaData.INPUTNAMES;
		this.rootElement = myElement.nativeElement;
		this['ready'] = new EventEmitter();
		metaData.OUTPUTS.forEach( (event: any, n: any) => {
			(<any>this)[event.name] = new EventEmitter();
		});
	}

	AfterContentInit(ExtJSBaseRef) {
		//var extJSRootComponentRef : ViewContainerRef = ExtJSBaseRef.first;
		var extJSRootComponentRef : xbase = ExtJSBaseRef.first;
		//var firstExtJS = extJSRootComponentRef['_element'].component.extjsObject;
		var firstExtJS = extJSRootComponentRef.extjsObject;
		firstExtJS.setRenderTo(this.myElement.nativeElement);
		var ExtJSComponentRefArray: any = ExtJSBaseRef.toArray();
		var arrayLength = ExtJSComponentRefArray.length;
		for (var i = 1; i < arrayLength; i++) {
			//var obj = ExtJSComponentRefArray[i]['_element'].component.extjsObject;
			var obj = ExtJSComponentRefArray[i].extjsObject;
			if (obj.config.docked != null) {
				firstExtJS.insert(0, obj);
			}
			else {
				firstExtJS.add(obj);
			}
		}
	}

	OnInit(dynamicTarget,metadata?) {
		let me: any = this;
		let o: any = {};
		o.listeners = {};
		var eventtasks = this.myElement.nativeElement.__zone_symbol__eventTasks;
		if (eventtasks != undefined) {
			eventtasks.forEach(function (eventtask, index, array) {
				var eventIndex = metadata.OUTPUTNAMES.indexOf(eventtask.data.eventName);
				if (eventIndex != -1) {
					var eventname = eventtask.data.eventName;
					var eventparameters = metadata.OUTPUTS[eventIndex].parameters
					o.listeners[eventname] = function() {
							let parameters: any = eventparameters;
							let parms = parameters.split(',');
							let args = Array.prototype.slice.call(arguments);
							let o: any = {};
							for (let i = 0, j = parms.length; i < j; i++ ) {
									o[parms[i]] = args[i];
							}
							me[eventname].next(o);
					};
				}
			});
		}

		o.xtype = me.xtype;
		if (me.xtype != '') { o.xtype = me.xtype; }
		for (var i = 0; i < me.metaData.INPUTNAMES.length; i++) { 
			var prop = me.metaData.INPUTNAMES[i];
			//need to handle listeners coming in here
			if (me[prop] != undefined && 
					prop != 'listeners' && 
					prop != 'config' && 
					prop != 'fitToParent') { 
				o[prop] = me[prop]; 
			};
		}
		if ('true' == me.fitToParent) {
			o.top=0, 
			o.left=0, 
			o.width='100%', 
			o.height='100%'
		}
		if (me.config !== {} ) {
			Ext.apply(o, me.config);
		};
		me.extjsObject = Ext.create(o);
		me.ext = me.extjsObject;
		me.x = me.extjsObject;

		var componentFactory: ComponentFactory<any>;
		var type: Type<any>;

		if (me.component != undefined) {
			type = me.component;
			componentFactory = me.componentFactoryResolver.resolveComponentFactory(type);
			me.componentRef = dynamicTarget.createComponent(componentFactory);
			//me.componentRef.instance['buttontext'] = 'testing';
			var node = me.extjsObject.innerElement.dom;
			node.appendChild(me.componentRef['_hostElement'].nativeElement);
		}
		if (me.parent != undefined) {
			me.parent.insert(0, me.extjsObject);
		}
		me.ready.next(me);
	}
}
`
}


function doExt(prefix) {
    return `import { Component, OnInit, ViewChild, ElementRef, Attribute, ComponentFactory, ComponentFactoryResolver, ViewContainerRef, forwardRef, ContentChildren, QueryList, Type } from '@angular/core';
import { ${prefix}base } from './${prefix}.base';
export class extMetaData {
	public static XTYPE: string = '';
	public static INPUTNAMES: string[] = ['xtype','fittoparent'];
	public static OUTPUTS: any[] = [ { name: 'click', parameters: 'control,record,eOpts' }];
	public static OUTPUTNAMES: string[] = ['click'];
}
@Component({
  selector: '${prefix}' + extMetaData.XTYPE,
	inputs: extMetaData.INPUTNAMES.concat('config'),
	outputs: extMetaData.OUTPUTNAMES.concat('ready'),
	providers: [{provide: ${prefix}base, useExisting: forwardRef(() => ${prefix})}],
	template: '<template #dynamic></template>'
})
export class ${prefix} extends ${prefix}base implements OnInit {
	constructor(myElement: ElementRef, componentFactoryResolver: ComponentFactoryResolver, viewContainerRef: ViewContainerRef) {
		super(myElement, componentFactoryResolver, viewContainerRef, extMetaData);
	}
	//@ContentChildren(${prefix}base,{read: ViewContainerRef}) extbaseRef: QueryList<ViewContainerRef>;
	@ContentChildren(${prefix}base,{read: ${prefix}base}) extbaseRef: QueryList<${prefix}base>;
	@ViewChild('dynamic',{read: ViewContainerRef}) dynamicRef: ViewContainerRef;
	ngAfterContentInit() { this.AfterContentInit(this.extbaseRef); }
	ngOnInit() { this.OnInit(this.dynamicRef); }
}
`
}

function doExtNgComponent(prefix) {
    return `import {Component,ViewChild,ElementRef,ComponentFactoryResolver,ViewContainerRef,forwardRef,ContentChildren,QueryList} from '@angular/core';
import { ${prefix}base } from './${prefix}.base';
export class ExtNgComponentMetaData {
	public static XTYPE: string = 'container';
	public static INPUTNAMES: string[] = ['selector','component','selectorParams'];
	public static OUTPUTS: any[] = [];
	public static OUTPUTNAMES: string[] = [];
}
@Component({
  selector: '${prefix}-ngcomponent',
	inputs: ExtNgComponentMetaData.INPUTNAMES.concat('config'),
	outputs: ExtNgComponentMetaData.OUTPUTNAMES.concat('ready'),
	providers: [{provide: ${prefix}base, useExisting: forwardRef(() => ${prefix}ngcomponent)}],
	template: '<template #dynamic></template>'
})
export class ${prefix}ngcomponent  extends ${prefix}base {
	//@ContentChildren(${prefix}base,{read:ViewContainerRef}) extbaseRef: QueryList<ViewContainerRef>;
	@ContentChildren(${prefix}base,{read: ${prefix}base}) extbaseRef: QueryList<${prefix}base>;
	@ViewChild('dynamic',{read:ViewContainerRef}) dynamicRef: ViewContainerRef;
	constructor(myElement: ElementRef, componentFactoryResolver: ComponentFactoryResolver, viewContainerRef: ViewContainerRef) {
		super(myElement, componentFactoryResolver, viewContainerRef, ExtNgComponentMetaData);
	}
	ngAfterContentInit() { this.AfterContentInit(this.extbaseRef); }
	ngOnInit() { this.OnInit(this.dynamicRef); }
}
`
}

function doExtClass(prefix) {
    return `export class ${prefix}class {
	public className: any;
	public extend: any;
	public defineConfig: any;
	public createConfig: any;
	public extjsObject;
	public ext;
	public x;

	constructor (className: any, extend: string, defineConfig: any, createConfig: any) {
		if (!Ext.ClassManager.isCreated(className)) {
			Ext.apply(defineConfig, { extend: extend });
			Ext.define(className, defineConfig);
		}
		this.className = className;
		this.extend = extend;
		this.defineConfig = defineConfig;
		this.createConfig = createConfig;
		this.extjsObject = Ext.create(className, createConfig);
		this.ext = this.extjsObject;
		this.x = this.extjsObject;
	}
}
`
}

Steps.

  • Change files: tsconfig.json, package.json and all.js
  • npm i
  • npm run build:new
  • Optional: npm link

After.
In application (Optional: npm link angular2-extjs).

Prepare build and ext.

vendors.ts

import "script-loader!./ext/Boot.js";
import "script-loader!./build/testing/Theme/app.js";

import "./ext/misc.css";
import "./build/testing/Theme/resources/Theme-all.css";

ng-main.ts

import {platformBrowserDynamic} from "@angular/platform-browser-dynamic";
import {NgMainModule} from "./ng-main.module";

declare let Ext: any;

let isReady = false;

setInterval(() => {
    if (Ext && Ext.isReady && !this.isReady) {
        this.isReady = true;
        platformBrowserDynamic().bootstrapModule(NgMainModule);
    }
}, 10);

ng-main.component.ts

import {ChangeDetectionStrategy, Component, OnInit} from "@angular/core";

@Component({
    changeDetection: ChangeDetectionStrategy.OnPush,
    selector: "ng-main-component",
    template: `
        <div style="margin: 0 auto; width: 700px; padding: 10px; ">
            <h1>Ext JS Bridge for Angular2</h1>
            <x-grid
                    [columns]="gridcolumns"
                    [store]="gridstore"
                    [config]="gridconfig"
                    (select)="onGridSelect($event)"
            ></x-grid>
        </div>
    `
})
export class NgMainComponent implements OnInit {
    gridcolumns: Array<any> = [
        {text: 'Name', width: 100, dataIndex: 'name'},
        {text: 'Email Address', flex: 1, dataIndex: 'email'},
        {text: 'Phone Number', width: 150, dataIndex: 'phone'}
    ];
    gridstore: any = {
        fields: ['name', 'email', 'phone'],
        data: [
            {name: 'Lisa', email: 'lisa@simpsons.com', phone: '555-111-1224'},
            {name: 'Bart', email: 'bart@simpsons.com', phone: '555-222-1234'},
            {name: 'Homer', email: 'homer@simpsons.com', phone: '555-222-1244'},
            {name: 'Marge', email: 'marge@simpsons.com', phone: '555-222-1254'}
        ]
    };
    gridconfig: Object = {width: '600px', height: '200px', scrollable: 'false'};

    constructor() {
    }

    ngOnInit(): void {
    }

    private onGridSelect(event:any) {
        alert(event);
    }
}

@ezavgorodniy
Copy link

@kartzum, thanks for the workaround, I'm also experiencing this issue but when I tried your workaround I received:
image
image

Have you seen something like this before?

# for free to join this conversation on GitHub. Already have an account? # to comment
Labels
None yet
Projects
None yet
Development

No branches or pull requests

6 participants