Webpack → Vite: การย้ายตัวบันเดลเลอร์ของ Storybook
(medium.com/@hong009319)ได้ย้ายตัวบันเดลเลอร์ของ Storybook จาก Webpack ไปเป็น Vite ในกระบวนการนี้เกิดปัญหาหลายอย่างต่อเนื่องกัน จนสุดท้ายจำเป็นต้องเปลี่ยนเทคโนโลยีสแตกเดิม
การเปลี่ยนเทคโนโลยีสแตก
• [เทคโนโลยีสแตกเดิม] Storybook v6.5, builder-webpack5, Node v18, Yarn 1
• [เทคโนโลยีสแตกสุดท้าย] Storybook v7, react-vite, Node v18, Pnpm
ปัญหาที่เกิดขึ้นระหว่างการย้าย
1. ปัญหาความเข้ากันได้ระหว่าง Webpack 4 กับ OpenSSL 3
-
คำอธิบายปัญหา
- ระหว่างกระบวนการย้ายจาก builder-webpack5 ไปเป็น builder-vite เกิดปัญหาความเข้ากันได้ของเวอร์ชัน OpenSSL
- Webpack เวอร์ชันต่ำกว่า 5.61.0 ใช้ OpenSSL เวอร์ชันเก่า และหลังจากนั้นใช้ OpenSSL 3
- Storybook v6 ใช้ Webpack 4 เป็นบิลเดอร์เริ่มต้น และมี Webpack 5 ให้เลือกใช้งานแบบออปชัน
- ตอนนั้นได้เลือกใช้ Webpack 5 และใช้ builder-webpack5 ที่ใช้ Webpack ^5.9.0 จึงไม่เกิด OpenSSL error
- แม้ builder-vite ที่ย้ายมาแล้วจะใช้ Vite ในการ build แต่ Storybook v6 ยังใช้ Webpack 4 เป็นบิลเดอร์เริ่มต้นภายใน จึงเกิดปัญหาความเข้ากันได้ของเวอร์ชัน OpenSSL
-
วิธีแก้ไข: ย้ายไปใช้ Storybook v7
- ใน Storybook v7 เมื่อใช้ Vite แล้ว Storybook ภายในจะไม่ใช้ Webpack 4 จึงไม่เกิด OpenSSL error
2. การใช้ dependency คนละเวอร์ชันเนื่องจากการ hoisting ของ Yarn 1
-
คำอธิบายปัญหา
- ในแพ็กเกจ @isaacs/cliui มีการใช้ string-width@5 ในรูปแบบ ESM และ string-width@4 ในรูปแบบ CommonJS(CJS) โดยใช้นามแฝง string-width-cjs
- Yarn 1 จะ hoist แพ็กเกจ dependency ที่ซ้ำกันขึ้นไปยัง root node_modules ทำให้แพ็กเกจสามารถเข้าถึง dependency ที่ไม่ได้ติดตั้งไว้เองได้
- เนื่องจาก string-width@4 และ @5 เป็น sub-dependency ที่หลายแพ็กเกจใช้ซ้ำกัน จึงถูก hoist ไปยัง root node_modules
- ในบรรดาแพ็กเกจ string-width นั้น cli-table3 ซึ่งเป็นรูปแบบ CJS พยายามเข้าถึง string-width@4 แต่เนื่องจาก alias ทำให้ไม่มีเวอร์ชันเดียวกันอยู่ จึง resolve ไปยัง string-width@5 แบบ ESM และเกิดปัญหาความเข้ากันได้ของโมดูล
-
วิธีแก้ไข: เปลี่ยน package manager เป็น pnpm ซึ่งไม่ทำให้เกิด phantom dependency
1 ความคิดเห็น
คำถาม มีเหตุผลอะไรหรือเปล่าที่ไม่ได้ใช้
esbuild-loaderบน webpack?คำตอบ
เราใช้ Vite เพื่อใช้ความสามารถของ Native ESM
เท่าที่ทราบ
esbuild-loaderเป็น loader ที่ทำให้สามารถใช้ esbuild บน Webpack ได้ แต่ถึงแม้จะใช้esbuild-loaderแล้วทำให้ความเร็วในการ build เร็วขึ้นมาก ก็ยังคงต้องผ่านกระบวนการ bundling อยู่ดีในทางกลับกัน หากใช้ Native ESM จะ build เฉพาะโมดูลที่ใช้งานแล้วส่งไปยังเบราว์เซอร์ และเมื่อมีการเปลี่ยนแปลงโมดูล ก็จะ build เฉพาะโมดูลที่เปลี่ยนแปลง จึงเร็วกว่า
ในกรณีอย่าง Storybook ที่มีการร้องขอเฉพาะบางคอมโพเนนต์ เราจึงเห็นว่าการใช้ Native ESM เหมาะกว่า และเลือกใช้ Vite