2

This is my first time working in the world of schematics, so it's quite possible I just don't have this set up correctly. But I've been following the guide on angular.io and some additional blog walkthroughs. I'm wanting to package ng-add and ng-update schematics into a component library, that I already have setup and running well. After setting up the initial plumbing for the ng-add one, I wrote a simple unit test just to validate the setup and as soon as it hits the call to new SchematicTestRunner, it blows up with a ton of Module not found errors, including child_process and fs. In fact i commented out everything in the unit test except the creation of the test runner, just to identify the breaking point. And the schematic itself isn't doing anything yet except returning the tree as-is. Interestingly, the "blank"/sample schematics project that the schematics-cli generates doesn't use ng test at all, but instead uses jasmine directly. But with this being in an existing Angular Library with full test suite, i want to test in the same way. Any help with this, would be much appreciated!

Portion of error:

ERROR in C:/Users/<username>/src/fabric/ui/node_modules/@angular-devkit/schematics/tasks/node-package/executor.js
Module not found: Error: Can't resolve 'child_process' in 'C:\Users\<username>\src\fabric\ui\node_modules\@angular-devkit\schematics\tasks\node-package'
resolve 'child_process' in 'C:\Users\<username>\src\fabric\ui\node_modules\@angular-devkit\schematics\tasks\node-package'
  Parsed request is a module
  using description file: C:\Users\<username>\src\fabric\ui\node_modules\@angular-devkit\schematics\package.json (relative path: ./tasks/node-package)
    Field 'browser' doesn't contain a valid alias configuration
    resolve as module
      looking for modules in C:/Users/<username>/src/fabric/ui
        using description file: C:\Users\<username>\src\fabric\ui\package.json (relative path: .)
          Field 'browser' doesn't contain a valid alias configuration
          using description file: C:\Users\<username>\src\fabric\ui\package.json (relative path: ./child_process)
            no extension
              Field 'browser' doesn't contain a valid alias configuration
              C:\Users\<username>\src\fabric\ui\child_process doesn't exist
            .ts
              Field 'browser' doesn't contain a valid alias configuration
              C:\Users\<username>\src\fabric\ui\child_process.ts doesn't exist
            .tsx
              Field 'browser' doesn't contain a valid alias configuration
              C:\Users\<username>\src\fabric\ui\child_process.tsx doesn't exist
            .mjs
              Field 'browser' doesn't contain a valid alias configuration
              C:\Users\<username>\src\fabric\ui\child_process.mjs doesn't exist
            .js
              Field 'browser' doesn't contain a valid alias configuration
              C:\Users\<username>\src\fabric\ui\child_process.js doesn't exist
            as directory
              C:\Users\<username>\src\fabric\ui\child_process doesn't exist
      C:\Users\<username>\src\fabric\ui\node_modules\@angular-devkit\schematics\tasks\node-package\node_modules doesn't exist or is not a directory
      C:\Users\<username>\src\fabric\ui\node_modules\@angular-devkit\schematics\tasks\node_modules doesn't exist or is not a directory
      C:\Users\<username>\src\fabric\ui\node_modules\@angular-devkit\node_modules doesn't exist or is not a directory
      C:\Users\<username>\src\fabric\ui\node_modules\node_modules doesn't exist or is not a directory
      C:\Users\<username>\src\fabric\node_modules doesn't exist or is not a directory
      C:\Users\<username>\src\node_modules doesn't exist or is not a directory
      C:\Users\<username>\node_modules doesn't exist or is not a directory
      C:\Users\node_modules doesn't exist or is not a directory
      C:\node_modules doesn't exist or is not a directory
      looking for modules in C:\Users\<username>\src\fabric\ui\node_modules\@angular-devkit\schematics\node_modules
        using description file: C:\Users\<username>\src\fabric\ui\node_modules\@angular-devkit\schematics\package.json (relative path: ./node_modules)
          Field 'browser' doesn't contain a valid alias configuration
      looking for modules in C:\Users\<username>\src\fabric\ui\node_modules
        using description file: C:\Users\<username>\src\fabric\ui\package.json (relative path: ./node_modules)
          Field 'browser' doesn't contain a valid alias configuration
          using description file: C:\Users\<username>\src\fabric\ui\node_modules\@angular-devkit\schematics\package.json (relative path: ./node_modules/child_process)
            no extension
              Field 'browser' doesn't contain a valid alias configuration
          using description file: C:\Users\<username>\src\fabric\ui\package.json (relative path: ./node_modules/child_process)
            no extension
              Field 'browser' doesn't contain a valid alias configuration
              C:\Users\<username>\src\fabric\ui\node_modules\@angular-devkit\schematics\node_modules\child_process doesn't exist
            .ts
              Field 'browser' doesn't contain a valid alias configuration
              C:\Users\<username>\src\fabric\ui\node_modules\child_process doesn't exist
            .ts
              Field 'browser' doesn't contain a valid alias configuration
              C:\Users\<username>\src\fabric\ui\node_modules\@angular-devkit\schematics\node_modules\child_process.ts doesn't exist
            .tsx
              Field 'browser' doesn't contain a valid alias configuration
              C:\Users\<username>\src\fabric\ui\node_modules\child_process.ts doesn't exist
            .tsx
              Field 'browser' doesn't contain a valid alias configuration
              C:\Users\<username>\src\fabric\ui\node_modules\@angular-devkit\schematics\node_modules\child_process.tsx doesn't exist
            .mjs
              Field 'browser' doesn't contain a valid alias configuration
              C:\Users\<username>\src\fabric\ui\node_modules\child_process.tsx doesn't exist
            .mjs
              Field 'browser' doesn't contain a valid alias configuration
              C:\Users\<username>\src\fabric\ui\node_modules\@angular-devkit\schematics\node_modules\child_process.mjs doesn't exist
            .js
              Field 'browser' doesn't contain a valid alias configuration
              C:\Users\<username>\src\fabric\ui\node_modules\child_process.mjs doesn't exist
            .js
              Field 'browser' doesn't contain a valid alias configuration
              C:\Users\<username>\src\fabric\ui\node_modules\@angular-devkit\schematics\node_modules\child_process.js doesn't exist
            as directory
              C:\Users\<username>\src\fabric\ui\node_modules\@angular-devkit\schematics\node_modules\child_process doesn't exist
              C:\Users\<username>\src\fabric\ui\node_modules\child_process.js doesn't exist
            as directory
              C:\Users\<username>\src\fabric\ui\node_modules\child_process doesn't exist
