ค้นหาเว็บไซต์

typescript - Angular monorepo ข้อผิดพลาด TS6059: ไฟล์ 'ng-youtube-api.service.ngtypecheck.ts' ไม่อยู่ภายใต้ 'rootDir' คาดว่า 'rootDir' จะต้องมีไฟล์ต้นฉบับทั้งหมด


ฉันได้สร้างไลบรารี/แพ็กเกจ Angular จำนวน 3 ตัว:

  • @example/ng-youtube-player ซึ่งประกอบด้วย YoutubePlayerComponent และ YoutubeApiService
  • @example/ng-dailymotion-player ประกอบด้วย DailymotionPlayerComponent และ DailymotionApiService
  • @example/ng-vimeo-player ที่ประกอบด้วย VimeoPlayerComponent และ VimeoApiService

ตอนนี้ผมต้องการสร้างไลบรารีที่มี VideoPlayerComponent โดยใช้เฉพาะแพ็กเกจที่ให้บริการ YoutubeApiService, DailymotionApiService และ VimeoApiService เพื่อหลีกเลี่ยงการรวมคอมโพเนนต์อื่น ๆ โดยไม่จำเป็น ผมจึงต้องการแยกไลบรารีทั้ง 3 ออกเป็นแต่ละอัน เพื่อที่จะสามารถติดตั้งเฉพาะคลาส Service ได้

คุณอาจจะโต้แย้งได้ว่า Angular ใช้ tree-shaking ดังนั้นส่วนประกอบจะไม่ถูกบรรจุรวมกับแอปพลิเคชันอยู่แล้ว แต่ยังไงก็ตาม ฉันก็อยากให้การพึ่งพานั้นแยกออกไปเพื่อความกระชับ

ฉันได้ลองตั้งค่า monorepo ที่มีไลบรารี 2 ตัวและแอปพลิเคชันทดสอบ แต่ตั้งแต่ช่วงที่ฉันอ้างอิงบริการจากไลบรารีอื่น การสร้างจะล้มเหลว ฉันได้สร้าง workspace ตัวอย่างที่ง่ายมากเพื่อทำซ้ำปัญหา:

git clone https://github.com/PieterjanDeClippel/angular-monorepo-test
cd angular-monorepo-test
npm install
ng build @mintplayer/ng-youtube-api
ng build @mintplayer/ng-youtube-player
ng build ng-youtube-player-demo

All projects compile successfully
Now go to the NgYoutubePlayerComponent and uncomment the injection parameter in the constructor (line 16)

ng build @mintplayer/ng-youtube-player

การสร้างล้มเหลวพร้อมกับข้อผิดพลาดเหล่านี้จำนวนมาก:

✖ Compiling with Angular sources in Ivy partial compilation mode.
projects/mintplayer/ng-youtube-api/src/lib/ng-youtube-api.service.ts:1:1 - error TS6059: File 'C:/Users/user/source/repos/Tmp/mintplayer-ng-youtube-player/projects/mintplayer/ng-youtube-api/src/lib/ng-youtube-api.service.ngtypecheck.ts' is not under 'rootDir' 'C:\Users\user\source\repos\Tmp\mintplayer-ng-youtube-player\projects\mintplayer\ng-youtube-player\src'. 'rootDir' is expected to contain all source files.
1 import { Injectable } from '@angular/core';
 
projects/mintplayer/ng-youtube-api/src/public-api.ts:1:1 - error TS6059: File 'C:/Users/user/source/repos/Tmp/mintplayer-ng-youtube-player/projects/mintplayer/ng-youtube-api/src/public-api.ngtypecheck.ts' is not under 'rootDir' 'C:\Users\user\source\repos\Tmp\mintplayer-ng-youtube-player\projects\mintplayer\ng-youtube-player\src'. 'rootDir' is expected to contain all source files.

มีปัญหาหลักอยู่ 2 ประการที่นี่:

  1. คุณต้องสร้างแต่ละโปรเจกต์แยกกัน ตามลำดับที่ถูกต้อง
  2. คุณไม่สามารถใช้บริการจากไลบรารีอื่นภายในไลบรารีได้

ฉันได้อ่านคำถามที่คล้ายกันต่อไปนี้แล้ว แต่ก็ไม่ได้ช่วยฉันได้เลย:

  • 'rootDir' คาดว่าจะมีไฟล์ซอร์สทั้งหมด

รหัส

โค้ดทดสอบของฉันถูกโฮสต์อยู่ที่นี่ คำแนะนำทั้งหมดในการทำซ้ำปัญหาจะถูกบันทึกไว้ในบล็อกโค้ดด้านบน การเปลี่ยนแปลงหลักที่ฉันทำอยู่ในไฟล์ tsconfig.json ซึ่งอยู่ที่ราก:

{
  ...
  "compilerOptions": {
    ...,
    "paths": {
      "@mintplayer/ng-youtube-api": [
        "projects/mintplayer/ng-youtube-api/src/public-api.ts"
      ],
      "@mintplayer/ng-youtube-player": [
        "projects/mintplayer/ng-youtube-player/src/public-api.ts"
      ]
    }
  }
}

ฉันได้ตั้งค่า workspace ที่มีทั้งไลบรารีและแอปพลิเคชันแล้ว โดยแอปพลิเคชันสามารถใช้งานคลาสจากไลบรารีได้โดยไม่มีปัญหา (ดูที่ 3 รีโพสิตอรีด้านบนของคำถาม) แต่ตั้งแต่ช่วงที่ไลบรารีหนึ่งใช้งานคลาสจากไลบรารีอีกตัว การสร้างโปรเจกต์ก็ล้มเหลว

ฉันจะแก้ไขสิ่งนี้ได้อย่างไร และมีพื้นที่ทำงานเดียวที่มีไลบรารี 2 ตัวและแอปพลิเคชันทดสอบได้อย่างไร?

คำตอบ #1

ถ้าคุณกำลังใช้ nx และพบข้อผิดพลาดที่รายงานโดยผู้โพสต์...

ฉันก็เจอปัญหานี้เช่นกัน...

มันทำให้ฉันทรมานมาก... ฉันไม่สามารถหาสาเหตุได้ว่าเพราะอะไร nx ถึงสร้างโปรเจกต์ไม่ถูกต้อง... มันให้ข้อผิดพลาดมากมายเกี่ยวกับหนึ่งในโปรเจกต์ที่ฉันอ้างอิง @scope1/lib2 และไฟล์ .ts ทั้งหมดของมันที่อยู่นอกโปรเจกต์ที่อ้างอิงมัน... ฉันยังสังเกตเห็นด้วยว่า dep-graph มี @scope1/lib2 แต่ไม่มีลูกศรการพึ่งพาจากไลบรารีที่อ้างอิงนั้น...

ฉันพบวิธีแก้นี้:

rm -rf node_modules/.cache

ฉันเดาว่า nx น่าจะมีบางอย่างในแคชที่ผิดพลาด... หลังจากลบไปแล้ว กราฟการขึ้นต่อกันก็แสดงลิงก์อย่างถูกต้องและการสร้างเริ่มทำงานได้

คำตอบ #2

อาจจะมาช้าหน่อย แต่ฉันเจอปัญหานี้ที่นี่และฉันใช้แค่ Angular CLI ปกติเพื่อจัดการ workspace ของฉัน...หลังจากค้นหามากมายและอ่านเอกสาร Typescript เกี่ยวกับการแก้ไขโมดูล ฉันเชื่อว่าฉันเข้าใจสิ่งที่เกิดขึ้น:

การแม็ปเส้นทางเป็นเรื่องปกติสำหรับ Angular Libraries (โดยเฉพาะเมื่อใช้กลยุทธ์ entry-points รอง) แต่พฤติกรรมของมันค่อนข้างซับซ้อน สิ่งต่าง ๆ จะซับซ้อนขึ้นอีกเมื่อเรามีหลายไลบรารีใน workspace เดียวกัน: บางครั้ง IDE แสดงข้อผิดพลาดอย่างบ้าคลั่ง; บางครั้งทุกอย่างดูปกติ แต่จะล้มเหลวระหว่างการ build; บางครั้งทุกอย่างโอเคระหว่างการ build ของไลบรารี แต่ทุกอย่างระเบิดเมื่อ build แอป/ไลบรารีของผู้ใช้งาน

ปัญหาคือ: ผู้บริโภคต้องการเวอร์ชันที่ถูกสร้างขึ้นของไลบรารีเพื่อให้ทำงานได้อย่างถูกต้อง ดังนั้นพวกเขาควรมองไปที่โฟลเดอร์ dist วิธีที่ฉันแก้ปัญหานี้คือ:

  • เก็บแมปปิ้งในช่วงเวลาการพัฒนา (แก้ไขเป็น projects/...) ไว้ใน tsconfig.json ราก
  • เพิ่มการแมปไปยังสิ่งก่อสร้างที่สร้างขึ้นใน tsconfig ที่ใช้ในการสร้างไลบรารีผู้บริโภค (ระบุไว้ในการกำหนดค่า angular.json)

IDE มีความสุข, ng-packagr มีความสุข ฮ่าฮ่าฮ่า

ชนแก้ว!

บทความที่เกี่ยวข้อง