เราเข้าสู่ทศวรรษที่ 20s แล้ว เรามีเครื่องมือช่วยอำนวยความสะดวกในการทำเว็บเยอะแยะมากมาย หนึ่งในนั้นคือบรรดา CSS Preprocessor ทั้งหลายไม่ว่าจะเป็น SASS, LESS, หรือ Stylus รวมไปถึงฟีเจอร์ใหม่ๆ ใน JavaScript ที่เพิ่มเข้ามาใหม่อย่างรวดเร็วจนเบราเซอร์ตามกันไม่ค่อยทัน
กำแพงสำคัญอย่างหนึ่งที่ทำให้หลายคนยังไม่ก้าวไปใช้เครื่องมือเหล่านี้สักทีนั่นคือความยุ่งยากในการตั้งค่าเครื่องมือในการคอมไพล์ (หรือทรานสไพล์) ภาษาเหล่านี้ให้เป็นโค้ดที่เบราเซอร์ส่วนใหญ่ในตลาดสามารถเอาไปใช้งานได้
เออ พูดถึงแกนั่นแหละนัง Webpack
ทางออกหนึ่งคือไปใช้ starter theme ที่ตั้งค่าพวกนี้มาให้แล้วอย่างเช่น Sage 9
- เขียนธีม WordPress บนเทคโนโลยีสมัยใหม่ด้วย Sage 9 – ตอนที่ 1 แนะนำ Sage 9
- เขียนธีม WordPress ด้วย Sage 9 – ตอนที่ 2 ระบบจัดการแพ็คเกจ
- เขียนธีม WordPress ด้วย Sage 9 – ตอนที่ 3 Blade Template Engine
- เขียนธีม WordPress ด้วย Sage 9 – ตอนที่ 4 ควบคุมข้อมูลด้วย Controller
Laravel Mix
วันนี้จะพามารู้จัก Laravel Mix ซึ่งเป็น wrapper ของ Webpack ที่ช่วยให้เราสามารถคอมไพล์ CSS Preprocessor และ ESNext รวมไปถึงบันเดิลไฟล์จากหลายๆ แพ็คเกจออกมาเป็นไฟล์เดียว ที่เราสามารถใช้งานมันได้ง่ายๆ แบบแทบไม่ต้องตั้งค่าอะไรให้ยุ่งยากเลย
จริงๆ Laravel Mix นี่มันเป็นเครื่องมือของเฟรมเวิร์ก Laravel นั่นแหละ แต่ว่ามันสามารถเอาออกมาใช้แบบ standalone กับโปรเจ็กท์อื่นๆ รวมไปถึงธีมของ WordPress ได้ด้วย
ก่อนที่เราจะติดตั้ง Laravel Mix ก่อนอื่นเครื่องเราต้องนิดตั้ง Node.js และ package manager สักตัวเช่น npm (มากับ Node.js เอง) หรือ Yarn
แนะนำว่าต้องมีพื้นฐานการใช้งาน Command prompt หรือ Terminal เล็กน้อยนะครับ อย่างน้อยคือใช้คำสั่ง
cd
เป็น และใช้npm
หรือyarn
เป็น
ติดตั้ง Laravel Mix
เปิด cmd หรือ Terminal ขึ้นมาแล้วเปิดไปยังไดเรคทอรี่ธีมของเรา แล้วสั่งติดตั้งแพ็คเกจ laravel-mix
และ cross-env
ให้เรียบร้อย
// สำหรับคนที่ใช้ npm $ npm install laravel-mix cross-env --save-dev // สำหรับคนที่ใช้ Yarn $ yarn add laravel-mix cross-env --dev
cross-env เป็นแพ็คเกจสำหรับช่วยเรื่อง environment variable ที่บน Windows และ Unix-like นั้นมีวิธีใช้ต่างกัน ซึ่งเราจำเป็นจะต้องใช้ env นี้ในขั้นตอนการคอมไพล์ assets
ใครที่ใช้ Node.js เวอร์ชัน 8 ต้องติดตั้งแพ็คเกจ [email protected] แทน เพราะเวอร์ชันล่าสุดนั้นต้องการ Node.js เวอร์ชัน 10 ขึ้นไป
โดยส่วนตัวผมเจอปัญหาคอมไพล์ไม่ผ่านจาก
node-sass
ตัว global ไม่ตรงเวอร์ชัน ถึงจะสั่งติดตั้งใหม่แล้วก็ไม่สามารถใช้ได้ กรณีแบบนี้เราสามารถแก้ได้ง่ายๆ ด้วยการติดตั้งแพ็คเกจnode-sass
เพิ่มลงไปอีกแพ็คเกจหนึ่ง
จากนั้นคัดลอกไฟล์ node_modules/laravel-mix/setup/webpack.mix.js
ออกมาวางไว้ที่ root directory ของธีมเรา
$ cp node_modules/laravel-mix/setup/webpack.mix.js ./
จากนั้นเปิดไฟล์ package.json
ขึ้นมา แล้วก็อปคอนฟิก scripts นี้ไปใส่ไว้ก่อนปิดปีกกาสุดท้าย (หรือถ้ามีคอนฟิก scripts อยู่แล้ว ก็ก็อปข้างในใส่เพิ่มเข้าไป)
"scripts": { "build": "cross-env NODE_ENV=development node_modules/webpack/bin/webpack.js --progress --hide-modules --config=node_modules/laravel-mix/setup/webpack.config.js", "build:production": "cross-env NODE_ENV=production node_modules/webpack/bin/webpack.js --no-progress --hide-modules --config=node_modules/laravel-mix/setup/webpack.config.js" }
คอนฟิกทั้งสองค่าข้างบนจะเพิ่มคำสั่ง build และ build:production ให้กับ npm หรือ yarn สำหรับใช้บิลด์ assets สำหรับ dev (เว็บที่กำลังทำอยู่) และ production (ตัวเว็บที่เปิดใช้จริง) ตามลำดับ (มันเป็นช็อตคัทสำหรับคำสั่งยาวๆ ข้างหลัง ใครจะไปอยากจำ จริงมั้ย) เราสามารถรันคำสั่งนี้ผ่าน terminal ได้แบบนี้
// สำหรับคนใช้ npm $ npm run build $ npm run build:production // สำหรับคนใช้ Yarn $ yarn build $ yarn build:production
ความต่างของการ build ธรรมดาสำหรับตอน dev และการ build:production สำหรับใช้บน production คือในเวอร์ชัน dev นั้น ไฟล์ JS และ CSS จะมี sourcemap บอกอยู่ว่าโค้ดส่วนนั้นมาจากไฟล์ไหน แพ็คเกจไหน บรรทัดเท่าไหร่ เมื่อเราเปิดด้วย dev tool ดูแล้วมันจะมีบอกให้เราได้เห็นในพาเนล style เราจะได้ตามไปแก้ได้ถูกไฟล์
ส่วนการบิลด์สำหรับ production นั้นจะเอา sourcemap ออกไป และทำการ minify ไฟล์ให้ด้วยเพื่อลดขนาดไฟล์ให้เล็กลง


