วิธีการใช้โมดูล npm จาก typescript


93

ฉันกำลังถ่ายทำที่ typescript ทำงานได้ดีในเวทีโลกสวัสดี ตอนนี้ฉันกำลังพยายามใช้โมดูล npm:

index.ts =

import _ = require('lodash')

console.log(_.toUpper('Hello, world !'))

สิ่งนี้ใช้ไม่ได้:

  • tsc index.ts -> Cannot find module 'lodash'. (2307)
  • node-ts index.js -> Cannot find module 'lodash'. (2307)

การดูเอกสาร typescript และใน Google ไม่ได้ช่วยอะไร คำถาม S / O อื่น ๆ อาจไม่มีคำตอบ ( ที่นี่และที่นี่ ) หรือไม่เกี่ยวข้อง

องค์ประกอบ:

  • typescript 1.8 ล่าสุด
  • ใช่ติดตั้ง lodash แล้ว npm i --save lodashและมีอยู่ในระบบไฟล์ของฉัน (ตรวจสอบ)
  • ฉันก็ทำเช่นกัน typings i --save lodash
  • ตัวแปรimport * as _ from 'lodash'หรือconst _ = require('lodash')ไม่ทำงานอย่างใดอย่างหนึ่ง
  • ฉันลองปรับแต่งตัวเลือก tsconfig.json ตามที่แนะนำในคำตอบอื่น ๆ "moduleResolution": "node"และ"module": "commonjs"ตามที่แนะนำในบางคำตอบก็ยังไม่ได้ผล

เราจะใช้แพ็คเกจ npm ใน typescript ได้อย่างไร ??


2
คุณได้เพิ่มการอ้างอิงถึง lodash.d.ts ใน index.ts ของคุณหรือไม่ ควรมีลักษณะดังนี้: ///<reference path="../typings/lodash/lodash.d.ts"/>
Granga

@Granga มันได้ผล เพิ่มเป็นคำตอบได้ไหม
Offirmo

2
ดีใจที่ได้ผล Blackus ได้เพิ่มคำตอบแล้วและระบุสิ่งที่ฉันแนะนำให้ดียิ่งขึ้น ข้อสังเกตประการหนึ่ง: เมื่อระบุไฟล์อินพุตในบรรทัดคำสั่ง (ซึ่งเป็นกรณีของคุณ) ไฟล์ tsconfig.json จะถูกละเว้น (ที่มา )
Granga

คำตอบ:


63

[แก้ไข] ขอบคุณมากสำหรับคำตอบนี้! อย่างไรก็ตามในปี 2018 มันล้าสมัยไปแล้ว ผู้อ่านลองดูคำตอบอื่น ๆ

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

  • หากคุณมีการพิมพ์และไม่ได้ใช้ a tsconfig.jsonให้ใช้referenceเพื่อนำเข้าการพิมพ์:

    /// <reference path="path/to/typings/typings.d.ts" />
    
    import * as _ from 'lodash`;
    
    console.log(_.toUpper('Hello, world !'))
    
  • หากคุณกำลังใช้tsconfig.jsonไฟล์ตรวจสอบให้แน่ใจว่าได้รวมไฟล์การพิมพ์ของคุณแล้ว (หรือไม่ได้ยกเว้นตามที่คุณเลือก) และดำเนินการให้importเหมือนในตัวอย่างก่อนหน้านี้

ในกรณีที่ไม่มีการพิมพ์ คุณมีสองทางเลือก: เขียนของคุณเองใน.d.tsไฟล์หรือละเว้นการตรวจสอบประเภทสำหรับไลบรารี

หากต้องการละเว้นการตรวจสอบประเภทโดยสิ้นเชิง (นี่ไม่ใช่วิธีที่แนะนำ) ให้นำเข้าไลบรารีโดยใช้ตัวแปรชนิด anyนำเข้าห้องสมุดตามตัวแปรประเภท

 const _: any = require('lodash');

 console.log(_.toUpper('Hello, world !'))

