ไม่สามารถนำเข้าไฟล์ svg ใน typescript


139

ในtypescript(*.tsx)ไฟล์ฉันไม่สามารถนำเข้าไฟล์ svg ด้วยคำสั่งนี้:

import logo from './logo.svg';

Transpiler พูดว่า:[ts] cannot find module './logo.svg'. ไฟล์ svg ของฉันเป็นไฟล์<svg>...</svg>.

แต่ใน .jsไฟล์ฉันสามารถนำเข้าได้โดยไม่มีปัญหาใด ๆ กับคำสั่งนำเข้าที่เหมือนกันทุกประการ ฉันคิดว่ามันมีส่วนเกี่ยวข้องกับประเภทของไฟล์ svg ซึ่งต้องตั้งค่าไว้สำหรับ ts Transpiler

คุณช่วยแบ่งปันวิธีทำให้งานนี้เป็นไฟล์ ts ได้ไหม


2
ไฟล์ svg ไม่ใช่ javascript และไม่สามารถใช้เป็นโมดูลจาวาสคริปต์ได้ คุณควรโหลดไฟล์เหล่านั้นโดยใช้คำขอ http แทน
toskv

2
คุณใช้ Webpack หรือไม่? นั่นเป็นสิ่งเดียวที่ฉันเห็นว่าเข้าใจimportคำพูดดังกล่าว บางที Webpack อาจเป็นสิ่งที่อนุญาตใน JavaScript ของคุณ แต่มันไม่ได้ทำเวทมนตร์แบบเดียวกันในไฟล์ TypeScript (ฉันไม่คิดว่า TypeScript เองก็รู้ว่าต้องทำอะไรที่นี่)
user94559

1
หากคุณใช้ Webpack คุณอาจต้องแชร์การกำหนดค่า Webpack เพื่อรับความช่วยเหลือเพิ่มเติม
user94559

2
อ่านเพิ่มเติมเกี่ยวกับเรื่องนี้คุณสามารถทำได้const logo = require("./logo.svg");หรือเพียงแค่เพิกเฉยต่อข้อผิดพลาด (ฉันเชื่อว่า TS ควรยังคงส่งออกรหัสที่ถูกต้องอยู่)
user94559

1
ทำไม Webpack / React จึงต้องซับซ้อน มันจะง่ายกว่าไหมที่จะนำเข้าอะไรก็ได้ด้วยimport. สำหรับมือใหม่อย่างฉันสิ่งเหล่านี้ทำให้ฉันท้อใจ ในปี 2020 ที่ "การกำหนดค่าอัตโนมัติ" ควรเป็นบรรทัดฐานไม่ใช่หรือ
SimpleGuy

คำตอบ:


223

หากคุณใช้ webpack คุณสามารถทำได้โดยสร้างไฟล์ประเภทที่กำหนดเอง

สร้างไฟล์ชื่อcustom.d.tsโดยมีเนื้อหาต่อไปนี้:

declare module "*.svg" {
  const content: any;
  export default content;
}

เพิ่มcustom.d.tsไปtsconfig.jsonด้านล่าง

"include": ["src/components", "src/custom.d.ts"]

ที่มา: https://webpack.js.org/guides/typescript/#importing-other-assets


39
มีแนวโน้มที่คุณจะต้องเพิ่มไปยังincludeส่วนในtsconfig.json
Frederik Krautwald

12
ขอบคุณ! ฉันรู้ว่ามันต้องรวมอยู่ที่ไหนสักแห่ง แต่ฉันนึกภาพไม่ออก แม้ฉันคิดว่ามันอยู่ใน tsconfig.json แต่ฉันไม่รู้วิธีทำ ขอบคุณความคิดเห็นของคุณ ฉันค้นหาและพบ:"files": [ "custom.d.ts" ]
Shil Nevado

6
คุณสามารถตรวจสอบประเภทของคอมโพเนนต์ JSX ได้โดยพิมพ์เนื้อหา:const content: React.FunctionComponent<React.SVGAttributes<SVGElement>>;
RedMatt

1
เป็นไปได้ไหมที่จะให้custom.d.tsไฟล์ทำงานทั่วโลกเพื่อให้ SVG อยู่ในไดเร็กทอรีอื่นที่ไม่ใช่custom.d.tsไฟล์ ฉันได้รับข้อผิดพลาด "ไม่พบโมดูล" เว้นแต่จะอยู่ในไดเร็กทอรีเดียวกัน
Nic Scozzaro

1
สิ่งนี้ไม่ได้นำเข้าเนื้อหาของไฟล์ใน Angular แต่จะนำเข้าชื่อไฟล์เป็นสตริง ฉันต้องการเนื้อหา เราจะรับเนื้อหาของไฟล์ได้อย่างไร?
Routhinator

41

