@angular-builders/custom-webpack:karma fails compiling TypeScript with activated strictNullChecks
Describe the Bug
When a custom webpack config is provided written in TypeScript, @angular-builders/custom-webpack:karma throws an error if strictNullChecks are activated.
Minimal Reproduction
https://github.com/Markus-Ende/custom-webpack-builder-strictnullchecks-issue
- Clone & install repo
- run
npm test.
(Deactive strictNullChecks in tsconfig.json to see, that the Error does only occur when activated)
Expected Behavior
Karma tests should run normally.
Error output
An unhandled exception occurred: ⨯ Unable to compile TypeScript:
webpack-config/extra-webpack.config.ts:2:54 - error TS2345: Argument of type 'undefined' is not assignable to parameter of type 'Function'.
2 export default (config) => __awaiter(void 0, void 0, void 0, function* () {
~~~~~~
See "/tmp/ng-Hi3EUl/angular-errors.log" for further details.
Environment
Libs
- @angular/core version: 9.1.9
- @angular-devkit/build-angular version: 0.901.7
- @angular-builders/custom-webpack version: 9.1.0
For Tooling issues:
- Node version: v12.16.1
- Platform: Linux
Is this just Karma issue? No problems with ng build and ng serve?
Yes, just Karma.
Ok. A few findings:
- The problem is with
asynckeyword - once it is removed the problem goes away. So as a workaround you can just use plainPromisesyntax. - I can disable the type checking for the config file by passing
transpileOnlyoption intoregister. Not sure it's the right decision though (it is basically your only indication for type errors in your config). - Another solution would be to have a separate
tsconfig.json(built in the builder) for config transpilation. Not sure this is the right decision either, since I do want people to have control of it. - I'd probably go with
#2or#3if it was happening with all the commands. But it only happens with Karma and I don't have any idea why. So I think it's important to understand how Karma flow is different from the others before we take any actions.
Can confirm, that the problem is fixed in my project setup, when avoiding the async keyword. Nice catch!
Would vote for #2. Couldn't you just add "strictNullChecks":false to the compiler options in register?
But I agree with you that we should first understand the problem before fixing the symptoms.
just had a similar issue in e2e-specs.
I do not use custom-webpack ... just startet ng e2e.
15:16:23] E/launcher - Error: TSError: ⨯ Unable to compile TypeScript:
e2e/src/app.e2e-spec.ts:12:48 - error TS2345: Argument of type 'undefined' is not assignable to parameter of type 'Function'.
12 beforeEach(() => __awaiter(void 0, void 0, void 0, function* () {
~~~~~~
e2e/src/app.e2e-spec.ts:20:74 - error TS2345: Argument of type 'undefined' is not assignable to parameter of type 'Function'.
20 it('should have menu item "Basics"', () => __awaiter(void 0, void 0, void 0, function* () {
seems like there were two different helpers for the awaiter (one for the code from the spec and one for the code of the component harness)
... stopped further investigations since the "strictNullChecks": false solution (only for e2e specs) works for me. Thanks @Markus-Ende
@e-hein you use plain Karma builder and you got this error too? Did you solve it by setting "strictNullChecks": false in tsconfig.spec.json?
- I do not use custom webpack ... will start a new plain angular project and find the point where it breaks (seems not to be an issue for every user so there must be something in my setup, but the project isn't very big yet)
- yes,
"strictNullChecks": falsesolved that error (but now I'm struggling with other errors)
got it (in my case):
- I use "pathes" in my tsconfig.json to reference angular libraries (ng generate new library)
- There's some shared testing code in some of my libraries
- ts-node does not support "pathes", so I included
tsconfig-pathes- too early
now I moved the code into the onPrepare method of my protractor.conf:
onPrepare() {
const tsNode = require('ts-node');
require('tsconfig-paths/register');
tsNode.register({
project: require('path').join(__dirname, './tsconfig.json')
});
jasmine.getEnv().addReporter(new SpecReporter({ spec: { displayStacktrace: true } }));
}
and reactivated "strictNullChecks": true
Result:
- all compiler errors (including the awaiter and following) are solved
- I can use "pathes", even switch between precompiled libraries and source
- My e2e test is red (expected result)
@e-hein Great news! I'm not sure how tsconfig-paths can affect the async generator but OK.
Seems like the problem might be with ts-node registration. I'll look into it more.
Seems like this is the issue. Karma runner registers ts-node automatically and since it's also registered in custom-webpack the transpiled code is corrupted.
I have the same issue with customWebpackConfig when I run ng serve command.
My workspace
"@angular-builders/custom-webpack": "^10.0.1"
"@angular/core": "10.1.6"
"@nrwl/angular": "10.3.1"
"ts-node": "~7.0.0"
I have my extra-webpack.config.ts write in typescript. When I try to use async/await anywere in the file, I have this in the console
> ng run my-app:serve
An unhandled exception occurred: ⨯ Unable to compile TypeScript:
apps/my-app/extra-webpack.config.ts:26:111 - error TS2322: Type 'number' is not assignable to type '{ label: number; sent: () => any; trys: any[]; ops: any[]; }'.
26 if (!(t = _.trys, t = t.length > 0 && t[t.length - 1]) && (op[0] === 6 || op[0] === 2)) { _ = 0; continue; }
~
See "/<path-to-angular-errors-file>/angular-errors.log" for further details.
So, what about this issue ? Any solution ?
Thanks for the efforts <3
The issue is that there are two instances of ts-node registered during the run. No out of the box solution at the moment.
As a first step I'd try to remove your direct ts-node dependency and if that doesn't help I'd just use Promise.then syntax.
I removed ts-node direct dependency but problem was always there. I used the Promise.then syntax and it work very well.