alxhub / io17

106 stars 21 forks source link

ngu-app-shell --module fails #8

Open GregOnNet opened 7 years ago

GregOnNet commented 7 years ago

Hi,

first thanks for providing these tools. They really help me to be more productive generating PWA-Applications.

Problem

I experience an error (see section Error) when I run ./node_modules/.bin/ngu-app-shell --module src/app/app.module.ts

Research

The error claims that the path to the files containing templates and styles cannot be resolved. ng-app-shell expects all .html and .sass files in the root directory of the app. I put a console.log inside the FileLoader located in ng.js.

var FileLoader = (function () {
    function FileLoader() {
    }
    FileLoader.prototype.get = function (url) {
      console.log('!!!!!!!!!!!!!!!!!!!!!!!!!!!!!', url)
        return new Promise(function (resolve, reject) {
            resolve(fs.readFileSync(url).toString());
        });
    };
    return FileLoader;
}());

It turns out that only the filenames of the template and style files are passed to the FileLoader. Maybe the caller for FileLoader.get has to pass the right url to the needed files

Workaround

To get ./node_modules/.bin/ngu-app-shell --module src/app/app.module.ts to run I temporarly copied the templates and the styles to the root folder of the app

$ cp src/**/*.{html, sass} .

After that the precompile runs without any problems.

Error

