นำเข้า - การนำเข้า Angular2 & TypeScript ของ node_modules
ฉันมีแอป Angular2 'hello world' ที่เรียบง่ายมาก ฉันยังได้ตัดสินใจที่อาจดูไม่สมเหตุสมผลในการทำงานกับโครงสร้างไดเรกทอรีที่แตกต่างกันระหว่างโปรเจคพัฒนาของฉันกับโฟลเดอร์การปรับใช้สุดท้ายบน backend ของ Spring ของฉันด้วย
เนื่องจากความแตกต่างนี้ ฉันจึงมีปัญหากับการนำเข้า TypeScript และบรรทัดนี้ทำให้เกิดข้อผิดพลาด 404 (ไม่สามารถค้นหาไลบรารี /angular2/core) เมื่อฉันพยายามเปิดแอปจริงในเบราว์เซอร์ของฉัน:
import {Component, View} from 'angular2/core';
สรุปสั้น ๆ ก็คือ ในที่สุดฉันก็เพิ่มโฟลเดอร์ /app กลับเข้าไปเพื่อให้ทุกอย่างทำงานได้ แต่ฉันก็ได้แก้ไขคำสั่งนำเข้าของฉันดังนี้:
import {Component, View} from '../node_modules/angular2/core';
อย่างไรก็ตาม สิ่งนี้กลับทำให้เกิดพฤติกรรมที่แปลกประหลาด บางเหตุผลการระบุ ../node_modules ในเส้นทางไลบรารีทำให้ JS โหลดไฟล์ Angular2 ทั้งหมดจากศูนย์โดยใช้การเรียก ajax เพื่อดึงไฟล์แต่ละไฟล์จากโฟลเดอร์ npm_modules/angular2/ แม้ว่านี่จะเป็นส่วนหนึ่งของส่วนหัว HTML ของฉัน:
<script src="/node_modules/angular2/bundles/angular2.dev.js"></script>
เมื่อฉันสังเกตได้ในที่สุดว่ากำลังเกิดอะไรขึ้น ฉันก็เปลี่ยนคำสั่งนำเข้ากลับไป
import {Component, View} from 'angular2/core';
และทุกอย่างก็ใช้งานได้ Angular2 ตอนนี้ถูกโหลดอย่างสมบูรณ์จากแท็กสคริปต์ด้านบนและไม่มีไฟล์ใดถูกโหลดโดยการเรียก ajax เพิ่มเติม
มีใครช่วยอธิบายได้ไหมว่าสาเหตุของสิ่งนี้คืออะไร? ฉันสมมติว่ามันเป็นพฤติกรรมปกติ แต่ฉันไม่เข้าใจว่าการนำเข้าทำงานอย่างไรและทำไมการระบุเส้นทางที่ละเอียดกว่าจะมีผลต่างมากขนาดนี้
คำตอบ #1
กฎของ import ใน TypeScript จะปฏิบัติตามรูปแบบเดียวกับ node.js หากการ import เริ่มต้นด้วยจุด:
import {Something} from './some/path';
จากนั้นจะถือว่าเป็นเส้นทางเชิงสัมพันธ์จากไฟล์ที่ประกาศการนำเข้า อย่างไรก็ตาม หากเป็นเส้นทางเชิงสมบูรณ์:
import {Component} from 'angular2/core';
จากนั้นจะถูกสมมติว่าเป็นโมดูลภายนอก ดังนั้น Typescript จะเดินขึ้นไปตามโครงสร้างต้นไม้ค้นหาไฟล์ package.json แล้วเข้าไปในโฟลเดอร์ node_modules และหาชื่อโฟลเดอร์ที่เหมือนกับการนำเข้า จากนั้นจะมองหาไฟล์ .d.ts หรือ .ts หลักใน package.json ของโมดูลนั้น แล้วทำการโหลดไฟล์นั้น หรือ จะมองหาไฟล์ที่มีชื่อเดียวกับไฟล์ที่ระบุ หรือ ไฟล์ index.d.ts หรือ index.ts
ว้าว ดูซับซ้อนเมื่อเขียนออกมา และยังมีข้อยกเว้นบางอย่างอยู่... แต่โดยรวมแล้ว ถ้าคุณเคยทำงานกับ node.js มาก่อน นี่ควรทำงานในลักษณะเดียวกันทุกประการ
สิ่งหนึ่งที่ควรสังเกตคือมีตัวเลือกคอมไพเลอร์ TypeScript ที่ควรถูกตั้งค่าเพื่อให้การแก้ไขประเภททำงานในลักษณะนี้
"moduleResolution": "node"
ตอนนี้ ส่วนที่สองของคำถามของคุณคือ วิธีที่สิ่งนี้ถูกโหลดโดยไม่ใช้การเรียก ajax นี่เป็นคุณสมบัติของ System.js แท็กสคริปต์ที่ถูกโหลดในไฟล์ index.html จะนำเข้าชุดไฟล์ซึ่งลงทะเบียนชุดไฟล์ angular2 กับ System เมื่อสิ่งนี้เกิดขึ้น System จะรู้เกี่ยวกับไฟล์เหล่านี้และกำหนดให้กับการอ้างอิงของมันอย่างถูกต้อง นี่เป็นหัวข้อที่ค่อนข้างลึก แต่สามารถหาข้อมูลมากมายได้ทั้งใน README ของ systemjs หรือ systemjs-builder.