[C:\Users\<username>\src\fabric\ui\child_process]
[C:\Users\<username>\src\fabric\ui\child_process.ts]
[C:\Users\<username>\src\fabric\ui\child_process.tsx]
[C:\Users\<username>\src\fabric\ui\child_process.mjs]
[C:\Users\<username>\src\fabric\ui\child_process.js]
[C:\Users\<username>\src\fabric\ui\node_modules\@angular-devkit\schematics\tasks\node-package\node_modules]
[C:\Users\<username>\src\fabric\ui\node_modules\@angular-devkit\schematics\tasks\node_modules]
[C:\Users\<username>\src\fabric\ui\node_modules\@angular-devkit\node_modules]
[C:\Users\<username>\src\fabric\ui\node_modules\node_modules]
[C:\Users\<username>\src\fabric\node_modules]
[C:\Users\<username>\src\node_modules]
[C:\Users\<username>\node_modules]
[C:\Users\node_modules]
[C:\node_modules]
[C:\Users\<username>\src\fabric\ui\node_modules\@angular-devkit\schematics\node_modules\child_process]
[C:\Users\<username>\src\fabric\ui\node_modules\child_process]
[C:\Users\<username>\src\fabric\ui\node_modules\@angular-devkit\schematics\node_modules\child_process.ts]
[C:\Users\<username>\src\fabric\ui\node_modules\child_process.ts]
[C:\Users\<username>\src\fabric\ui\node_modules\@angular-devkit\schematics\node_modules\child_process.tsx]
[C:\Users\<username>\src\fabric\ui\node_modules\child_process.tsx]
[C:\Users\<username>\src\fabric\ui\node_modules\@angular-devkit\schematics\node_modules\child_process.mjs]
[C:\Users\<username>\src\fabric\ui\node_modules\child_process.mjs]
[C:\Users\<username>\src\fabric\ui\node_modules\@angular-devkit\schematics\node_modules\child_process.js]
[C:\Users\<username>\src\fabric\ui\node_modules\child_process.js]
 @ C:/Users/<username>/src/fabric/ui/node_modules/@angular-devkit/schematics/tasks/node-package/executor.js 11:24-48
 @ C:/Users/<username>/src/fabric/ui/node_modules/@angular-devkit/schematics/tasks/node/index.js
 @ C:/Users/<username>/src/fabric/ui/node_modules/@angular-devkit/schematics/testing/schematic-test-runner.js
 @ C:/Users/<username>/src/fabric/ui/node_modules/@angular-devkit/schematics/testing/index.js
 @ ./schematics/ng-add/index.spec.ts
 @ . sync \.spec\.ts$
 @ ./test.ts
