จะหลีกเลี่ยงการนำเข้าด้วยเส้นทางสัมพัทธ์ที่ยาวมากใน Angular 2 ได้อย่างไร


คำตอบ:


140

TypeScript 2.0+

ใน TypeScript 2.0 คุณสามารถเพิ่มbaseUrlคุณสมบัติในtsconfig.json:

{
    "compilerOptions": {
        "baseUrl": "."
        // etc...
    },
    // etc...
}

จากนั้นคุณสามารถนำเข้าทุกอย่างราวกับว่าคุณอยู่ในไดเร็กทอรีฐาน:

import {XyService} from "services/validation/xy.service";

นอกจากนี้คุณสามารถเพิ่มpathsคุณสมบัติซึ่งช่วยให้คุณจับคู่รูปแบบแล้วแมปออกมาได้ ตัวอย่างเช่น:

{
    "compilerOptions": {
        "baseUrl": ".",
        "paths": {
            "services/*": [
                "services/validation/*"
            ]
        }
        // etc...
    },
    // etc...
}

ซึ่งจะช่วยให้คุณสามารถนำเข้าได้จากทุกที่ดังนี้:

import {XyService} from "services/xy.service";

จากนั้นคุณจะต้องกำหนดค่าตัวโหลดโมดูลที่คุณใช้เพื่อรองรับชื่อนำเข้าเหล่านี้ด้วย ตอนนี้คอมไพเลอร์ TypeScript ดูเหมือนจะไม่ได้แมปสิ่งเหล่านี้โดยอัตโนมัติ

คุณสามารถอ่านเพิ่มเติมเกี่ยวกับเรื่องนี้ในปัญหา GitHub นอกจากนี้ยังมีrootDirsคุณสมบัติที่เป็นประโยชน์เมื่อใช้หลายโครงการ

Pre TypeScript 2.0 (ยังใช้ได้กับ TS 2.0+)

ฉันได้พบมันสามารถทำได้ง่ายขึ้นโดยใช้"ถัง"

  1. สร้างindex.tsไฟล์ในแต่ละโฟลเดอร์
  2. ในไฟล์เหล่านี้ให้ส่งออกไฟล์แต่ละไฟล์ภายในโฟลเดอร์อีกครั้ง

ตัวอย่าง

ในกรณีของคุณก่อนอื่นให้สร้างไฟล์ชื่อmy-app-name/services/validation/index.ts. ในไฟล์นี้มีรหัส:

export * from "./xy.service";

จากนั้นสร้างไฟล์ที่เรียกว่าmy-app-name/services/index.tsและมีรหัสนี้:

export * from "./validation";

ตอนนี้คุณสามารถใช้บริการของคุณได้แล้ว ( indexโดยนัย):

import {XyService} from "../../../services";

และเมื่อคุณมีไฟล์หลายไฟล์แล้วมันจะง่ายยิ่งขึ้น:

import {XyService, MyOtherService, MyOtherSerivce2} from "../../../services";

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

ข้อควรระวัง

เมื่อทำสิ่งนี้มีบางสิ่งที่คุณต้องระวังและไม่สามารถทำได้:

  1. คุณต้องเฝ้าระวังการส่งออกซ้ำ ดังนั้นหากไฟล์ในสองโฟลเดอร์ย่อยอ้างอิงถึงกันคุณจะต้องใช้เส้นทางแบบเต็ม
  2. คุณไม่ควรย้อนกลับโฟลเดอร์จากโฟลเดอร์เดิมเดิม (เช่นอยู่ในไฟล์ในโฟลเดอร์ตรวจสอบความถูกต้องและกำลังดำเนินการimport {XyService} from "../validation";) ฉันพบสิ่งนี้แล้วและจุดแรกอาจนำไปสู่ข้อผิดพลาดของการนำเข้าที่ไม่ได้กำหนดไว้
  3. สุดท้ายคุณไม่สามารถส่งออกสองรายการในโฟลเดอร์ย่อยที่มีชื่อเดียวกันได้ โดยปกตินั่นไม่ใช่ปัญหา

