[React] Folder Structure ออกแบบโครงสร้าง React Application ยังไงให้ใช้งานง่าย
React คือ “JavaScript library for building user interfaces” ซึ่งเป็น JavaScript library ที่นิยมใช้งานกันอย่างมากสำหรับการสร้างเว็บไซต์ เนื่องจากหลาย ๆ เหตุผลไม่ว่าจะเป็น virtual DOM หรือ reusable component
การใช้งาน React นั้นมีทั้งหมด 2 วิธี คือ ใช้ CDN ซึ่งจะต้องทำการ config เองทั้งหมด ทำให้เกิดความลำบากกับผู้ใช้งานเป็นอย่างมาก จึงมีวิธีที่สอง คือ create-react-app ที่เรานิยมใช้งานกัน เพราะเป็นคำสั่งในการสร้าง React Application ขึ้นมาแบบ zero configuration หรือไม่ต้อง config อะไรเลย เราสามารถเขียนโปรแกรมได้ทันที สะดวกมาก ๆ ครับ
เมื่อเราใช้คำสั่ง create-react-app เพื่อสร้าง React Application ขึ้นมา เราก็จะพบกับ folder ต่าง ๆ มากมายจนไม่รู้จะเริ่มจากตรงไหนดี แน่นอนว่าเราจะต้องรู้จักความหมายของ folder ต่าง ๆ ก่อนที่จะเริ่มเขียนโปรแกรม เพราะฉะนั้นมาลองดูความหมายกับสิ่งที่อยู่ใน folder ต่าง ๆ กันเลยครับ
node_modules
folder สำหรับเก็บ dependency หรือจะเรียกว่า library/package ก็ได้ ซึ่งข้างในจะมี folder อื่น ๆ อีกมากมาย เวลาที่เราเขียนโปรแกรมแล้วจะใช้งาน library หรือ package เราก็ต้อง import มาจาก folder นี้ครับ เช่น
- ถ้าจะใช้งาน react ก็ต้อง
import react from ‘react';
ซึ่ง react ที่เรา import มาก็จะมาจาก node_modules นั่นเองครับ - ถ้าเราจะใช้ third-party library ที่เราดาวน์โหลดมาจากที่อื่น ก็ต้องติดตั้งด้วยคำสั่งพวก npm หรือ yarn หลังจากติดตั้งแล้ว library นั้นก็จะมาอยู่ใน node_modules ให้เรา import ใช้งานครับ
public
folder สำหรับเก็บ index.html และ assets พวก icon หรือภาพได้ ผมแนะนำให้ folder public นี้ใช้เฉพาะการปรับ index.html เช่น เพิ่ม fonts และ icon ของ website ไม่ควรจะใช้ในการเก็บภาพที่ใช้ใน project ครับ โดยเริ่มต้น create-react-app จะให้ไฟล์มาดังนี้
- favicon.ico — icon สำหรับใช้ใน website ซึ่งเป็นภาพ icon ตอนเราเปิดแถบบน web browser (หน้า title ของเว็บไซต์)
- index.html — เนื่องจาก React นิยมใช้สร้าง single page application จึงให้ html มาหนึ่งไฟล์ ซึ่งเราสามารถใช้แค่ html ไฟล์เดียวได้ โดยเราสามารถเขียน code เพิ่ม font หรือ icon ในไฟล์นี้ได้ครับ
- logo192.png กับ logo512.png — logo ที่ react ให้มาโดยมีขนาดต่างกันเพื่อปรับให้เหมาะกับ device
- manifest.json — เป็นไฟล์ที่เก็บ metadata เพื่อบอกว่าเว็บไซต์ของเรามีลักษณะอย่างไร เช่น name (ชื่อเว็บไซต์), start_url (เปิดเว็บแล้วเริ่มที่ url ไหน), icons (icon ของเว็บที่มีหลายขนาด เพื่อปรับให้หมาะกับ device ซึ่งจะมี favicon.ico, logo192.png และ logo512.png อยู่เป็น default)
- robots.txt — ไฟล์ที่บอกให้ search engine มาเก็บข้อมูลในเว็บของเรา โดยปกติแล้วจะเก็บทุกส่วนของเว็บไซต์ แต่เราสามารถกำหนดได้ว่าจะไม่ให้เขาเก็บข้อมูลตรงส่วนไหนบ้าง (สำคัญสำหรับการทำ SEO)
src
เป็น folder หลักที่เราจะใช้เขียนโปรแกรมกันครับ ซึ่งหลัก ๆ จะเก็บไฟล์ JavaScript, CSS และ image มาดูกันครับว่าเขาให้ไฟล์อะไรมาบ้าง
- App.css กับ index.css — ปกติแล้วเราจะลบไฟล์ App.css ออก แล้วใช้เฉพาะ index.css ครับ เพราะทั้งคู่มีความสามารถเหมือนกัน โดยจะใช้ index.css ในการตกแต่งสิ่งที่ทุก component ใช้เหมือนกัน เช่น
box-sizing: border-box;
หรือปรับ font - App.js — เป็นไฟล์หลักที่เราจะใช้รวม component ทั้งหมด
- index.js — ไฟล์ที่จะนำ App component จาก App.js ไป render ซึ่งปกติแล้วเราจะไม่ยุ่งกับ index.js
- App.test.js — เป็นไฟล์ทำ Unit test สำหรับ App.js
- logo.svg — ใช้แสดง logo ของ React ที่เราเห็นตอน npm start ครั้งแรก
- reportWebVitals.js — report ค่ามาตรฐานของประสิทธิภาพด้าน UX ของเว็บไซต์ โดยมาจาก page speed insights
- setupTests.js — ใช้ในการทำ test ใน app
.gitignore
ใช้สำหรับเวลาที่เราใช้งาน Git ใน React Project แล้วต้องการจะใช้งาน git commit ตัวของ Git จะไม่ commit ไฟล์หรือโฟลเดอร์ ที่เราระบุใน .gitignore ซึ่งถ้าเราลองเปิดเข้าไปดูจะพบว่ามี node_modules อยู่ในนั้นด้วย แสดงว่า Git จะไม่เก็บ folder นี้ไว้ใน repository เมื่อเรา commit ครับ
package.json
เป็นไฟล์ประเภท JSON ที่บอกข้อมูลต่าง ๆ ของ project ที่ใช้ node package manager โดยบอกถึง dependencies, version ของ dependencies และอื่น ๆ ที่ใช้ใน React app
ทำไมถึงต้องมี package.json — เวลาที่เราทำงานกับร่วมกับคนในทีม เขาอาจจะไม่รู้ว่าเราใช้ dependencies ตัวไหนบ้าง ถึงแม้จะทราบ แต่ก็อาจจะไม่ทราบ version ของ dependencies ที่เราใช้ เราจึงต้องมี package.json ไว้บอกข้อมูลว่าเราใช้อะไรบ้าง เวลาที่เราส่งต่องานก็ไม่จำเป็นต้องส่ง node_module ไปด้วย เพราะมีขนาดไฟล์ใหญ่มาก เราแค่ส่ง source code กับ package.json ไปให้เขา
จากนั้นคนที่รับ code กับ package.json ของเรา ก็ใช้เพียงแค่คำสั่ง npm install
ซึ่งคำสั่งนี้จะทำให้ terminal ไปดูที่ package.json ว่ามี dependencies อะไรบ้าง แล้วติดตั้ง dependencies ทุกอย่างเหมือนกับของเราเลยครับ เพียงเท่านี้ก็ได้ node_module เหมือนกับของเรา แล้วใช้งานได้ project ของเราได้ตามปกติแล้วครับ
README.md
เป็นไฟล์ประเภท markdown ที่ใช้อธิบายเกี่ยวกับ create-react-app ว่าใช้งานยังไง โดยจะอธิบาย 4 คำสั่งที่สำคัญ
- yarn start — run app in the development mode คือ ใช้เวลาที่เราอยู่ในขั้นตอนการพัฒนา เขียน code เสร็จส่วนหนึ่งแล้วอยากจะให้แสดงผลบนเว็บไซต์ดูว่ามีลักษณะเป็นอย่างไร มี error เกิดขึ้นไหม เขียน CSS ถูกต้องหรือเปล่า เป็นต้น
- yarn test — launch the test runner in the interactive watch mode เป็นการใช้คำสั่งเพื่อ test app ของเราตาม test ที่เราเขียน
- yarn build — builds the app for production to the ‘build’ folder คือเมื่อเราพอใจกับ app ที่เราเขียนโปรแกรมเสร็จเรียบร้อย แล้วอยากจะส่ง app ขึ้น production ให้ผู้ใช้ได้ใช้งาน website ของเราจริง ๆ ก็จะใช้คำสั่งนี้ครับ ซึ่ง React จะทำ bundle และ optimize app ของเราให้มี performance ที่ดีที่สุด โดยผลลัพธ์ที่ออกมาจะมีขนาดไฟล์น้อยมาก เมื่อเทียบกับตอนเรา develop อยู่
- yarn eject — กรณีที่เราไม่พอใจกับ config ของ create-react-app ที่เขาให้มา เราอยากจะได้ full control ใน app ของเรา ให้สามารถ config ได้ทุกอย่าง ก็สามารถใช้คำสั่งนี้ได้ แต่ผมไม่แนะนำถ้าไม่จำเป็นต้อง config จริง ๆ เพราะถ้าเราใช้คำสั่งนี้แล้ว เวลาที่เราใช้ yarn start หรือ npm start จะเกิด error ขึ้น เพราะหา path ไม่เจอ เพราะฉะนั้นไม่ควรใช้คำสั่งนี้ถ้าไม่จำเป็นจริง ๆ ครับ
yarn.lock
เป็นไฟล์ที่ใช้ lock version ของ dependencies สำหรับคนที่ต้องการใช้ yarn แทน npm เพื่อบอกให้ใช้ version นี้ทุกครั้ง เวลาที่เราส่งมอบให้ team อื่นทำต่อ ทำให้ไม่เกิดปัญหา version ของ dependencies ไม่ตรงกันครับ
บางคนอาจจะเคยเห็นไฟล์ชื่อ package-lock.json อันนี้ก็เหมือนกับ yarn.lock เลยครับ เพียงแต่ใช้สำหรับ npm เพราะฉะนั้นถ้ามีทั้ง yarn.lock กับ package-lock.json ใน project ก็หมายความว่าเราสามารถใช้ได้ทั้ง yarn และ npm เลยครับ
แนวทางในการจัด Folder Structure
ใน src folder ผมแนะนำให้สร้าง folder ประมาณนี้นะครับ
- assets — เก็บรูปภาพและ font (กรณีที่เราดาวน์โหลด font มาใช้แบบไม่ใช้ CDN)
- components — เก็บ component ที่ไม่มีการใช้ state โดย folder ข้างใน 1 folder จะเก็บ 1 component โดยตั้งชื่อ component ขึ้นต้นด้วย capital letter เพื่อบอกว่าเป็น component และ 1 folder จะประกอบด้วย 2 files คือ .js (เขียน code JSX) และ .css (เขียน CSS)
- containers — เก็บ component ที่ใช้ state โดยหลักการตั้งชื่อและสร้าง component จะเหมือนกับ folder components
ส่วน folder และ file อื่น ๆ ก็ปล่อยไว้ก่อนก็ได้ครับ แล้วค่อยปรับเปลี่ยนในภายหลัง ทั้งหมดนี้ก็เป็นแนวทางการจัด folder structure แบบหนึ่ง ถ้ามีข้อผิดพลาดในส่วนไหนก็แนะนำผมได้นะครับ ไว้พบกันในบทความหน้าครับ ✨