[ES6] เพิ่มความเร็ว development ให้ Node.js ที่ต้องใช้ Babel กับ Nodemon ด้วย Webpack 4+ บน Docker
หลังจากที่ขึ้นโครง Project ตัวใหม่ที่เป็น Node.js server แล้วก็ใส่ Docker สร้าง Container ขึ้นมา เพื่อ development กันในตัวนั้นเลยซึ่งการ compile code แล้วก็ทำ live-reload เพื่อ restart server ให้เองบน Docker Container พอทำจริงรู้สึกกว่าจะ restart หน่วงพอสมควร (10 วินาที)
ตัวอย่าง Project ตามลิ้งนี้ github.com/ttanachot/es6-node-webpack
ทำไมต้องใส่เข้าไปใน container แล้ว development กันบนนั้น?
ถ้าคุณอยากเปิด service สักสองตัวเช่น frontend กับ backend ที่แยกกันขึ้นมาพร้อมๆกัน เราก็จะใช้ docker จะช่วยเรื่องนี้ให้ชีวิตคุณง่ายขึ้น อาจจะไม่ต้องมานั่งเกี่ยงกันว่า develop คนนั้นใช้ libary version นี้ dependency แบบนี้ ซึ่งจะควบคุม environment ได้ค่อนข้างโอเคเลย
ไปรู้จัก library แต่ละตัวที่นำมาใช้ดีกว่า
Library สำหรับ ES6 กับ NodeJS ถ้าทำด้วย Babel กับ Nodemon บน local อาจจะดูชิลๆ ลอง บน container อาจจะเห็นความแตกต่าง ในแนวทางนี้เราก็ใช้ Webpack 4+ เข้ามาเป็นตัวช่วยในการเพิ่มความเร็วในการ compile, transform, watch ในการ development ที่เร็วยิ่งขึ้น
Babel
อยากเขียน EMCA Script 6+ บน Node.js แต่ก็ยังไม่ได้ Support เต็มที่พระเอกของเราก็คือ Babel ที่ใช้แปลง Syntax หรือจะใส่ Polyfill ให้ compatible กับที่เราใช้ Node.js v.10 ณ ตอนที่เขียน (อนาคตเราไม่จำเป็นต้องมีส่วนนี้เลยถ้า Node upgrade ขึ้นไป)
Nodemon
Nodemon เป็นตัวช่วยในการ monitor changes สำหรับไฟล์ code ฝั่ง server แล้วก็จะ restart ให้เราแบบอัตโนมัติเป็น live-reload โดยที่เราแค่ save code โดยไม่ต้องมา start/stop เอง
Webpack
Webpack ก็จะรู้จักกันว่าเป็น bundler tool ที่ไว้ช่วยจัดการ JS ไฟล์ของเราให้เป็น module ก็จะมีการสร้าง configuration ไฟล์ได้ตามที่เราต้องการที่จะจัดการ package ของ server เราแล้วก็มี plugins ให้ใช้หลายตัวทั้งที่เป็น build-in และ community
Docker
Docker จะทำหน้าที่เป็น service ที่สร้าง Image แล้วก็เอาไปใส่ใน Container ช่วยให้เราเมื่อเราเอา service ไปใช้งานขั้นต้นของการทำ package ยังช่วยเรื่อง environment control ลดปัญหาอย่างเช่น ทำให้ dependency ของ development กับ production ตรงกัน
ทำไมเอา Babel กับ Nodemon มารวมกันใน Docker ถึงช้า?
สังเกตได้ว่าสิ่งที่นานคือการแปลง code จาก ES6 ให้เป็น Syntax ที่ compatible กับสิ่งที่ Node.js นั้น Support อยู่ ณ เวลานี้ ส่วน Nodemon ก็ต้องรอให้ไฟล์ทั้งหมดถูกแปลงให้เสร็จซึ่งในส่วนนี้มันค่อนข้างกินเวลาพอสมควรกว่าที่ Server จะสามารถ Restart แน่นอนแหละว่า Performance ในการ watch changes อาจจะนานตามไปด้วย แต่ถ้าเรา improve ได้มันก็จะช่วยประหยัดเวลารอของเรามากขึ้น
Setup ตัว webpack.config.js ยังไงบ้าง?
Idea หลักๆก็คือว่า ให้ webpack เนี่ยไปช่วยสร้าง bundle ไฟล์จาก ./src/index.js แล้วเอาไปวางไว้ที่ ./build/server.js แทน
ก็จะใช้ community plugin ที่ชื่อว่า nodemon-webpack กับ webpack-node-externals รวมถึง babel-loader แล้วให้ไปอ่าน config จาก .babelrc ตามสิ่งที่เราต้องการให้มันช่วยแปลง Syntax ที่ขาดไม่ได้เลยคือตัว HotModuleReplacement จะ watch changes แค่สิ่งที่เราเปลี่ยนแล้วไม่ได้เป็น full reload แจ่มเลย
ทีนี้ก็อย่าลืมไปใส่ npm scriptsให้เป็น "webpack --watch"
Development กับ Docker
- เราจะต้องทำ Image ขึ้นมาก่อนจาก .Dockerfile ใน backend-service เพื่อ prepare environment ให้เรา
docker-compose build backend-service
- สร้าง Container แล้วก็ใส่ Image ลงไปด้วย แล้วก็สั่งตาม command ที่ใส่ไว้
npm install && npm run dev
ทีนี้ Docker ก็จะ map ตัว backend-service ของเราไว้ที่ port:9001docker-compose up backend-service
ลองแก้ code สักหน่อย
พอ save ไฟล์ที่แก้ตัว nodemon สั่ง restart server หลังจากนั้น webpack ก็ compile ไฟล์ในส่วนที่แก้แค่บาง part ด้วย HMR
ใช้เวลาประมาณ 2 วินาทีก็ start server ขึ้นมาใหม่แล้ว แจ่มกว่า 10 วินาทีตั้งเยอะ
การแก้ code เป็นอะไรที่ทำบ่อยมาก แล้วยิ่งถ้าใส่ live-reload เข้าใน Docker Container แล้วด้วยแน่นอนว่าการใส่ resource เข้าอาจจะไม่ได้เหมือนการ development บน local เลยถ้ารอนานกันเข้าไปอีก
ถ้าเราประหยัดเวลาในส่วนนี้ไปได้ผมว่ามันก็คุ้มค่านะ หวังว่าบทความนี้จะเป็น อะไรที่ช่วยให้ developer ทำงานง่ายขึ้นครับ