tscจะบ่นว่าrequireไม่มีอยู่จริง ระบุการnodeพิมพ์หรือdeclareเพื่อทิ้งข้อผิดพลาด


2
คำตอบที่สมบูรณ์พร้อม 3 โซลูชั่น +1
Offirmo

นอกจากนี้ยังใช้งานได้ts-nodeตราบเท่าที่มีการอ้างอิงดัชนีการพิมพ์ในtsconfig.json
Offirmo

ฉันสับสนกับความหมายของการ "ประกาศเพื่อยกเลิกข้อผิดพลาด" ฉันจำเป็นต้องทำการเปลี่ยนแปลงนี้ในโมดูลที่ฉันพยายามจะนำเข้าหรือไม่
Slug

1
คำตอบนี้ล้าสมัยอย่างมาก ดูคำตอบใหม่ของฉันด้านล่างstackoverflow.com/a/53786892/587407
Offirmo

53

[2018/12] ใหม่ล่าสุดคำตอบสำหรับคำถามนี้ที่ฉันถามในปี 2016 ซึ่งยังคงแสดงกิจกรรมมากมายแม้ว่าจะมีคำตอบที่ไม่เป็นปัจจุบันก็ตาม

เรื่องสั้นขนาดยาว TypeScript ต้องการข้อมูลประเภทเกี่ยวกับรหัสของแพ็คเกจของคุณ (aka " type declaration files " aka "typings") และบอกคุณอย่างถูกต้องว่ามิฉะนั้นคุณจะสูญเสียจุดทั้งหมดของ TypeScript มีวิธีแก้ปัญหาหลายอย่างที่จะให้หรือเลือกไม่ใช้โดยระบุไว้ที่นี่ตามแนวทางปฏิบัติที่ดีที่สุด:


โซลูชันที่ 0 : โมดูลมีการพิมพ์อยู่แล้ว หาก package.json มีบรรทัดดังนี้:

"typings": "dist/index.d.ts",

มันเปิดใช้งาน TypeScript แล้ว เป็นไปได้มากว่าคุณกำลังอ่านหน้านี้ดังนั้นมาดูกันต่อ ...


โซลูชันที่ 1 : ใช้ชุมชนมีส่วน typings จากDefinitelyTyped สำหรับโมดูล "foo" ให้ลองทำดังนี้

npm add -D @types/foo

ถ้าได้ผลแจ็คพอต! ตอนนี้คุณมีการพิมพ์และสามารถใช้โมดูลของคุณได้แล้ว ถ้า npm บ่นว่าหา module @ types / foo ไม่เจอให้ไปต่อ ...


โซลูชันที่ 2 : ระบุการพิมพ์ที่กำหนดเองเกี่ยวกับโมดูลนี้ (พร้อมตัวเลือกที่จะไม่ต้องออกแรง)

  1. สร้างโฟลเดอร์ชื่อ "typings-custom" ที่รากของโปรเจ็กต์ของคุณ
  2. อ้างอิงเนื้อหาของโฟลเดอร์นี้ใน tsconfig.json ของคุณ:
"include": [
    "./typings-custom/**/*.ts"
]
  1. สร้างไฟล์ที่มีชื่อตรงตามนี้: foo.d.ts [foo = ชื่อของโมดูล] โดยมีเนื้อหา:
declare module 'foo'

ตอนนี้โค้ด TypeScript ของคุณควรคอมไพล์แล้วแม้ว่าจะมีข้อมูลประเภท NO (TypeScript พิจารณาโมดูล foo ประเภท "any")

นอกจากนี้คุณยังสามารถพยายามที่จะเขียนข้อมูลประเภทตัวเองดูที่เอกสารอย่างเป็นทางการและ / หรือตัวอย่างจากDefinitelyTyped หากคุณทำเช่นนั้นให้นึกถึงการพิมพ์ของคุณลงในโมดูลโดยตรง (โซลูชัน 0 หากผู้เขียนโมดูลยอมรับ) หรือใน DefinelyTyped (โซลูชัน 1)