mfaith
  • 115
  • 3
  • 11
  • Did you find a solution to this problem? I got the same issue right now, but also just started out with schematics. – Brudus Jun 23 '20 at 20:13
  • @Brudus unfortunately not. Still trying to figure it out. Hoping someone here with more experience with schematics can point me in the right direction. I've been looking through github repos too for some indication. I'll report back here if i figure it out. – mfaith Jun 24 '20 at 00:15
  • I found out, that it is actually unrelated to libraries. I can create a brand new project. Run `ng test` and everything works fine. If I then add the `SchematicTestRunner` it will cause the issue you've listed above. For me, that's a bug even when the Angular team says it's not. Anyway, it's at least poorly documented. – Brudus Jun 24 '20 at 00:21
  • 1
    @Brudus oh yeah, i knew it was that specific line that was breaking me. I'd commented everything else out in my test code except that line in the BeforeEach block and that's definitely the point of failure. I originally filed an issue in the angular-cli repo on it, but they said to post here instead, that they don't help with support. I told them the same thing you said: they should at least consider providing some documentation on schematics unit testing, at the very least. There's currently zero coverage. – mfaith Jun 24 '20 at 08:41

1 Answers1

3

I finally got it running! @mfaith and I had a conversation on GitHub with the Angular CLI team. You can find it here: https://github.com/angular/angular-cli/issues/17986

There are two important key takeaways:

  1. You can't run testing, building, and bundling with ng commands. So ng test will never work with the schematic tests as it is meant to be used in the browser (unlike Schematics).
  2. There is a dummy project you can use as a reference. Simply run schematics schematic your-name-for-this-project and it will create a schematic project (named your-name-for-this-project) with 3 basic schematics. There you have the scripts that you can use to run to execute your schematic tests inside a library/app.

I ended up doing the following:

  1. I've created a file tsconfig.schematics.spec.json inside my library folder (see below).
  2. I added two scripts to my projects package.json (see below).
  3. Execute the script via npm run schm:test inside the library folder.

I guess, initially there were two errors on my side. First, I wanted to make the schematic tests work with ng test. Secondly, there were for sure issues with the configuration that I was able to resolve with the configuration files from the schematics schematic project.

tsconfig.schematics.spec.json:

{
    "compilerOptions": {
        "baseUrl": "tsconfig",
        "lib": [
            "es2018",
            "dom"
        ],
        "module": "commonjs",
        "moduleResolution": "node",
        "noEmitOnError": true,
        "noFallthroughCasesInSwitch": true,
        "noImplicitAny": true,
        "noImplicitThis": true,
        "noUnusedParameters": true,
        "noUnusedLocals": true,
        "rootDir": "schematics/",
        "skipDefaultLibCheck": true,
        "skipLibCheck": true,
        "sourceMap": true,
        "strictNullChecks": true,
        "target": "es6",
        "types": [
            "jasmine",
            "node"
        ]
    },
    "include": [
        "schematics/**/*"
    ],
    "exclude": [
        "schematics/*/files/**/*"
    ]
}

2 Scripts in package.json:

"schm:build": "tsc -p tsconfig.schematics.spec.json",
"schm:test": "npm run schm:build && jasmine schematics/**/*.spec.js"
Brudus
  • 749
  • 1
  • 8
  • 22
  • Thanks for helping to get to the bottom of it. I had also noticed that the "blank" schematics project used a different mechanism for testing, but i kind of just assumed it was so they didn't have to include as many dependencies since it was sort of a barebones setup. Now it's just a matter of figuring out a good way to segment the testing, so that the schematics can live in the same library as components, but have testing done independently. – mfaith Jun 24 '20 at 12:10
  • How are you stopping the schematics tests from running as part of the regular library ng test? Or are your schematics in a separate library altogether? – mfaith Jun 24 '20 at 12:12
  • @mfaith No, they are in the library. The ng test is defined in the angular.json. There in the projects find your library and the test target itself. There you should have some options (like main, tsConfig and karmaConfig). Main should point to a file test.ts inside your src folder. My schematics are in a schematics folder in the library but outside of the src folder. Hope that helps, otherwise, let me know how your structure looks like. – Brudus Jun 24 '20 at 13:37
  • I see. Yeah, flattened my library structure from the beginning, so there's no src folder. Everything under the projects/ folder is my library. I set it up similar to how Material had theirs. The schematics folder is just another folder alongside the reusable component folders. But i think i've worked out a solution for segmenting them, by tweaking the test.ts to exclude the schematics folder from being included in ng tests. Then adding the scripts you mentioned to the package for runing the schematics tests separately. That seems to work now. – mfaith Jun 24 '20 at 15:29
  • 1
    Here's a breakdown of how i got it to work, in case that helps others: https://github.com/angular/angular-cli/issues/17986#issuecomment-648915762 – mfaith Jun 24 '20 at 18:19