Skip to content
New issue

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

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

Already on GitHub? Sign in to your account

Admin Ui: Angular error when compiling AdminUiPlugin #758

Closed
Wanztwurst opened this issue Mar 12, 2021 · 15 comments
Closed

Admin Ui: Angular error when compiling AdminUiPlugin #758

Wanztwurst opened this issue Mar 12, 2021 · 15 comments
Assignees
Labels
type: bug 🐛 Something isn't working

Comments

@Wanztwurst
Copy link
Contributor

Wanztwurst commented Mar 12, 2021

Compiling the AdminUiPlugin works with devMode since 1.0.0-beta.3 again, but now the compiled admin-ui throws an error in the Angular code when opening the admin page in browser: TypeError: e.factory is not a function

To Reproduce

  1. Start vendure server with AdminUiPlugin.init({ ... app: compileUiExtensions({ ... }) )
  2. Open admin page in Browser
  3. main.ts:16 TypeError: e.factory is not a function – page doesn't load

Empty extensions: [] or parameters, including devMode, don't seem to make a difference.

@Wanztwurst Wanztwurst added the type: bug 🐛 Something isn't working label Mar 12, 2021
@michaelbromley
Copy link
Member

I ran into some issues with Angular after updating, and the solution in my case seemed to be to delete the lockfile, node_modules, and then reinstall. If you've not tried that yet, have a go and let me know if it solves it.

@Wanztwurst
Copy link
Contributor Author

This didn't change the outcome. Sadly I have no idea what could cause this issue.

@michaelbromley
Copy link
Member

OK. Is there more to the stack trace you can share?

@Wanztwurst
Copy link
Contributor Author

Wanztwurst commented Mar 12, 2021

Last year some people experienced the bug after an Angular upgrade from 8 to 9, there was something wrong with a decorator. But I compiled the admin-ui successfully after the upgrade to Angular 11 last week – no clue again.

Chromium:

TypeError: record.factory is not a function
    at R3Injector.hydrate (core.js:11379)
    at R3Injector.get (core.js:11200)
    at core.js:11237
    at Set.forEach (<anonymous>)
    at R3Injector._resolveInjectorDefTypes (core.js:11237)
    at new NgModuleRef$1 (core.js:25268)
    at NgModuleFactory$1.create (core.js:25322)
    at core.js:29133
    at ZoneDelegate.invoke (zone-evergreen.js:372)
    at Object.onInvoke (core.js:28534)

Firefox:

TypeError: record.factory is not a function
    Angular 20
        hydrate
        get
        _resolveInjectorDefTypes
        _resolveInjectorDefTypes
        NgModuleRef$1
        create
        bootstrapModuleFactory
        invoke
        onInvoke
        invoke
        run
        run
        bootstrapModuleFactory
        bootstrapModule
        invoke
        run
        scheduleResolveOrReject
        invokeTask
        runTask
        drainMicroTaskQueue
main.ts:16:16

This is the error trace from the browser – is there a better one I could get you? Also, does it currently work on your system – then it should be an error on my end?

@michaelbromley
Copy link
Member

Thanks, the non-minified stack trace is much more useful.

I have a project with quite a lot of custom UI stuff being compiled. Didn't have any issue with the latest beta.3 (after deleting lockfile as mentioned).

So take another look at your end, let me know if you find anything else useful. If not, then a minimal reproduction repo would be helpful for me to debug.

@Wanztwurst
Copy link
Contributor Author

Will do, thank you!

@martijnvdbrug
Copy link
Collaborator

martijnvdbrug commented Mar 13, 2021

I found this related issue: angular/angular#35282, where some comments say that upgrading added unwanted @Injectable()'s to components.
In packages/admin-ui/src/lib/core/src/shared/pipes/locale-base.pipe.ts I see an Injectable() on abstract class LocaleBasePipe, which should not be there, because this is an abstract class.
Nope, this is not it.

@michaelbromley
Copy link
Member

I went though angular/angular#35282 and tried to re-create the error in the real-world-vendure repo:

  • Adding a reference to ReviewsSharedModule to the ReviewsUiExtensionModule providers array
  • Adding the @Injectable() decorator to the ReviewsUiExtensionModule

Neither of those reproduced the error. So I'm a bit stuck in fixing this without a reproduction.

One question I have is this: did you delete the admin-ui folder after upgrading?

@martijnvdbrug
Copy link
Collaborator

martijnvdbrug commented Mar 15, 2021

One question I have is this: did you delete the admin-ui folder after upgrading?
Yep.

I think I have a minimal reproduction. It does use createTestEnvironment instead of a 'real' vendure instance, but the error is the same:

  1. Run this with yarn ts-node dev-server.ts
  2. Go to http://localhost:3050/admin and see TypeError: record.factory is not a function in the console.
// dev-server.ts
import {createTestEnvironment, registerInitializer, SqljsInitializer, testConfig,} from '@vendure/testing';
import {DefaultLogger, LogLevel} from '@vendure/core';
import {AdminUiPlugin} from '@vendure/admin-ui-plugin';
import {compileUiExtensions} from '@vendure/ui-devkit/compiler';
import * as path from 'path';
import {initialData} from '../../test/initialData';

(async () => {
    testConfig.logger = new DefaultLogger({level: LogLevel.Debug});
    registerInitializer('sqljs', new SqljsInitializer('__data__'));
    testConfig.plugins.push(AdminUiPlugin.init({
        route: 'admin',
        port: 3002,
        app: compileUiExtensions({
            outputPath: path.join(__dirname, '__admin-ui'),
            extensions: [],
            devMode: true,
        }),
    }));
    testConfig.apiOptions.shopApiPlayground = {};
    testConfig.apiOptions.adminApiPlayground = {};
    const {server} = createTestEnvironment(testConfig);
    await server.init({
        initialData,
        productsCsvPath: '../test/products-import.csv',
    });
})();

Dependency versions:

// yarn list --pattern "@angular/*"
yarn list v1.22.10
├─ @angular/animations@11.2.4
├─ @angular/cdk@11.2.3
├─ @angular/cli@11.2.4
├─ @angular/common@11.2.4
├─ @angular/compiler-cli@11.2.5
├─ @angular/compiler@11.2.5
├─ @angular/core@11.2.4
├─ @angular/forms@11.2.4
├─ @angular/language-service@11.2.4
├─ @angular/platform-browser-dynamic@11.2.4
├─ @angular/platform-browser@11.2.4
└─ @angular/router@11.2.4

ts-node

yarn list v1.22.10
└─ ts-node@9.1.1

typescript

yarn list v1.22.10
└─ [email protected]

@michaelbromley
Copy link
Member

michaelbromley commented Mar 15, 2021

Great, thanks.

Initially I could not reproduce the error. My angular deps looked like:

$ yarn list --pattern "@angular/*"
yarn list v1.19.1
├─ @angular/[email protected]
├─ @angular/[email protected]
├─ @angular/[email protected]
├─ @angular/[email protected]
├─ @angular/[email protected]
├─ @angular/[email protected]
├─ @angular/[email protected]
├─ @angular/[email protected]
├─ @angular/[email protected]
├─ @angular/[email protected]
├─ @angular/[email protected]
└─ @angular/[email protected]

Then I deleted the lockfile and reinstalled, so my Angular deps were the same as your list. Now I get the error.

The specific packages changed are:

@angular/[email protected]   -> 11.2.4
@angular/[email protected]   -> 11.2.5
@angular/[email protected]  -> 11.2.5

So a work-around for now would be to use yarn resolutions to pin those 3 Angular packages to the previous version.

@michaelbromley
Copy link
Member

OK I think I have the reason right here: angular/angular#41193 (comment)

Packages must be compiled and ran using the exact same version of Angular; any other combination is not supported and likely to break in subtle ways.

So the @vendure/admin-ui/.. packages have been compiled with the compiler v11.2.4, but now you are trying to use those compiled files with compiler v11.2.5.

The solution is that I need to pin the dependencies of the ui-devkit package to exact patch versions which match those used by the admin-ui package. Currently they are listed as:

"@angular/cli": "^11.2.3",
"@angular/compiler": "^11.2.4",
"@angular/compiler-cli": "^11.2.4",

@Wanztwurst
Copy link
Contributor Author

Can confirm, with compiler 11.2.4 it works.

"resolutions": {
    "@angular/cli": "11.2.4",
    "@angular/compiler-cli": "11.2.4",
    "@angular/compiler": "11.2.4"
},

What's the long term solution for this? Thank you for investigating!

@Draykee
Copy link
Contributor

Draykee commented Mar 15, 2021

I think it's not the compiler version itself, but the forced resolution. When I put compiler version 11.2.3 into the resolutions

"resolutions": {
    "@angular/cli": "11.2.3",
    "@angular/compiler": "11.2.4",
    "@angular/compiler-cli": "11.2.4"
  }

it still works for me. Therefore I would say the solution is to have the same compiler version accross the projects.

michaelbromley added a commit that referenced this issue Mar 15, 2021
Relates to #758. Updated and pinned all Angular dependencies to match between admin-ui & ui-devkit.
michaelbromley added a commit that referenced this issue Mar 15, 2021
Relates to #758. Prevents future updates to the Angular versions from introducing version
mismatch errors
@michaelbromley
Copy link
Member

What's the long term solution for this?

I've implemented an automated check to ensure that Angular compiler versions match between the admin-ui & ui-devkit packages. This should prevent such errors being re-introduced in future.

@martijnvdbrug
Copy link
Collaborator

If you're using yarn workspaces or Lerna with yarn, don't forget to add the resolutions in your root package.json, not in child package.json's

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
type: bug 🐛 Something isn't working
Projects
None yet
Development

No branches or pull requests

4 participants