1
@Offirmo เรายังสามารถประกาศการพิมพ์ที่กำหนดเองหลายแบบในไฟล์เดียวได้ ดังนั้นไม่จำเป็นต้องมีไฟล์หลายไฟล์ (อาจจะ?)
lazycipher

ขั้นตอนที่ 2. Reference the content of this folder in your tsconfig.json:แสดงข้อผิดพลาดต่อไปนี้: Unknown compiler option 'include'.
Sumit

1
@ ซูมิทไม่ใช่ตัวเลือกคอมไพเลอร์ควรเป็นพี่น้องของcompilerOptions
Offirmo

24

คุณอาจไม่มีไฟล์การประกาศไฟล์ประกาศ

ดูแน่นอนพิมพ์สำหรับข้อมูลเพิ่มเติม


ลองสิ่งนี้:

npm install --save lodash
npm install --save @types/lodash

ตอนนี้คุณสามารถนำเข้า

import _ from 'lodash';

หากโมดูลที่คุณนำเข้ามีการส่งออกหลายรายการคุณสามารถทำได้:

import { Express, Router } from 'express';

หากโมดูลที่คุณกำลังนำเข้า"ไม่มีการส่งออกเริ่มต้น"คุณต้องดำเนินการดังนี้:

import * as http from 'http';

ทำไมเราถึงต้องใช้* as _และไม่_ from 'lodash'เหมือนกับในรหัส ES6
JohnnyQ

@JohnnyQ จุดดี. การใช้import _ from 'lodash';จะดีกว่าในกรณีนี้ ฉันได้อัปเดตคำตอบเพื่อแสดงวิธีต่างๆในการนำเข้าและเหตุผลที่คุณควรใช้
Derek Soike

1
* as _ เป็นสิ่งจำเป็นถ้าโมดูลมีการส่งออกเริ่มต้นไม่มี คอมไพเลอร์ tsc จะเตือนถึงสิ่งนี้
user2867342

โดย 'ไม่มีการส่งออกเริ่มต้น' หมายความว่าไม่มีการกำหนดประเภท typescript (เช่นการนำเข้าโมดูล JavaScript ธรรมดา) หรือไม่? ฉันเพิ่งเริ่มใช้ JS / typescript ....
Big Rich

2
@BigRich "ไม่มีการส่งออกเริ่มต้น" หมายความว่าโมดูลไม่มีexport default <...>คำสั่ง ลองดูที่ส่วน "การส่งออกเริ่มต้น" ของการที่เอกสาร typescript โมดูล
Derek Soike

5

มันได้ผลสำหรับฉัน

  1. สร้างโฟลเดอร์ชื่อ "typings"
  2. ในโฟลเดอร์ typings สร้างชื่อไฟล์โมดูล name.d.ts ประกอบด้วย:

    declare module "module-name";

  3. ใน tsconfig.json อ้างถึงโฟลเดอร์

    "typeRoots": [ "./typings", "../node_modules/@types" ]


ไฮ! ขอบคุณที่ร่วมให้ข้อมูล วิธีนี้รวมอยู่ในคำตอบของฉันแล้วและควรใช้เป็นทางเลือกสุดท้ายเท่านั้น
Offirmo

ขั้นตอนที่ 3: In tsconfig.json, refer to the folderให้ข้อผิดพลาดต่อไปนี้:Unknown compiler option 'typesRoots'.
Sumit

1
@Sumit ในกรณีของฉัน "typesRoots" อยู่ใน "compilerOptions"
Quynh Ngo

1
เป็น typeRoots ไม่ใช่ typesRoots และควรอยู่ใน compilerOptions
CM

0

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

$npm install @types/<module_name>

ตัวอย่างเช่น

npm install @types/cheerio

แทนที่จะพูด

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