Computer >> บทช่วยสอนคอมพิวเตอร์ >  >> การเขียนโปรแกรม >> การเขียนโปรแกรม

บทช่วยสอน Gulp 4 สำหรับมือใหม่ (Workflow Sass และ JS)

บทช่วยสอน Gulp 4 นี้จะอธิบายทีละขั้นตอน วิธีตั้งค่า Gulp ใน Workflow เพื่อคอมไพล์ไฟล์ Sass และ JavaScript

หากยังไม่เคยใช้ Gulp ผมแนะนำให้ลองดู! คุณสามารถใช้ Gulp รัน Tasks ที่มีประโยชน์มากมาย เช่น คอมไพล์ไฟล์ Sass เป็น CSS ประมวลผลไฟล์ JavaScript และเพิ่มประสิทธิภาพไฟล์

นี่คือขั้นตอนพื้นฐานในการติดตั้งและรัน Gulp ที่เราจะครอบคลุมในบทช่วยสอนนี้:

  1. ติดตั้ง gulp-cli บนบรรทัดคำสั่งด้วย npm install gulp-cli -g
  2. ติดตั้ง Gulp ด้วย npm install gulp
  3. ติดตั้งแพ็กเกจ npm อื่นๆ สำหรับ Gulp Workflow
  4. สร้างไฟล์ gulpfile.js ในรากโปรเจกต์
  5. Import แพ็กเกจ npm เป็น Modules ใน gulpfile
  6. เพิ่ม Tasks ใน gulpfile คอมไพล์ SCSS/JS และรัน Watch Task
  7. รันคำสั่ง gulp เพื่อรัน Tasks ทั้งหมด

Gulp คืออะไร และทำอะไรได้บ้าง?

Gulp เป็นเครื่องมือที่จะรัน Tasks ต่างๆ ให้คุณใน Web Development Workflow อาจเรียกว่า Bundler, Build Tool หรือ Task Runner เครื่องมือคล้ายกันคือ Webpack และ Grunt (แม้ Grunt จะล้าสมัยเร็วๆ นี้)

นี่คือสิ่งที่เราจะให้ Gulp ทำให้:

  1. คอมไพล์ไฟล์ Sass เป็น CSS
  2. เพิ่ม Vendor Prefixes ให้ CSS
  3. Minify ไฟล์ CSS ตัวสุดท้าย
  4. Concatenate (รวม) ไฟล์ JS
  5. Uglify ไฟล์ JS ตัวสุดท้าย
  6. ย้ายไฟล์ CSS/JS ตัวสุดท้ายเข้าโฟลเดอร์ /dist

เท่ห์ไหม?!

การทำงานคือ Settings และ Tasks ทั้งหมดเก็บในไฟล์ gulpfile.js และรัน Gulp บนบรรทัดคำสั่ง

จุดเด่นคือ เมื่อ gulpfile พร้อมแล้ว คุณนำไปใช้ซ้ำในโปรเจกต์อื่นได้ง่าย มากกว่าประหยัดเวลา!

ไปติดตั้งและตั้งค่า Gulp บนคอมพิวเตอร์กัน

วิธีติดตั้ง Gulp 4

ก่อนรัน Gulp ต้องติดตั้ง 2 อย่าง:

เมื่อ Gulp ทำงานแล้ว ดูโปรเจกต์ Demo ที่ผมสร้างใช้ Gulp!

เป็น Front-end Boilerplate Project สำหรับเริ่มต้นเว็บไซต์ Front-end เรียบง่ายได้เร็ว

(ผมมี Code Snippets 多มในบทช่วยสอนนี้ อ้างอิงได้เลย!)

ตั้งค่า Front-end Boilerplate Project:

  • Clone หรือ Download Git Repo ของโปรเจกต์นี้ลงคอมพิวเตอร์
  • เปิดโปรเจกต์ ในโฟลเดอร์รากโปรเจกต์ ไปที่บรรทัดคำสั่ง รัน npm install จะติดตั้งแพ็กเกจ npm ที่ระบุใน package.json โดยเฉพาะ Gulp 4

ตอนนี้ควรมีไฟล์โปรเจกต์พร้อม และแพ็กเกจ npm ติดตั้งครบสำหรับรัน Gulp Tasks

เนื่องจากไฟล์จาก Repo พร้อมใช้งาน หากพิมพ์ gulp ในบรรทัดคำสั่ง ควรเห็น Output ประมาณนี้:

