dart-lang / webdev

A CLI for Dart web development.
https://pub.dev/packages/webdev
212 stars 75 forks source link

Main method not called using ddc #1216

Open agPublicVoid opened 3 years ago

agPublicVoid commented 3 years ago

main.dart has following code:

import 'package:angular/angular.dart';
import 'package:angular_router/angular_router.dart';
import 'main.template.dart' as self;
import 'package:company/app_component.template.dart' as ng;

@GenerateInjector([
  routerProvidersHash, 
])
final InjectorFactory injector = self.injector$Injector;

void main() {
  print(" in main 25 "); // main method never executed
   runApp(ng.AppComponentNgFactory, createInjector: injector); // this line never executed, neither
}

app_component.dart:

import 'package:angular/angular.dart';
import 'package:angular_router/angular_router.dart';

@Component(
    selector: 'infapp',
    templateUrl: 'app_component.html',
    directives: const [
      coreDirectives,
      routerDirectives,
    ],
)
class AppComponent  {
  AppComponent(Router router)  {
    print("AppComponent called ... "); // never executed
  }
}

app_component.html

<p>I should see this ...</p>

index.html:

<!DOCTYPE html>
<html>
  <head>
    <meta name="viewport" content="width=device-width, initial-scale=1.0">
    <meta charset="utf-8"/>
    <link rel="icon" type="image/ico" href="img/icons/favicon.ico">
    <title>company</title>
    <script>
      (function () {
        var m = document.location.pathname.match(/^(\/[-\w]+)+\/web($|\/)/);
        document.write('<base href="' + (m ? m[0] : '/') + '" />');
      }());
    </script>
    <script defer src="main.dart.js"></script>
  </head>
  <body>
    <infapp>
      <div class="container">
        <div class="col-xs-12 col-sm-6 col-md-3 mx-auto pt-5">
          <div class="card">
            <div class="card-body">
              <h4 class="text-center">
                Loading...<br>
                Please Wait
              </h4>
            </div>
          </div>
        </div>
      </div>
    </infapp>
  </body>
</html>

pubsec.yaml

name: company
description: company
version: 0.0.1
environment:
  sdk: '>=2.10.0 <=3.0.0'
dependencies:
  angular: ^6.0.1
  angular_forms: ^3.0.0
  angular_router: ^2.0.0
  http: ^0.12.2
  stream_transform: ^1.2.0
  uuid: ^2.2.2
  json_annotation: ^3.1.0
  bootstrap_sass: ^4.5.0
  angular_components: ^1.0.2
dev_dependencies:
  sass_builder: ^2.1.3
  json_serializable: ^3.5.0
  build_runner: ^1.10.9
  build_web_compilers: ^2.15.1

Command used to run the app with ddc compiler: pub global run webdev serve --debug -v

It compiles fine, no errors, but when navigating to http://localhost:8080, only index.html content is displayed, AppComponent component never instantiated, nor main method of main.dart called . Only one warning in a chrome developer console:

DevTools failed to load SourceMap: Could not load content for http://127.0.0.1:8080/packages/build_web_compilers/src/dev_compiler_stack_trace/stack_trace_mapper.dart.js.map: HTTP error: status code 404, net::ERR_HTTP_RESPONSE_CODE_FAILURE

When running dart2js compiler, app behaves correctly, and AppComponent is loaded: pub global run webdev serve --release -v

As another example, I have tested this issue with sample TOH at: https://github.com/angular-examples/quickstart/tree/master too

After fixing few dependencies, app could build, not able to run it with ddc compiler, only with dart2js.

Note: There is no build.yaml in a project sources.

1) Why is main.dart main method never executes ? 2) Why is AppComponent constructor never gets called ? 3) What am I doing wrong ? :)

Thank you

sigmundch commented 3 years ago

Thanks for your question @agPublicVoid - please also consider in the future posting your question to stack overflow, since other community members monitor that more often and may be able to provide help faster.

Did you see any errors in the command-line console? Are you able to see different issues if you delete the webdev/build cache under .dart_tools/...?

When I tried your example from scratch, I got errors on the command-line console indicating that the build process couldn't find app_component.template.dart. In my case, main.dart.js didn't exist. Turns out that I didn't have a app_component.html file. Adding it fixed the issue, the app rendered appropriately and log messages were visible.

As for why it worked with dart2js, I'm not sure. Maybe some code was partially cached under .dart_tools and they were still being used in that workflow?

/cc @jakemac53 @grouma in case they have other suggestions.

agPublicVoid commented 3 years ago

Hello @sigmundch, @jakemac53 , @grouma . Thank you for you response!