2
@ ThomasZuberbühlerฉันคิดว่าใน TypeScript 1.8 จะพร้อมใช้งาน ( ดูที่นี่ )
David Sherret

3
ฉันจะดาวน์โหลด typescript 2.0+ ด้วย npm ได้อย่างไร
maximedupre

4
เคล็ดลับเล็ก ๆ น้อย ๆ - หลังจากอ่านเอกสารปรากฎว่าข้อมูลbaseUrlนั้นสัมพันธ์กับตำแหน่งของ 'tsconfig.json' ดังนั้นในกรณีของเรา (แอปพลิเคชันเชิงมุม) ค่าจะต้องเป็น"baseUrl": "./app",โดยที่ "แอป" เป็นรากของแอปพลิเคชัน
Pawel Gorczynski

10
ผู้ใช้ angular-cli เท่านั้น : หากคุณใช้ angular-cli 2+ พวกเขาจะเปลี่ยนไปใช้ webpack และ webpack.config.js แบบ blackbox (ภายใน node_modules) "จากนั้นคุณจะต้องกำหนดค่าตัวโหลดโมดูลใด ๆ ที่คุณใช้เพื่อรองรับชื่อการนำเข้าเหล่านี้ด้วย" เนื่องจาก webpack.config.js เป็น blackboxed คุณจึงไม่สามารถทำส่วนนี้ได้ โชคดีที่ผมพบว่าปัญหาได้รับการรายงานแล้วที่นี่และแก้ไขได้โดยการนี้การประชาสัมพันธ์ TL; DRการกำหนดค่า webpack blackboxed นั้นฉลาดพอที่จะดู tsconfig.json ได้แล้ว
Kevin

1
สำหรับผู้ใช้ angular-cli คุณสามารถสร้าง webpack.config ด้วย "ng eject" โปรดทราบว่าคุณจะต้องลบ ejected: true ออกจากโปรเจ็กต์ .angular-cli.json -> เพื่อให้สามารถให้บริการโปรเจ็กต์ได้
Drusantia

14

ดีกว่าที่จะใช้การกำหนดค่าด้านล่างใน tsconfig.json

{
  "compilerOptions": {
    "...": "reduced for brevity",

    "baseUrl": "src",
    "paths": {
      "@app/*": ["app/*"]
    }
  }
}

วิธีดั้งเดิมก่อน Angular 6:

`import {XyService} from '../../../services/validation/xy.service';`

ควรปรับโครงสร้างใหม่เป็น:

import {XyService} from '@app/services/validation/xy.service

สั้นและหวาน!


การเปลี่ยนแปลงนี้ใช้ไม่ได้ในการผลิต @shivangGupta
ไม่ระบุชื่อ

1

ฉันเพิ่งเจอคำถามนี้ ฉันรู้ว่าตอนนี้มันกลับมาแล้ว แต่สำหรับใครก็ตามที่เจอมันมีคำตอบที่ง่ายกว่านี้

ฉันเจอเพียงเพราะบางสิ่งที่ฉันทำมานานหยุดทำงานและฉันสงสัยว่ามีอะไรเปลี่ยนแปลงใน Angular 7 ไม่มันเป็นแค่รหัสของฉันเอง

ไม่ว่าฉันจะต้องเปลี่ยนเพียงบรรทัดเดียวtsconfig.jsonเพื่อหลีกเลี่ยงเส้นทางการนำเข้าที่ยาว

{
  "compilerOptions": {
  "...": "simplified for brevity",

   "baseUrl": "src"
  }
}

ตัวอย่าง:

// before:
import {XyService} from '../../../services/validation/xy.service';

// after:
import { XyService } from 'app/services/validation/xy.service';

สิ่งนี้ใช้ได้ผลกับฉันมากนับตั้งแต่ Angular-CLI เข้ามา


ขอบคุณสำหรับความพยายามของ Chris แต่คุณควรมีตัวอย่างการใช้งานไว้ในคำตอบของคุณ!
George43g
โดยการใช้ไซต์ของเรา หมายความว่าคุณได้อ่านและทำความเข้าใจนโยบายคุกกี้และนโยบายความเป็นส่วนตัวของเราแล้ว
Licensed under cc by-sa 3.0 with attribution required.