ขอบคุณsmarxrequire()สำหรับการชี้ออกมาใช้ ดังนั้นในกรณีของฉันควรเป็น:

const logo = require("./logo.svg") as string;

ซึ่งทำงานได้ดีในไฟล์ * .tsx


7
logoอาจจะดีกว่าlogoPathเพราะนั่นคือสิ่งที่มันกลายเป็น
DharmaTurtle

2
@DharmaTurtle ฉันคิดว่าสามารถถกเถียงกันได้ นอกจากนี้ยังเรียกว่าlogoในคำถามดังนั้นจึงเป็นคำตอบที่ดีกว่าสำหรับคำถามเฉพาะนี้ตามที่เป็นอยู่
ArneHugo

@DharmaTurtle เพื่อนตรงไปตรงมาชื่อของตัวแปรนั้นอยู่นอกเหนือประเด็นทำไมถึงฟุ้งซ่านเรื่องเล็กน้อยเช่นนี้?
ELI7VH

ฉันชอบคำตอบนี้มากกว่าการสร้างกฎการกำหนดค่าที่กำหนดเอง คำถามเดียวคือสิ่งนี้ทำงานได้ดีเพียงใดในโครงสร้างการผลิตหากมีผลข้างเคียงใด ๆ เลย?
Munib

มีปัญหาในการทำงานนี้โปรดชี้แจง? stackoverflow.com/questions/65205211/…
Bondolin

19

เพิ่มcustom.d.tsไฟล์ (ฉันสร้างมันบนเส้นทางรูทของ src dir ของฉัน) ด้วยประเภทที่ถูกต้อง (ขอบคุณRedMatt ):

declare module '*.svg' {
  const content: React.FunctionComponent<React.SVGAttributes<SVGElement>>;
  export default content;
}

ติดตั้งsvg-react-loaderหรืออื่น ๆจากนั้น:

  • ใช้เป็นตัวโหลด svg หลัก
  • หรือหากคุณกำลังย้ายโค้ดเบสและไม่ต้องการสัมผัสส่วนการทำงาน (JS) ให้ระบุตัวโหลดในการนำเข้า:
import MySVG from '-!svg-react-loader!src/assets/images/name.svg'

จากนั้นใช้เป็นแท็ก JSX:

function f() { 
  return (<MySVG />); 
}

7

วิธีแก้ปัญหาที่ฉันพบ: ในโครงการ ReactJS ในไฟล์ react-app-env.d.ts คุณเพิ่งลบช่องว่างในความคิดเห็นเช่น:

ก่อน

// / <reference types="react-scripts" />

หลังจาก

/// <reference types="react-scripts" />

ฉันหวังว่าจะช่วยคุณ


สำหรับผู้ที่ใช้ create-react-app และ eslint ที่กำหนดค่าไว้สิ่งนี้อาจช่วยแก้ปัญหาได้
Daniel Chin

ฉันไม่พบคำอธิบายใด ๆ สำหรับเรื่องนี้ แต่ในกรณีของฉันดูเหมือนจะใช้ได้ ความคิดใด ๆ ทำไม?
Stamatis Deliyannis

4

ฉันมีปัญหาเดียวกันขณะลองใช้บทช่วยสอน REACT + typescript
สิ่งที่ได้ผลสำหรับฉันคือคำสั่งนำเข้าต่อไปนี้

import * as logo from 'logo.svg'

นี่คือการอ้างอิงของฉันใน package.json

  "dependencies": {
    "react": "^16.8.4",
    "react-dom": "^16.8.4",
    "react-scripts-ts": "3.1.0"
  },

หวังว่ามันจะช่วยใครบางคน


2

มีทางเลือกอื่นในการดำเนินการนี้ซึ่งเราได้นำไปใช้: สร้างส่วนประกอบ SVG ของคุณ ฉันทำสิ่งนี้เพราะมันทำให้ฉันสับสนว่าฉันใช้requireคำสั่งcommonJS ควบคู่ไปกับimports ของฉัน


2

หากต้องการใช้ n สินทรัพย์ในรหัสกับ typescriptเราต้องเลื่อนประเภทสำหรับเหล่านี้นำเข้า สิ่งนี้ต้องการไฟล์custom.d.tsซึ่งหมายถึงข้อกำหนดที่กำหนดเองสำหรับ TypeScript ในโครงการของเรา

มาตั้งค่าการประกาศสำหรับไฟล์. svg:

กำหนดเอง d.ts

declare module "*.svg" {
  const content: any;
  export default content;
}

ที่นี่เราประกาศโมดูลใหม่สำหรับ SVG โดยระบุการนำเข้าใด ๆ ที่ลงท้ายด้วย. svg และกำหนดเนื้อหาของโมดูลเป็นอย่างใดอย่างหนึ่ง


0
    // eslint-disable-next-line spaced-comment
/// <reference types="react-scripts" />

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

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