จริงๆ ถึงตรงนี้ Laravel Mix ก็พร้อมใช้งานในขั้นต้นแล้ว แต่เดี๋ยวเราจะไปปรับแต่ง Laravel Mix เพิ่มเติมอีกเล็กน้อย รวมถึงจัดการโครงสร้างไฟล์เพื่อให้เหมาะกับธีมเรามากขึ้น
อ้อ ถ้าสมมุติว่าเราไม่อยากมาสั่งคอมไพล์ไฟล์เองทุกครั้ง เราสามารถสั่งให้ Webpack คอยดูการเปลี่ยนแปลงของไฟล์ และคอมไพล์ใหม่อัตโนมัติได้ด้วย
// สำหรับคนใช้ npm $ npm run build -- --watch // สำหรับคนใช้ Yarn $ yarn build --watch

กำหนดโครงสร้างไฟล์
ค่าเริ่มต้นของ Laravel Mix นั้นจะกำหนด entry point สำหรับ CSS และ JS เอาไว้ในไดเรคทอรี่ src/
ในไดเรคทอรี่ธีมของเรา คือ
src/app.js
สำหรับไฟล์จาวาสคริปท์src/app.scss
สำหรับไฟล์ SCSS
และจะคอมไพล์ assets ออกมาเก็บไว้ในไดเรคทอรี่ dist/
dist/app.js
สำหรับไฟล์จาจาสคริปท์dist/app.css
สำหรับไฟล์ SCSS ที่ถูกคอมไพล์ออกมาเป็น CSS แล้ว
ในตัวอย่างนี้เราจะสมมุติว่าเราจะเปลี่ยนที่เก็บไฟล์ไปเป็นไดเรคทอรี่ assets/scripts/main.js
และ assets/styles/main.scss
และให้คอมไพล์ออกมาที่ dist/scripts/main.js
และ dist/styles/main.css
ตามลำดับ
เอาล่ะ เปิดไฟล์ webpack.mix.js
ที่เราก็อปออกมาเมื่อสักครู่นี้ขึ้นมา เราจะเห็นไฟล์ยาวเหยียด แต่ส่วนมากถูกคอมเมนต์ทิ้งเอาไว้ สาระสำคัญตอนนี้มีอยู่แค่สองบรรทัด คือ
let mix = require('laravel-mix'); mix.js('src/app.js', 'dist/').sass('src/app.scss', 'dist/');
เนี่ยแหละ คอนฟิกเริ่มต้นทั้งหมดของมัน ไม่มีแล้วความปวดหัว!
อธิบายโค้ดคือบรรทัดแรกให้ require แพ็คเกจ laravel-mix
เข้ามาไว้ในตัวแปร mix
จากนั้นในบรรทัดที่สอง จะเรียกใช้เมท็อด .js()
เพื่อกำหนดการคอมไพล์จาวาสคริปท์จากไฟล์ src/app.js
ไปไว้ที่ไดเรคทอรี่ dist/
และใช้เมท็อด .sass()
สำหรับคอมไพล์ไฟล์ src/app.scss
ไปเก็บไว้ในไดเรทอรี่ dist/
ด้วยอีกไฟล์
ดังนั้นถ้าเราจะเปลี่ยนไดเรคทอรี่ตามโจทย์ข้างบน ก็ทำได้ง่ายๆ เพียงแค่เปลี่ยนค่าจากสองเมท็อดนี้
let mix = require('laravel-mix'); mix .js('assets/scripts/main.js', 'dist/scripts/') .sass('assets/styles/main.scss', 'dist/styles/');
จากนั้นสั่ง npm run build
ก็จะได้ไฟล์ที่คอมไพล์แล้วไปโผล่อยู่ในไดเรคทอรี่ dist/scripts/
และ dist/styles/
ตามลำดับ
ขั้นตอนต่อไปคือบอกให้เวิร์ดเพรส enqueue ไฟล์พวกนี้เข้ามา ให้เราเปิดไฟล์ functions.php
ของธีมขึ้นมา แล้ว enqueue มันเข้าไปให้เรียบร้อย
<?php add_action('wp_enqueue_scripts', function () { wp_enqueue_style('main-style', get_stylesheet_directory_uri() . "/dist/styles/main.css", false, null); wp_enqueue_script('main-js', get_stylesheet_directory_uri() . "/dist/scripts/main.js", ['jquery'], null, true); }, 100);
และอย่าลืมไปเพิ่มไดเรคทอรี่ dist/
ลงในไฟล์ .gitignore
ด้วย
ถ้าลองดูการตั้งค่าอื่นๆ ในไฟล์ที่ถูกคอมเมนต์เอาไว้ จะพบว่า Laravel Mix ยังรองรับการคอมไพล์อย่างอื่นอีกเพียบ ไม่ว่าจะเป็น LESS, Stylus, PostCSS, หรือแม้แต่ TypeScript และ React.js
เรียกใช้ jQuery ของ WordPress ใน Laravel Mix
jQuery ยังถือเป็นหนึ่ง library คู่บุญของชาว WordPress ทั้งนี้ถ้าเราจะเอามาใช้ใน Laravel Mix โดยปกติแล้วเราต้องติดตั้ง jQuery เพิ่มเข้าไปเอง ซึ่งจะกลายเป็นว่าเว็บเรามี jQuery สองตัว คือตัวหนึ่งของ WordPress เอง และอีกตัวคือที่เราติดตั้งไว้บน Webpack
เราสามารถแก้ให้ Laravel Mix เรียกใช้ jQuery ของ WordPress ได้ง่ายๆ ด้วยการใส่ตั้งค่าให้ jQuery ถูกเรียกผ่าน external plugin โดยให้เพิ่มการตั้งค่านี้ลงในไฟล์ webpack.mix.js
mix.webpackConfig({ externals: { jquery: 'jQuery' } });
เท่านี้แหละ พร้อมใช้แล้ว
ใช้ Bootstrap ผ่าน npm
อันนี้เป็น use case ประหลาดๆ อันนึงที่เจอบ่อยๆ นั่นคือหลายคนติดตั้งแพ็คเกจ Bootstrap ผ่าน npm แล้วเวลาดีพลอยก็อัปโหลดไดเรคทอรี่หลุมดำอย่าง node_modules
ขึ้นไปทั้งก้อน ซึ่งแน่นอนมันใหญ่มาก
ขั้นแรกให้ติดตั้งแพ็คเกจ bootstrap
และ popper.js
ลงไปให้เรียบร้อย (เราไม่จำเป็นต้องติดตั้ง jQuery เพราะเราสามารถใช้ของ WordPress ได้เลย)
// สำหรับคนใช้ npm $ npm install bootstrap popper.js // สำหรับคนใช้ Yarn $ yarn add bootstrap popper.js
ขั้นต่อไปให้เปิดไฟล์ assets/styles/main.scss
ขึ้นมา แล้วอิมพอร์ต scss ของ Bootstrap เข้ามาด้วยคำสั่ง @import
@import "~bootstrap/scss/bootstrap";
เราสามารถแก้ไขการตั้งค่าของ Bootstrap เพิ่มเติมเช่นเปลี่ยนค่าสีเริ่มต้น ผ่านการตั้งตัวแปร SCSS ซึ่งอันนี้ขอติดไว้ก่อน มันยาวพอจะแยกเป็นอีกเรื่องได้เลย
จากนั้นให้เปิดไฟล์ assets/scripts/main.js
ขึ้นมา แล้วอิมพอร์ต jquery
และ bootstrap
เข้ามา
import 'jquery'; import 'bootstrap';
เท่านี้ก็เรียบร้อย เราสามารถเขียน CSS และ JS ใช้งานต่อตามปกติได้เลย
Optimize ไฟล์ภาพอัตโนมัติด้วย Imagemin
นอกจากฟีเจอร์ built-in ทั้งหลายแล้ว เรายังเพิ่มความสามารถให้ Laravel Mix ผ่านส่วนเสริมได้อีกด้วย (ดูส่วนเสริมทั้งหมดได้ในนี้) ในตัวอย่างนี้เราจะพาไปดูการใช้ laravel-mix-imagemin
ในการ optimize ไฟล์ภาพอัตโนมัติกัน
อย่างแรกให้ติดตั้งส่วนเสริม laravel-mix-imagemin
ก่อน
// สำหรับคนใช้ npm $ npm install laravel-mix-imagemin --save-dev // สำหรับคนใช้ Yarn $ yarn add laravel-mix-imagemin --dev
จากนั้นเปิดไฟล์ webpack.mix.js
ขึ้นมา แล้ว require ส่วนเสริมและเพิ่มคอนฟิกของ imagemin ดังนี้
let mix = require('laravel-mix'); require('laravel-mix-imagemin'); mix.webpackConfig({ externals: { jquery: 'jQuery' } }); mix .js('src/app.js', 'dist/') .sass('src/app.scss', 'dist/') .imagemin([ { from: 'assets/images/', to: 'dist/images/' } ]);
สังเกตุว่าที่ออพเจ็กท์ mix เราเรียกใช้เมท็อด .imagemin()
เพิ่มเข้ามา จากคอนฟิกตัวอย่างจะเป็นการคัดลอกไฟล์ภาพจากไดเรคทอรี่ assets/image/
เอาไปเก็บไว้ที่ dist/images/
แล้วทำการ optimize ไฟล์เหล่านั้น
เวลาเราเรียกใช้ไฟล์ในธีมก็ให้อ้างอิงไฟล์จากไดเรคทอรี่ dist/images
ได้เลย หรือถ้าเป็นการเรียกใช้จาก CSS ก็เรียกเอาผ่าน relative path เช่น
body { background-image: url("../images/background.svg"); }
ปิดตัวเลือก Process CSS URLs
โดยปกติแล้วเมื่อ Laravel Mix เจอว่าไฟล์ SCSS ของเรามีการเรียกใช้ assets อื่น เช่นรูปภาพหรือฟอนต์ Laravel Mix จะสแกนหาไฟล์ที่เรียกใช้แล้วคัดลอกออกมาที่ public directory พร้อมกับเปลี่ยน URL ในไฟล์ CSS ที่คอมไพล์แล้วให้อัตโนมัติ
ฟังดูสะดวกดี แต่เอาเข้าจริงในบางกรณี Laravel Mix จะไม่สามารถหาไฟล์นั้นเจอได้ และทำให้คอมไพล์ไม่ผ่านในที่สุด รวมกับเราใช้วิธีก็อปไฟล์ออกมายัง dist/
เองแล้ว (ทั้งจาก imagemin และ copy-watched) ทำให้เราสามารถปิดฟีเจอร์นี้ได้ ด้วยการเรียกใช้เมท็อด option ดังนี้
mix.options({ processCssUrls: false, });
ดีพลอยเว็บจริง
เมื่อเราติดตั้งแพ็คเกจต่างๆ ด้วย npm
หรือ yarn
เราจะได้ไดเรคทอรี่ node_modules/
มาอันหนึ่ง ที่ในนั้นจะประกอบด้วยแพ็คเกจย่อยๆ มากมายมหาศาล และถ้าหากใครที่ยังใช้วิธีดีพลอยเว็บผ่าน FTP อยู่ น่าจะเข้าใจความเจ็บปวดในการอัปโหลดไฟล์มากมายมหาศาลเหล่านี้ได้เป็นอย่างดี
ข่าวดีก็คือเมื่อเราจัดการรวมไฟล์ทั้งหมดออกมาเป็นไฟล์เดียวแล้ว เราก็ไม่จำเป็นต้องใช้ node_modules/
อีกต่อไป รวมไปถึงไดเรคทอรี่ assets/
ที่ใชเก็บไฟล์ดิบก่อนการคอมไพล์อีกด้วย
ดังนั้นในขั้นตอนการดีพลอย เราสามารถข้ามสองไดเรคทอรี่นี้ไปได้เลย เพียงแค่อัปโหลดไดเรคทอรี่ dist/
อันเดียวก็เพียงพอแล้ว
Leave a Reply