1) There were no errors in a build console, nor browser console. 2) I do have valid app_component.html with following contents: <p>I should see this ...</p> I just did not add it here.

To clarify the main.dart.js is generated, but app never calls main method of main.dart thus angular app is not "bootstrapped" in method: runApp .

I have, also, tested this behavior using this example: https://github.com/angular-examples/quickstart/tree/master.

My colleagues report the same behavior for ddc with my example, and with https://github.com/angular-examples/quickstart/tree/master tutorial sample app, using same Mac OS listed, above.

Running app in dart2js works fine, no issues at all: main method of main.dart called, and angular is "bootstrapped"

We have also tired to remove router dependencies or any declaration of it, and router outlet from app_component.html, but the same issue happens.

We have, also, tried to delete all build and dart_tool folders, and deleting pub cache.

Thank you for your response, really.

agPublicVoid commented 3 years ago

Also looking into generated no sound files, bootstrap file, and .template files. I can see that following code is never executed:

main.dart.bootstrap.js

if(!window.$dwdsInitialized) {
    window.$dwdsInitialized = true;// executes
    window.$dartMainTearOffs = [(app.web__main || app.main).main]; // executes
    window.$dartRunMain = function() { 
      window.$dartMainExecuted = true; // this is never executed
      window.$dartMainTearOffs.forEach(function(main) { // never executed
         main(); // never executed
      });
    }

It seems like, Code executes in app_component.template.dart, following:

var _visited = false;
void initReflector() {
  if (_visited) {
    return;
  }
  _visited = true;

  _ngRef.registerComponent(AppComponent, createAppComponentFactory());
  _ref0.initReflector();
  _ref1.initReflector();
}

And always comes to:

if (_visited) {
    return;
  }

and returns, since _visited is always false.

agPublicVoid commented 3 years ago

Sorry, I don't mean to spam your service desk, but, code above works fine in following environment:

Code Works with following environment, on another MAC computer:

Chrome - 79.0.39 and 86.0.4240.198 Dart - Dart SDK version: 2.10.3 (stable) (Tue Oct 27 14:44:30 2020 +0100) on "macos_x64" MacOS - 10.15.6 build_runner: ^1.10.3 build_web_compilers: ^2.12.2

It does executes following code in main.dart.bootstrap.js:

if(!window.$dwdsInitialized) {
    window.$dwdsInitialized = true; 
    window.$dartMainTearOffs = [(app.web__main || app.main).main];  
    window.$dartRunMain = function() { 
      window.$dartMainExecuted = true;  
      window.$dartMainTearOffs.forEach(function(main) {  
         main(); // CALLS MAIN METHOD
      });
    }

But in the in the following environment (note , I have downgraded sdk to 2.10.3) it does NOT:

Chrome - 87.0.4280.88 Dart - Dart SDK version: 2.10.3 (stable) (Tue Oct 27 14:44:30 2020 +0100) on "macos_x64" MacOS - 10.15.7 (19H2) build_runner: ^1.10.3 build_web_compilers: ^2.12.2

we of course deleted .dart_tool, build and cleared pub cache, before trying.

agPublicVoid commented 3 years ago

It appeared to be a problem with permissions.

Running application with:

sudo pub global run webdev serve web:8081 --auto=refresh --debug creates .dart_tool/webdev folder and starts a web browser.

Checking audit logs, there were permissions denied errors found to create .dart_tool/webdev folder. Running command with sudo privileges solved a problem. However non of the other other folders under .dart_tool/webdev folder require sudo permissions

Also, if a new browser window is opened, main method is not loaded, again.

sigmundch commented 3 years ago

Glad you were able to find out the source of the issue with permissions!

It does seem strange, since our tools do not require to be run with sudo entirely.

I wonder whether your device is in an odd state. For example, if you had used sudo in the past or if files are shared across users, I could imagine such a mix could make the files not accessible to non-sudo users and as a result cause trouble later. Not sure how to diagnose that further. Maybe check whether all files in your pub cache are visible to the current user of the machine? try clearing the entire pub-cache folder as well as the .dart_tools/ folder as you did recently?

grouma commented 3 years ago

Note that when you pass --debug, webdev automatically launches Chrome and loads you application for you. Are you trying to manually load it?

With that being said, the .dart_tool/webdev folder is used when we launch Chrome. If you have permission issues an error should be thrown. We don't have any special error handling around that so I wonder if it is simply silently failing.

agPublicVoid commented 3 years ago

Hello Yes.

--debug does open Chrome automatically as intendant.

"If you have permission issues an error should be thrown." - sadly, no error is thrown in a console.

For some reason, only webdev folder: .dart_tool/webdev causes main method not to execute. build, build_resolvers and pub folders do get created without using sudo.

Thank you