I'm looking for a reason this is happening, everything works fine in the regular dev build!
But when I start using a --prod build, it just fails... But I don't know how this would be a difference for the compiler?
Prod build of ionic results in an error:
ionic-app-scripts build --prod
[15:01:41] ionic-app-scripts 1.0.0
[15:01:41] build prod started ...
[15:01:41] clean started ...
[15:01:41] clean finished in 1 ms
[15:01:41] copy started ...
[15:01:41] ngc started ...
[15:01:56] build prod failed: Cannot read property 'kind' of undefined
[15:01:56] ionic-app-script task: "build"
[15:01:56] TypeError: Cannot read property 'kind' of undefined
TypeError: Cannot read property 'kind' of undefined
at _symbolImportLookup (/Users/bramdecuypere/git/max-immo/mobile-app/node_modules/@ionic/app-scripts/dist/aot/app-module-resolver.js:88:92)
at Object.resolveAppNgModuleFromMain (/Users/bramdecuypere/git/max-immo/mobile-app/node_modules/@ionic/app-scripts/dist/aot/app-module-resolver.js:132:18)
at /Users/bramdecuypere/git/max-immo/mobile-app/node_modules/@ionic/app-scripts/dist/aot/aot-compiler.js:92:71
I get an error in this function of the app-scripts library:
function _symbolImportLookup(sourceFile, symbolName, fileCache, host, program) {
// We found the bootstrap variable, now we just need to get where it's imported.
var imports = typescript_utils_1.findNodes(sourceFile, sourceFile, typescript_1.SyntaxKind.ImportDeclaration)
.map(function (node) { return node; });
for (var _i = 0, imports_1 = imports; _i < imports_1.length; _i++) {
var decl = imports_1[_i];
if (!decl.importClause || !decl.moduleSpecifier) {
continue;
}
if (decl.moduleSpecifier.kind !== typescript_1.SyntaxKind.StringLiteral) {
continue;
}
var resolvedModule = typescript_1.resolveModuleName(decl.moduleSpecifier.text, sourceFile.fileName, program.getCompilerOptions(), host);
if (!resolvedModule.resolvedModule || !resolvedModule.resolvedModule.resolvedFileName) {
return null;
}
var module_2 = path_1.normalize(path_1.resolve(resolvedModule.resolvedModule.resolvedFileName));
console.log('decl.importClause.namedBindings.kind', decl.importClause.namedBindings.kind);
console.log('typescript_1.SyntaxKind.NamespaceImport', typescript_1.SyntaxKind.NamespaceImport);
--- decl.importClause.namedBindings.kind: 233
--- typescript_1.SyntaxKind.NamespaceImport: 232
if (decl.importClause.namedBindings.kind === typescript_1.SyntaxKind.NamespaceImport) {
var binding = decl.importClause.namedBindings;
if (binding.name.text === symbolName) {
// This is a default export.
return module_2;
}
}
--- namedBindings is undefined ??? What does this?
else if (decl.importClause.namedBindings.kind === typescript_1.SyntaxKind.NamedImports) {
var binding = decl.importClause.namedBindings;
for (var _a = 0, _b = binding.elements; _a < _b.length; _a++) {
var specifier = _b[_a];
if (specifier.name.text === symbolName) {
// Create the source and recursively lookup the import.
var file = fileCache.get(module_2);
if (file) {
var moduleSourceFile = typescript_utils_1.getTypescriptSourceFile(module_2, file.content, typescript_1.ScriptTarget.Latest, false);
var maybeModule = _recursiveSymbolExportLookup(moduleSourceFile, symbolName, fileCache, host, program);
if (maybeModule) {
return maybeModule;
}
}
}
}
}
}
return null;
}
Which @ionic/app-scripts version are you using?
Cordova CLI: 6.5.0
Ionic Framework Version: 2.0.0-rc.6
Ionic CLI Version: 2.1.13
Ionic App Lib Version: 2.1.7
Ionic App Scripts Version: 1.0.0
ios-deploy version: 1.9.0
ios-sim version: 5.0.13
OS: OS X El Capitan
Node Version: v6.9.4
Xcode version: Xcode 8.2.1 Build version 8C1002
I get a different error when running ionic build ios --prod using Ionic 2.0.0 Final.
[13:13:18] ionic-app-scripts 1.0.0
[13:13:18] build prod started ...
[13:13:18] clean started ...
[13:13:18] clean finished in 12 ms
[13:13:18] copy started ...
[13:13:18] ngc started ...
[13:13:20] ionic-app-script task: "build"
[13:13:20] TypeError: compiler_cli_1.ReflectorHost is not a constructor
TypeError: compiler_cli_1.ReflectorHost is not a constructor
at new AotCompiler (/Users/mraible/dev/myapp/node_modules/@ionic/app-scripts/dist/aot/aot-compiler.js:31:30)
at ngcWorker (/Users/mraible/dev/myapp/node_modules/@ionic/app-scripts/dist/ngc.js:19:20)
at Object.ngc (/Users/mraible/dev/myapp/node_modules/@ionic/app-scripts/dist/ngc.js:9:12)
at buildProject (/Users/mraible/dev/myapp/node_modules/@ionic/app-scripts/dist/build.js:95:51)
at /Users/mraible/dev/myapp/node_modules/@ionic/app-scripts/dist/build.js:43:16
My package.json:
{
"name": "ionic-hello-world",
"author": "Ionic Framework",
"homepage": "http://ionicframework.com/",
"private": true,
"scripts": {
"clean": "ionic-app-scripts clean",
"build": "ionic-app-scripts build",
"ionic:build": "ionic-app-scripts build",
"ionic:serve": "ionic-app-scripts serve"
},
"dependencies": {
"@angular/common": "^2.4.4",
"@angular/compiler": "^2.4.4",
"@angular/compiler-cli": "^2.4.4",
"@angular/core": "^2.4.4",
"@angular/forms": "^2.4.4",
"@angular/http": "^2.4.4",
"@angular/platform-browser": "^2.4.4",
"@angular/platform-browser-dynamic": "^2.4.4",
"@angular/platform-server": "^2.4.4",
"@ionic/storage": "1.1.7",
"angular-stormpath": "^0.1.1",
"ionic-angular": "2.0.0",
"ionic-native": "^2.4.1",
"ionicons": "3.0.0",
"rxjs": "5.0.3",
"sw-toolbox": "3.4.0",
"zone.js": "^0.7.6"
},
"devDependencies": {
"@ionic/app-scripts": "1.0.0",
"typescript": "2.0.10"
},
"cordovaPlugins": [
"cordova-plugin-whitelist",
"cordova-plugin-statusbar",
"cordova-plugin-console",
"cordova-plugin-device",
"cordova-plugin-splashscreen",
"ionic-plugin-keyboard"
],
"cordovaPlatforms": [
"ios",
{
"platform": "ios",
"version": "",
"locator": "ios"
}
],
"description": "MyFirstApp: An Ionic project"
}
@BramDecuypere,
Can you upload a very basic repository to Github so we can recreate the issue?
@mraible,
Ionic requires Angular 2.2.1 right now. There was a breaking change in the ngc AoT build process, so we need to update accordingly.
Thanks,
Dan
@danbucholtz Do you know when you might support 2.3+? Anything I can do to help?
@mraible,
Soon. As for helping, probably not as the build process is complicated. Is something in Angular not working for you? From our perspective, we are probably going to jump straight to Angular 4.
Thanks,
Dan
Angular 2.3+ adds support for overriding components, which makes it easy to customize templates for a library I wrote. With 2.2, developers will have to copy the component and override the template rather than just subclassing and overriding. I was able to get my Ionic app working with 2.3.1 and deployed to my phone (using Xcode), but it looks funny - likely because of the failing build step.
Like @mraible, I also have custom input components that heavily rely on inheritance. At the moment, I'm just using dev builds, since I thought support would come in the past couple of Ionic releases.
@danbucholtz is there any possibility of getting 2.3+ support earlier, even if in a separate branch? Or is the decision to wait until Angular 4 finalized? Angular 4's tentative release is March 2017, and I imagine Ionic's official support for that version will come after, not before.
If Ionic is officially going to wait, then developers using 2.3+ will need to make the decision to remove inheritance features from all of their components, or use the non-AoT dev mode in their releases.
No it's not finalized, that's just what I assumed we'd do. The API for ngc is hopefully the same. I'll investigate.
Thanks,
Dan
Hi @danbucholtz, thanks for the work you are doing! I don't really have the time to create a basic repo. But I fixed the problem. The problem we were having was coming from a config file.
By try catching the module I found it was this config block and figured it out what the problem was.
Everywhere we used a config file like this:
import config from './config';
## config.js
export default {/* config object */};
But I guess NGC should be able to handle this or am I wrong? I guess there is a small piece missing that is handling the unnamed export default. But that's just my $0.02!
Is there a GitHub issue I can subscribe to in order to track Angular 2.3+ support?
@mraible,
There isn't an issue tracking it. I added Angular 4 support today to app-scripts (see ng4 branch), and Ionic (see ng4 branch) just works with Angular 4.
However - and it's a big however - since metadata from ngc must be shipped with Angular libs, we'd have to update the ionic-angular dist to 2.3+, so unless there is a compelling reason to do so sooner, we probably will just go straight to ng4 in 8 weeks.
We are working _very_ closely with Angular on changes we want to see for Angular 4 to improve Ionic, so expect a new version of Ionic to drop hand-in-hand with ng4.
Thanks,
Dan
Thanks for the info @danbucholtz - I really appreciate it. Today I was able to get things working with Angular 2.3.1 by running ionic emulate ios and ionic run ios without the --prod flag. I'm sure this means that files are bigger, but it's "good enough" for blog posts and conference presentations. 馃槈
@mraible,
Why use Angular 2.3.1 if it doesn't fix any issues for you? We would prefer that you use the recommended Ionic and use --prod when presenting so apps are fast.
Thanks,
Dan
The library I'm using in Ionic is stormpath-sdk-angular. It's built with 2.3 and allows me to subclass components to override their templates. This allows end-users to customize HTML easily w/o copying and pasting TypeScript code.
To compare: here's a 2.3 version versus a 2.2 version.
As the author of Stormpath's SDK, I don't want to release a version of the library for Angular 2.2 and make users write more code. Instead, it seems OK to recommend using 2.3 and hoping that Ionic comes out with support for it in the near future.
Another use case: I have created custom components that wrap Ionic inputs. These components share a lot of functionality. For example, all the components have a label input for the field. All the components extend a base class with various shared @Input and @Output decorators.
With Angular 2.3+:
@Component({
selector: 'custom-component',
template: '<h1>{{label}}</h1>'
})
export class CustomComponent extends Component {
}
export class Component {
@Input() label: string;
@ViewChild(TextInput) ionTextInput: TextInput;
}
And the workaround for Ionic with 2.2 support only:
@Component({
selector: 'custom-component',
template: '<h1>{{label}}</h1>',
inputs: ['label']
})
export class CustomComponent extends Component {
@ViewChild(TextInput) ionTextInput: TextInput;
}
export class Component {
@Input() label: string;
@ViewChild(TextInput) ionTextInput: TextInput;
}
In the first scenario, I have access to the label input, and my view child in the parent component. In the second, I have to re-define all inputs, outputs, @HostBinding, and @HostListener in the component metadata. Additionally, I have to re-define all @ViewChild decorators.
It may not seem like much, but some of my base components have 10+ inputs and outputs. There are a ton of bindings and listeners, and each sub component has to redefine an ugly amount of metadata for the component. Additionally, any time I change the base class, I must update the metadata for every class that extends it. The reason I made a base class was to avoid copying and pasting the same functionality in each component.
I think there is definitely value in having component support for inheritance that Angular 2.3 provides.
Okay, I will talk to the team and see what they think. I don't think there is a super compelling reason to do it, but I also don't think there is a super compelling reason not to do it. We'll see what everyone's schedules look like and go from there.
Thanks,
Dan
I'm facing the same error described in these 3 issues.
ionic-app-scripts build "--prod"
[10:43:49] ionic-app-scripts 1.0.0
[10:43:49] build prod started ...
[10:43:49] clean started ...
[10:43:49] clean finished in 6 ms
[10:43:49] copy started ...
[10:43:49] ngc started ...
[10:43:50] ionic-app-script task: "build"
[10:43:50] TypeError: compiler_cli_1.ReflectorHost is not a constructor
TypeError: compiler_cli_1.ReflectorHost is not a constructor
Everything works well without the --prod flag. Are there any updates on these issue?
Most helpful comment
Okay, I will talk to the team and see what they think. I don't think there is a super compelling reason to do it, but I also don't think there is a super compelling reason not to do it. We'll see what everyone's schedules look like and go from there.
Thanks,
Dan