reactjs - ได้รับข้อผิดพลาดเมื่อใช้ FormattedMessage ภายในโมดูล: ข้อผิดพลาด: [React Intl] ไม่สามารถหาวัตถุ `intl` ที่จำเป็นได้
ฉันมีโมโนเรโปที่เปิดเผยโมดูล TypeScript ซึ่งถูกใช้งานและนำไปใช้โดยโครงการ React TypeScript
เมื่อโมดูลแทรกองค์ประกอบ React แบบสุ่มลงใน virtual DOM ทุกอย่างทำงานได้ตามที่คาดไว้ รวมถึงเมื่อฉันพยายามใช้ React Router (ซึ่งในตอนแรกมีปัญหา แต่ฉันสามารถแก้ได้)
อย่างไรก็ตาม เมื่อฉันพยายามใช้ react-intl ผ่าน FormattedMessage ฉันได้รับข้อผิดพลาด:
Error: [React Intl] Could not find required `intl` object. <IntlProvider> needs to exist in the component ancestry.
ซึ่งน่ารำคาญเป็นพิเศษเพราะฉันเห็นสิ่งนี้พิมพ์ในบันทึกคอนโซล:
The above error occurred in the <Context.Consumer> component:
in FormattedMessage
in h2
in div
in Loading (at App.tsx:11)
in IntlProvider (at App.tsx:8)
in App (at src/index.tsx:9)
in StrictMode (at src/index.tsx:8)
(สังเกต IntlProvider ที่ครอบ Loading - ซึ่งเป็นองค์ประกอบที่ใช้ FormattedMessage ซึ่งไม่สามารถหาค่า IntlProvider ได้)
ฉันนึกว่ามันน่าจะเกี่ยวข้องกับการจัดเวอร์ชัน หรือการมีอินสแตนซ์ของ React/React DOM/IntlProvider สองตัว แต่ฉันไม่รู้ว่าจะจัดการเรื่องนี้อย่างไร และฉันใช้เวลาค่อนข้างมากในการลองทุกอย่างที่คิดได้
สำหรับสิ่งที่มันคุ้มค่า นี่คือสิ่งที่ฉันใช้:
- TypeScript - สำหรับทั้งโมดูลและโปรเจกต์
- Webpack เพื่อบรรจุโมดูล ซึ่งฉันประกาศ React, ReactDOM และ react-intl เป็น
externalsและเพิ่มพวกมันเป็นpeerDependenciesแทนที่จะเป็น dependencies โดยตรง create-react-appสำหรับโครงการ
ฉันสามารถสร้างรีโพสิทอรีตัวอย่างขนาดเล็กได้ นี่คือวิธีการที่จะทำให้เกิดปัญหาของฉัน:
<cd somewhere>
git clone https://github.com/chakaz/repro-repo .
cd repro-lib
npm install
npm run build:dev
cd ../project
npm install
npm run start
มีใครพอรู้ไหม? ขอบคุณมากล่วงหน้า!
คำตอบ #1
ด้วยวิธีข้างต้นของคุณเพื่อให้มันใช้งานได้ คุณต้องลบ node_modules ในไดเรกทอรี repro-lib ของคุณเพราะมันจะติดตั้ง dependencies ทั้งในสองไดเรกทอรี
ดังนั้นเพื่อแก้ปัญหาเกี่ยวกับ monorepo ฉันอยากจะแนะนำให้คุณใช้ฟังก์ชัน workspace ของ yarn ตามที่อธิบายอย่างละเอียดที่นี่: https://classic.yarnpkg.com/en/docs/workspaces/
สรุปแล้ว มันเป็นฟังก์ชันที่ยอดเยี่ยมในการช่วยทำงานกับหลายพื้นที่ทำงานได้เพียงแค่ yarn install ครั้งเดียว
นี่คือขั้นตอนบางส่วนในการทำให้รีโปของคุณทำงานได้:
- วาง
package.jsonไว้ที่ระดับรากของโปรเจกต์โดยมีเนื้อหาดังต่อไปนี้:
{
"private": true,
"workspaces": ["project", "repro-lib"]
}
- ไปที่ไดเรกทอรี
projectและแทนที่บรรทัดต่อไปนี้ในpackage.json:
"pf-common": "file:../repro-lib"
ถึง
"pf-common": "1.0.0"
- สุดท้าย กลับไปที่ระดับบนสุดของ root เพื่อติดตั้ง dependencies อีกครั้ง:
yarn install
แค่นี้แหละ! ตอนนี้คุณสามารถรันแอปพลิเคชันของคุณใหม่เพื่อดูว่ามันทำงานอย่างไร
หมายเหตุ: ในเรื่องของความสนใจใน monorepo, lerna ก็เป็นเครื่องมือที่ยอดเยี่ยมที่ช่วยโดยการให้ CLI ที่ยอดเยี่ยม
