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 ประการที่นี่:
- คุณต้องสร้างแต่ละโปรเจกต์แยกกัน ตามลำดับที่ถูกต้อง
- คุณไม่สามารถใช้บริการจากไลบรารีอื่นภายในไลบรารีได้
ฉันได้อ่านคำถามที่คล้ายกันต่อไปนี้แล้ว แต่ก็ไม่ได้ช่วยฉันได้เลย:
- '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 มีความสุข ฮ่าฮ่าฮ่า
ชนแก้ว!
