วิธีการ Deploy React กรณีใช้ subfolder บน Server

Chai Phonbopit

Software Engineer & Blogger

20 April 2020

In

พอดีว่าได้มีโอกาสได้ทำ Single Page Application ด้วย React ของเว็บๆ นึง และที่นี้ปัญหาคือ เวลาเราไป Deploy เราต้องเอา SPA ของเราเนี่ย ไปเชื่อมต่อกับ Web ที่เค้ามีอยู่แล้ว โดยวางเป็น subfolder อีกทีนึง

เช่น เว็บ https://example.com เป็น domain ปกติ เราก็จะอยู่ภายใน https://example.com/myapp ไรงี้

โดยปกติแล้ว เวลาเราทำ React เวลาที่เรา build ตัว static หรือ assets ไฟล์ต่างๆ มันจะอ้างอิงตาม domain ของเรา เช่น /static/style.css แต่ทีนี้ ถ้าเราไป deploy ลง subfolder ซึ่ง path ที่ไฟล์เรามันอยู่คือ https://example.com/myapp/static/style.css ก็เลยทำให้ มันหาไฟล์ใน server ไม่เจอนั่นเอง เพราะ ตัว index.html ที่มัน build เสร็จแล้ว เราไม่ได้ตั้งค่าให้ นั่นเอง

ก็เลยเขียนเป็นสรุปไว้ เผื่ออนาคต หรือตัวเองอยากแก้ปัญหาแบบเร็วๆ จะได้กลับมาอ่าน ซึ่งมี 3 เวอร์ชั่นคือ

  • Create React App
  • Gatsby.js
  • Next.js

วิธีแก้ไม่ยากครับ

Create React App

สำหรับ Create React App โดยปกติแล้ว มันจะทำการ build โดยใช้ server root แบบ relative path ดังที่กล่าวไปตอนต้น ทีนี้ถ้าเราจะให้มัน deploy ไป subfolder เราก็ต้องไปตั้ง homepage ใน package.json ครับ เช่น

{
"homepage": "/myapp"
}

เพียงแค่นี้มันก็จะ link ไปที่ static / assets ที่เรา build ได้ถูกแล้ว

ต่อมา ถ้าใครใช้พวก React Router ก็จะมีปัญหาพวก Link ใช่มั้ย วิธีแก้ปัญหา ก็ไม่ยาก ตรงส่วน BrowserRouter เราใส่ basename ให้มันได้ เช่น

<BrowserRouter basename="/myapp" />

อ่านเพิ่มเติมได้ที่นี่ https://create-react-app.dev/docs/deployment

Gatsby.js

ตัว Gatsby.js เราก็ทำได้เช่น และ Gatsby เราจะเป็น Static Web บางครั้ง เราอยาก deploy ไว้ที่ subfolder และ url เช่น https://example.com/blog เราสามารถใช้ pathPrefix ได้ครับ

โดยแก้ไขไฟล์ gatsby-config.js

module.exports = {
pathPrefix: '/blog'
}

และเวลา Build ก็กำหนด option ให้มันซะ

gatsby build --prefix-paths

อ่านเพิ่มเติมได้ที่นี่ https://www.gatsbyjs.org/docs/path-prefix/

Next.js

ส่วน Next.js ผมได้ลองเอา Project ไป Deploy โดย build เป็น export html ครับ สิ่งที่ path ผิดคือ พวก assets เช่นกัน วิธีแก้ ก็คือ ที่ไฟล์ next.config.js

module.exports = {
assetPrefix: '/myapp'
};

ทีนี้เวลา build พวกไฟล์ assets ที่อยู่ใน static มันก็จะมี prefix และก็ link กันได้ถูกต้อง เพราะว่าเรา deploy ไป subfolder / subpath นั่นเอง

อ่านเพิ่มเติม : https://nextjs.org/docs/api-reference/next.config.js/cdn-support-with-asset-prefix


สรุป ก็บทความนี้จริงๆ แล้วไม่มีอะไรมาก โดยปกติเราจะ Deploy SPA ไว้ที่ root อยู่แล้ว แต่ถ้าเกิดว่ากรณีที่เราอยาก deploy ที่ไม่ใช่ root แต่เป็น subpath/subfolder แล้วมีปัญหา link assets ไม่ถูกต้อง ก็แก้ด้วยการ config ตามด้านบนเลยครับ

นอกจากพวก Assets แล้ว ที่ต้องใส่ prefix การทำ Single Page Application ที่ต้องเชื่อมกับ Server ที่มีอยู่แล้ว บางครั้งเราต้องทำการ Fallback ไปที่ index.html ของ SPA เพื่อให้มันจัดการ Routing ผ่าน Client ด้วยนะครับ ไม่งั้น หากเราทำ SPA แต่ลืมทำพวก Client Router มันก็จะ Request ไม่เจอนั่นเอง

สวัสดี

Happy Coding

  • #React
  • #React.js
  • #Gatsby
  • #Gatsby.js
  • #Next.js
  • #Nextjs
  • #React Subfolder