> gulp [22:29:48] Using gulpfile ~\Documents\GitHub\frontend-boilerplate\gulpfile.js [22:29:48] Starting 'default'... [22:29:48] Starting 'scssTask'... [22:29:48] Starting 'cacheBustTask'... [22:29:48] Finished 'cacheBustTask' after 39 ms [22:29:48] Starting 'jsTask'... [22:29:48] Finished 'jsTask' after 340 ms [22:29:48] Finished 'scssTask' after 347 ms [22:29:48] Starting 'watchTask'... 

คุณรัน Gulp สำเร็จแล้ว!

เกิดอะไรขึ้นในโปรเจกต์เมื่อรัน Gulp?

โปรเจกต์ทำงานสำเร็จ! มาดูรายละเอียดว่าโปรเจกต์มีอะไรและทำงานอย่างไร

โครงสร้างไฟล์โปรเจกต์:

  • index.html — ไฟล์ HTML หลัก
  • package.json — แพ็กเกจ npm ที่ติดตั้งเมื่อรัน npm install
  • gulpfile.js — Config และรัน Gulp Tasks ทั้งหมด
  • /app — Working Folder คุณจะแก้ไข SCSS/JS Files ที่นี่
  • /dist — Gulp จะ Output ไฟล์ที่นี่ อย่าแก้ไขไฟล์เหล่านี้

ใน Workflow คุณแก้ไข HTML, SCSS, JS Files Gulp จะตรวจจับการเปลี่ยนแปลงและคอมไพล์ทั้งหมด แล้วคุณโหลด CSS/JS ตัวสุดท้ายจากโฟลเดอร์ /dist ใน index.html

ตอนนี้ Gulp รันแล้ว มาดูรายละเอียดการทำงานของ Gulp กัน

gulpfile.js มีอะไรบ้าง?

อธิบายรายละเอียดแต่ละส่วนของ gulpfile และหน้าที่:

Step 1: Initialize NPM Modules

บนสุดของ gulpfile.js มี Constants หลายตัว Import แพ็กเกจ npm ที่ติดตั้งก่อนหน้า ด้วยฟังก์ชัน require()

แพ็กเกจแต่ละตัวทำอะไร:

Gulp Package:

  • gulp — รันทุกอย่างใน gulpfile.js Export เฉพาะฟังก์ชัน Gulp ที่จะใช้ เช่น src, dest, watch และอื่นๆ ทำให้เรียกฟังก์ชันเหล่านั้นโดยตรงโดยไม่ต้องพิมพ์ gulp. เช่นพิมพ์ src() แทน gulp.src()

CSS Packages:

  • gulp-sourcemaps — Map สไตล์ CSS กลับไปไฟล์ SCSS ต้นฉบับใน Dev Tools เบราว์เซอร์
  • gulp-sass — คอมไพล์ SCSS เป็น CSS
  • gulp-postcss — รัน Autoprefixer และ CSSNano (ดูด้านล่าง)
  • autoprefixer — เพิ่ม Vendor Prefixes ให้ CSS
  • cssnano — Minify CSS

JS Packages:

  • gulp-concat — รวมไฟล์ JS หลายไฟล์เป็นไฟล์เดียว
  • gulp-uglify — Minify JS

เรายังใช้ String Replace สำหรับ Cache Busting บน Reference CSS/JS ใน index.html เพื่อให้เว็บโหลดไฟล์ใหม่ล่าสุดเมื่อมีการเปลี่ยนแปลง

String Replace Package:

  • gulp-replace — เพิ่ม String Parameter ให้ CSS/JS References สำหรับ Cache Bust

ตอนนี้เรามี Modules แล้ว มานำไปใช้งานกัน!

Step 2: ใช้ Modules รัน Gulp Tasks

"Task" ใน Gulp คือ ฟังก์ชันที่ทำหน้าที่เฉพาะเจาะจง

เราสร้าง Utility Tasks คอมไพล์ SCSS และ JS Files และ Watch ไฟล์เหล่านั้นสำหรับการเปลี่ยนแปลง Utility Tasks นี้จะรันใน Default Gulp Task เมื่อพิมพ์ gulp บนบรรทัดคำสั่ง

สร้าง Constants สำหรับ File Paths

ก่อนเขียน Tasks เรามีโค้ดบางบรรทัดบันทึก File Paths เป็น Constants Optional แต่ผมชอบใช้ Path Variables เพื่อไม่ต้องพิมพ์ซ้ำ:

โค้ดนี้สร้าง Constants scssPath และ jsPath ใช้บอก Gulp ว่าไฟล์อยู่ที่ไหน

Sass Task

โค้ดสำหรับ Sass Task:

function scssTask(){ return src(files.scssPath) .pipe(sourcemaps.init()) .pipe(sass()) .pipe(postcss([ autoprefixer(), cssnano() ])) .pipe(sourcemaps.write('.')) .pipe(dest('dist') ); } 

Sass Task ชื่อ scssTask() ทำหลายอย่าง ใน Gulp สามารถ Chain ฟังก์ชันหลายๆ ตัวด้วย pipe() หลังฟังก์ชันแรก

ใน Task นี้ Gulp รัน src() โหลด Source Directory ของ SCSS Files ใช้ Constant files.scssPath

หลัง src() Pipe ทุกอย่างเข้า Build Process คิดเหมือนต่อท่อเพิ่มท่อนต่อท่อน

ฟังก์ชันที่รัน:

  • sourcemaps.init() — Sourcemaps ต้องเพิ่มทันทีหลัง src()
  • sass() — คอมไพล์ SCSS Files ทั้งหมดเป็น CSS ไฟล์เดียว
  • postcss() — รัน Plugins 2 ตัว:
    • autoprefixer() เพิ่ม Vendor Prefixes ให้ CSS
    • cssnano() Minify CSS File
  • sourcemaps.write() — สร้าง Sourcemaps File ใน Directory เดียวกัน
  • dest() — บอก Gulp วาง CSS File ตัวสุดท้ายและ CSS Sourcemaps File ในโฟลเดอร์ /dist

JS Task

โค้ด Task คอมไพล์ JS Files:

function jsTask(){ return src([files.jsPath]) .pipe(concat('all.js')) .pipe(uglify()) .pipe(dest('dist') ); } 

JavaScript Task ชื่อ jsTask() รันฟังก์ชันหลายตัว:

  • src() โหลด JS Files จาก files.jsPath
  • concat() รวม JS Files ทั้งหมดเป็น JS File เดียว
  • uglify() Uglify/Minify JS File
  • dest() ย้าย JS File ตัวสุดท้ายเข้าโฟลเดอร์ /dist

Cache Bust Task

โค้ด Cache Bust Task:

var cbString = new Date().getTime(); function cacheBustTask(){ return src(['index.html']) .pipe(replace(/cb=\d+/, 'cb=' + cbString)) .pipe(dest('.')); } 

ใน index.html ผมใช้ References สำหรับ CSS และ JS Files แบบนี้:

<link rel="stylesheet" href="dist/style.css?cb=123"> <script src="dist/all.js?cb=123"></script> 

เหตุผล Cache Bust ช่วยคือ เบราว์เซอร์และ Web Host Server มัก Cache (เก็บ) Copy ของ Asset Files เช่น CSS และ JS Files ดังนั้นโหลดหน้าเดิมอีกครั้ง เร็วกว่าโหลดจาก Server ใหม่

ปัญหาคือ บางครั้งไม่อยากโหลดเวอร์ชันเก่า ที่ Save ไว้ เมื่อคุณแก้ไข CSS หรือ JS และ Redeploy ขึ้น Server ต้องการบังคับให้คนโหลดไฟล์ใหม่

วิธีบังคับโหลดใหม่คือ เพิ่ม Query String เล็กๆ ?cb=123 ท้าย File References หากเบราว์เซอร์โหลดหน้าใหม่ และ Query String ต่างจากครั้งก่อน จะ Refresh File

ผมใช้ Gulp replace() หา String ที่มี "cb=" และตัวเลข แล้วแทนที่ตัวเลขด้วยตัวเลขใหม่จากเวลาปัจจุบันแปลงเป็น Milliseconds นับจาก 1970

ดังนั้นทุกครั้งที่ Gulp รัน Query String จะต่างกัน และมั่นใจว่า CSS และ JS Files ใหม่จะโหลดในเบราว์เซอร์ผู้ใช้

Gulp Watch Task

Gulp watch() Function เป็น Feature สูปน่าสนใจ ตอนรัน จะทำงานต่อเนื่อง Watch ไฟล์ตรวจจับการเปลี่ยนแปลง เมื่อเจอการเปลี่ยนแปลง จะรัน Tasks ที่คุณระบุ

ดีมากเพราะไม่ต้องรัน gulp เองทุกครั้งหลังแก้โค้ด