'<path>\ng-pwa\book-grid.component.html' ; Zone: <root> ; Task: Promise.then ; Value: { Error: ENOENT: no such file or directory, open '<path>\ng-pwa\book-grid.component.html'
    at Object.fs.openSync (fs.js:584:18)
    at Object.fs.readFileSync (fs.js:491:33)
    at <path>\ng-pwa\node_modules\ng-pwa-tools\lib\common\ng.js:25:24
    at new ZoneAwarePromise (<path>\ng-pwa\node_modules\zone.js\dist\zone-node.js:821:29)
    at FileLoader.get (<path>\ng-pwa\node_modules\ng-pwa-tools\lib\common\ng.js:24:16)
    at DirectiveNormalizer._fetch (<path>\ng-pwa\node_modules\@angular\compiler\bundles\compiler.umd.js:13297:45)
    at DirectiveNormalizer.normalizeTemplateAsync (<path>\ng-pwa\node_modules\@angular\compiler\bundles\compiler.umd.js:13352:21)
    at DirectiveNormalizer.normalizeTemplate (<path>\ng-pwa\node_modules\@angular\compiler\@angular\compiler.es5.js:13319:39)
    at CompileMetadataResolver._loadDirectiveMetadata (<path>\ng-pwa\node_modules\@angular\compiler\@angular\compiler.es5.js:14250:44)
    at <path>\ng-pwa\node_modules\@angular\compiler\@angular\compiler.es5.js:14446:54
  errno: -4058,
  code: 'ENOENT',
  syscall: 'open',
  path: 'C:\\workbench\\trainings\\angular\\ng-pwa\\book-grid.component.html',
  __zone_symbol__currentTask:
   ZoneTask {
     _zone:
      Zone {
        _properties: {},
        _parent: null,
        _name: '<root>',
        _zoneDelegate: [Object] },
     runCount: 0,
     _zoneDelegates: null,
     _state: 'notScheduled',
     type: 'microTask',
     source: 'Promise.then',
     data: undefined,
     scheduleFn: undefined,
     cancelFn: null,
     callback: [Function],
     invoke: [Function] } } Error: ENOENT: no such file or directory, open '<path>\ng-pwa\book-grid.component.html'
    at Object.fs.openSync (fs.js:584:18)
    at Object.fs.readFileSync (fs.js:491:33)
    at <path>\ng-pwa\node_modules\ng-pwa-tools\lib\common\ng.js:25:24
    at new ZoneAwarePromise (<path>\ng-pwa\node_modules\zone.js\dist\zone-node.js:821:29)
    at FileLoader.get (<path>\ng-pwa\node_modules\ng-pwa-tools\lib\common\ng.js:24:16)
    at DirectiveNormalizer._fetch (<path>\ng-pwa\node_modules\@angular\compiler\bundles\compiler.umd.js:13297:45)
    at DirectiveNormalizer.normalizeTemplateAsync (<path>\ng-pwa\node_modules\@angular\compiler\bundles\compiler.umd.js:13352:21)
    at DirectiveNormalizer.normalizeTemplate (<path>\ng-pwa\node_modules\@angular\compiler\@angular\compiler.es5.js:13319:39)
    at CompileMetadataResolver._loadDirectiveMetadata (<path>\ng-pwa\node_modules\@angular\compiler\@angular\compiler.es5.js:14250:44)
    at <path>\ng-pwa\node_modules\@angular\compiler\@angular\compiler.es5.js:14446:54
{ Error: Uncaught (in promise): Error: ENOENT: no such file or directory, open '<path>\ng-pwa\book-grid.component.html'

Environment

alxhub commented 7 years ago

Hi @GregOnNet, thanks for the issue report.

I don't think this will work anyway - ngu-app-shell does not support .sass input (because Angular does not). If your SASS code happens to be valid CSS it might work on accident, but the moment you go beyond what the Angular CSS parser supports you will run into trouble.

In the CLI this is not a problem as the ResourceLoader it provides to Angular is capable of running Webpack child compilations for resources, which passes them through the appropriate loaders. ngu-app-shell can't do that, it's designed to work with vanilla Angular apps and does not support all of the CLI's use cases.

alfredoperez commented 7 years ago

I see the same error. Where it is not able to find the .html and .scss paths.

I am also using windows and saw that is trying to find the files on root folder instead of where they are located.

Eg instead of trying to open the file at app/{page}/page.component.html it is trying to open it at ./page.component.html

I get the error running the ngu-app-shell and ngu-sw-manifest. Using windows as well.

alxhub commented 7 years ago

@alfredoperez make sure all of your components have moduleId: module.id in their metadata. All Angular CLI components should already follow this.

I will do some testing on Windows to make sure the ng-pwa-tools work well there. I believe there are cases where they make assumptions about path separators and other annoying little platform-specific things.

markgoho commented 7 years ago

@alxhub the Angular CLI hasn't included moduleId: module.id in Component decorators since mid-2016 when the CLI switched over to Webpack

Splaktar commented 7 years ago

I'm seeing these kinds of errors on OS X. I also don't have moduleId in my component's metadata since they are generated by the CLI which doesn't add that anymore.

Even after doing rm -rf node_modules/ and reinstalling everything with the latest npm (v4.6.1), I'm still seeing:

ngu-sw-manifest --dist dist --in ngsw-manifest.json --module src/app/app.module.ts --out dist/ngsw-manifest.json

Unhandled Promise rejection: ENOENT: no such file or directory, open 'page-not-found.component.html' ; Zone: <root> ; Task: Promise.then ; Value: { Error: ENOENT: no such file or directory, open 'page-not-found.component.html'
    at Error (native)
    at Object.fs.openSync (fs.js:641:18)
    at Object.fs.readFileSync (fs.js:509:33)
    at /Users/splaktar/Git/tf/webapp/node_modules/ng-pwa-tools/lib/common/ng.js:24:24
    at new ZoneAwarePromise (/Users/splaktar/Git/tf/webapp/node_modules/zone.js/dist/zone-node.js:776:29)
    at FileLoader.get (/Users/splaktar/Git/tf/webapp/node_modules/ng-pwa-tools/lib/common/ng.js:23:16)
    at DirectiveNormalizer._fetch (/Users/splaktar/Git/tf/webapp/node_modules/@angular/compiler/bundles/compiler.umd.js:13297:45)
    at DirectiveNormalizer.normalizeTemplateAsync (/Users/splaktar/Git/tf/webapp/node_modules/@angular/compiler/bundles/compiler.umd.js:13352:21)
    at DirectiveNormalizer.normalizeTemplate (/Users/splaktar/Git/tf/webapp/node_modules/@angular/compiler/@angular/compiler.es5.js:13319:39)
    at CompileMetadataResolver._loadDirectiveMetadata (/Users/splaktar/Git/tf/webapp/node_modules/@angular/compiler/@angular/compiler.es5.js:14250:44)
    at /Users/splaktar/Git/tf/webapp/node_modules/@angular/compiler/@angular/compiler.es5.js:14446:54
    at Array.forEach (native)
    at CompileMetadataResolver.loadNgModuleDirectiveAndPipeMetadata (/Users/splaktar/Git/tf/webapp/node_modules/@angular/compiler/@angular/compiler.es5.js:14445:16)
    at /Users/splaktar/Git/tf/webapp/node_modules/@angular/compiler/bundles/compiler.umd.js:25646:58
    at Array.forEach (native)
  errno: -2,
  code: 'ENOENT',
  syscall: 'open',
  path: 'page-not-found.component.html',
  __zone_symbol__currentTask: 
   ZoneTask {
     _zone: 
      Zone {
        _properties: {},
        _parent: null,
        _name: '<root>',
        _zoneDelegate: [Object] },
     runCount: 0,
     _zoneDelegates: null,
     _state: 'notScheduled',
     type: 'microTask',
     source: 'Promise.then',
     data: undefined,
     scheduleFn: undefined,
     cancelFn: null,
     callback: [Function],
     invoke: [Function] } } Error: ENOENT: no such file or directory, open 'page-not-found.component.html'
    at Error (native)
    at Object.fs.openSync (fs.js:641:18)
    at Object.fs.readFileSync (fs.js:509:33)
Splaktar commented 7 years ago

I went through my app and added moduleId: module.id to all my components. That fixed the no such file errors for my templates, but now I'm getting the SCSS files as not found:

This file is actually at: /Users/splaktar/Git/tf/webapp/src/app/shared/global-styles/imports/_variables.scss:

Unhandled Promise rejection: ENOENT: no such file or directory, open '/Users/splaktar/Git/tf/webapp/src/app/shared/global-styles/imports/variables' ; Zone: <root> ; Task: Promise.then ; Value: { Error: ENOENT: no such file or directory, open '/Users/splaktar/Git/tf/webapp/src/app/shared/global-styles/imports/variables'
    at Error (native)
    at Object.fs.openSync (fs.js:641:18)
    at Object.fs.readFileSync (fs.js:509:33)
    at /Users/splaktar/Git/tf/webapp/node_modules/ng-pwa-tools/lib/common/ng.js:24:24
    at new ZoneAwarePromise (/Users/splaktar/Git/tf/webapp/node_modules/zone.js/dist/zone-node.js:776:29)
    at FileLoader.get (/Users/splaktar/Git/tf/webapp/node_modules/ng-pwa-tools/lib/common/ng.js:23:16)
    at DirectiveNormalizer._fetch (/Users/splaktar/Git/tf/webapp/node_modules/@angular/compiler/bundles/compiler.umd.js:13297:45)
    at /Users/splaktar/Git/tf/webapp/node_modules/@angular/compiler/@angular/compiler.es5.js:13421:52
    at Array.map (native)
    at DirectiveNormalizer._loadMissingExternalStylesheets (/Users/splaktar/Git/tf/webapp/node_modules/@angular/compiler/@angular/compiler.es5.js:13421:14)
    at /Users/splaktar/Git/tf/webapp/node_modules/@angular/compiler/bundles/compiler.umd.js:13429:26
    at ZoneDelegate.invoke (/Users/splaktar/Git/tf/webapp/node_modules/zone.js/dist/zone-node.js:365:26)
    at Zone.run (/Users/splaktar/Git/tf/webapp/node_modules/zone.js/dist/zone-node.js:125:43)
    at /Users/splaktar/Git/tf/webapp/node_modules/zone.js/dist/zone-node.js:760:57
    at ZoneDelegate.invokeTask (/Users/splaktar/Git/tf/webapp/node_modules/zone.js/dist/zone-node.js:398:31)
  errno: -2,
  code: 'ENOENT',
  syscall: 'open',
  path: '/Users/splaktar/Git/tf/webapp/src/app/shared/global-styles/imports/variables',
  __zone_symbol__currentTask: 
   ZoneTask {
     _zone: 
      Zone {
        _properties: {},
        _parent: null,
        _name: '<root>',
        _zoneDelegate: [Object] },
     runCount: 0,
     _zoneDelegates: null,
     _state: 'notScheduled',
     type: 'microTask',
     source: 'Promise.then',
     data: undefined,
     scheduleFn: undefined,
     cancelFn: null,
     callback: [Function],
     invoke: [Function] } } Error: ENOENT: no such file or directory, open '/Users/splaktar/Git/tf/webapp/src/app/shared/global-styles/imports/variables'
    at Error (native)
    at Object.fs.openSync (fs.js:641:18)
    at Object.fs.readFileSync (fs.js:509:33)
    at /Users/splaktar/Git/tf/webapp/node_modules/ng-pwa-tools/lib/common/ng.js:24:24
alxhub commented 7 years ago

@Splaktar as I mentioned before, SCSS is not supported by Angular as a whole - being able to reference it directly is Angular CLI specific functionality.

cars10 commented 7 years ago

So what is the proposed solution? Do i have to decide if i want to use a serviceWorker or if i want to use sass?!

gund commented 7 years ago

I'm having different issues, specifically a lot of errors regarding usage of RxJs operators like:

Property 'map' does not exist on type 'Observable'

I have one .ts file where I importing all of the operators and importing that file in the module so theoretically it should work but it's not...

I guess it is because those file transpiled via ts-node separately from each other so if I import operators in the entry point those imports are not visible in other parts...

Is there any workaround/solution for it?

Thanks

alxhub commented 7 years ago

@cars10 in that case, you can not pass --module to ngu-sw-manifest, and instead write your routing configuration manually.

The fundamental problem here is that all of the ngu- tools require a Universal-compatible application, which not every CLI app is. In particular, Angular does not natively understand SCSS, support for it is exclusive to the @ngtools/webpack functionality used by the CLI. We do have a contributor working on Universal build support in the CLI, which will make this much easier for apps that rely on such features.

alfredoperez commented 7 years ago

@gund check your imports. see some of the imporst i used:

import 'rxjs/add/operator/debounceTime';
import 'rxjs/add/operator/distinctUntilChanged';
import 'rxjs/add/operator/map';
import 'rxjs/add/operator/do';
import 'rxjs/add/operator/mergeMap';
import 'rxjs/Observable';
gund commented 7 years ago

@alfredoperez yes I do have a whole lot of them located in one file and I'm importing that file right in the entry point (my module). But it still complains about them in other files...

I'm thinking about another approach, what if just before rendering on the server we prebundle an app with some tools like rollup/webpack and then pass it to server-side rendering? I guess this can eliminate some of the limitations of the ts-node...

gund commented 7 years ago

With prebundled module I have successfully server rendered an app! So until there will be a more fine grained control I guess for real-world complex application prebundling is the only way of using this utility...

stephaneeybert commented 7 years ago

@grund May I ask what do you mean with prebundling ?

stephaneeybert commented 7 years ago

@Splaktar How do we add moduleId: module.id to the components ?

gund commented 7 years ago

@stephaneeybert by prebundling I mean complete bundling of application as you would do for browsers (transpile TS, process styles etc) but then run that app on the server side in node (not in ts-node).

In this way you fully control how your app will be bundled with all necessary tweaks and then just pass to node plain JS app.

I did my prebundling via roll-up but any tool which produces single js file would be fine (for ex. webpack).

stephaneeybert commented 7 years ago

The sass issue which has received answers here is not the main issue of the thread. I'm having the same issue and not using sass at all. On angular 4.3.2 on Ubuntu 16.04 here.

$ npm-run ngu-app-shell --module src/app/app.module.ts
Unhandled Promise rejection: ENOENT: no such file or directory, open '../app.component.css' ; Zone: <root> ; Task: Promise.then ; Value: { Error: ENOENT: no such file or directory, open '../app.component.css'

Too bad this is bombing the awesome presentation