โค้ด Watch Task ตัวอย่าง:

function watchTask(){ watch( [files.scssPath, files.jsPath], parallel(scssTask, jsTask) ); } 

watch() Function รับ 3 Parameters แต่เราใช้ 2 ตัว:

  • Globs คือ File Path Strings
  • Options (ไม่ใช้)
  • Tasks คือ Tasks ที่ต้องการรัน

Watch Task ของเรา Watch ไฟล์ใน scssPath และ jsPath Directories หากมีการเปลี่ยนแปลงในตัวไหน ให้รัน scssTask และ jsTask พร้อมกัน

ตอนนี้ Utility Tasks พร้อม ต้องตั้งค่า Main Gulp Task

Default Gulp Task

นี่คือ Main Gulp Task จะรันอัตโนมัติหากพิมพ์ gulp บนบรรทัดคำสั่ง

exports.default = series( parallel(scssTask, jsTask), watchTask); 

Gulp จะค้นหา Task default ใน gulpfile.js อัตโนมัติเมื่อใช้คำสั่ง gulp ดังนั้นต้อง Export Default Task เพื่อให้ทำงาน

Default Task จะ:

  • รัน scssTask และ jsTask พร้อมกันด้วย parallel()
  • จากนั้นรัน watchTask

สังเกตว่าเราห่อ Tasks ทั้งหมดในฟังก์ชัน series()

นี่คือการเปลี่ยนแปลงหลักใน Gulp 4 สำหรับการจัดการ Tasks — ต้องห่อ Tasks ทั้งหมด (แม้ Task เดียว) ใน series() หรือ parallel()

การเปลี่ยนแปลงใน Gulp 4

หากคุณใช้ tasks() Function รันทุกอย่าง อาจสังเกตเห็นความแตกต่าง

แทนที่จะใช้ gulp.task() contain Task Functions ทั้งหมด เราสร้าง Functions จริงๆ เช่น scssTask() และ watchTask()

เพื่อปฏิบัติตามแนวทางทางการของ Gulp สำหรับการสร้าง Tasks

ทีม Gulp แนะนำใช้ exports แทน tasks():

แม้ยังอนุญาตให้ใช้ task() Function แต่ Syntax ใหม่กว่า คือ สร้าง JS Functions สำหรับแต่ละ Task แล้ว Export ถ้าทำได้ แนะนำอัปเดต Syntax ให้ทันสมัย เพราะ Gulp อาจ Deprecate task() ในอนาคต

ปัญหาการย้ายจาก Gulp 3?

หากคุณใช้ Gulp 3 และอยากให้มันทำงานกับ Gulp 4 คุณโชคดี!

Breaking Change หลักเกี่ยวกับวิธีรัน Tasks

Gulp 4 Introduce 2 ฟังก์ชันใหม่รัน Tasks: series() และ parallel() ให้เลือก Run Multiple Tasks พร้อมกัน หรือทีละอัน

ก่อนหน้าใน Gulp 3 สามารถ List Single Function หรือ Multiple Functions ใน Array ได้ แต่ใน Gulp 4 ทำแบบนั้นโดยไม่ห่อใน series() หรือ parallel() จะ Throw Error

อย่างเช่น:

AssertionError [ERR_ASSERTION]: Task function must be specified 


วิธีแก้ไขด่วน:


Tasks ใน Syntax Gulp 3 (เก่า)

ใน Gulp 3 อาจรัน Tasks แบบนี้:

gulp.task('default', ['sass', 'js', 'watch']); gulp.watch('app/scss/*.scss', ['sass']); 


Tasks ใน Syntax Gulp 4

ห่อ Tasks เข้า series() Function แบบนี้:

gulp.task('default', gulp.series('sass', 'js', 'watch')); gulp.watch('app/scss/*.scss', gulp.series('sass')); 


และจะแก้ Error Task Function ด้วยการเปลี่ยนแปลงน้อยที่สุด! 🙂

ดาวน์โหลดไฟล์โปรเจกต์

โค้ดทั้งหมดที่แสดงอยู่มาจาก GitHub Repository ของผมสำหรับ Front-end Boilerplate เป็น Starter Kit เร็วสำหรับโปรเจกต์เว็บไซต์ Front-end เรียบง่าย

คุณสามารถดู ปรับแต่ง และใช้สำหรับโปรเจกต์ของตัวเองได้!

ดู GitHub Repository ที่นี่