อึก: อาวุธลับของนักพัฒนาเว็บเพื่อเพิ่มความเร็วไซต์ให้สูงสุด
เผยแพร่แล้ว: 2022-03-11พวกเราหลายคนต้องจัดการโครงการบนเว็บที่ใช้ในการผลิตซึ่งให้บริการต่างๆ แก่สาธารณะ เมื่อต้องรับมือกับโครงการดังกล่าว สิ่งสำคัญคือต้องสามารถสร้างและปรับใช้โค้ดของเราได้อย่างรวดเร็ว การทำบางสิ่งอย่างรวดเร็วมักจะนำไปสู่ข้อผิดพลาด โดยเฉพาะอย่างยิ่งหากกระบวนการซ้ำซาก จึงเป็นแนวปฏิบัติที่ดีที่จะทำให้กระบวนการดังกล่าวเป็นไปโดยอัตโนมัติให้ได้มากที่สุด
ในโพสต์นี้ เราจะดูเครื่องมือที่สามารถเป็นส่วนหนึ่งของสิ่งที่จะช่วยให้เราบรรลุการทำงานอัตโนมัติดังกล่าวได้ เครื่องมือนี้เป็นแพ็คเกจ npm ชื่อ Gulp.js เพื่อทำความคุ้นเคยกับคำศัพท์พื้นฐาน Gulp.js ที่ใช้ในโพสต์นี้ โปรดอ้างอิงถึง “บทนำสู่การทำงานอัตโนมัติของ JavaScript ด้วยอึก” ที่เคยเผยแพร่บนบล็อกโดย Antonios Minas หนึ่งในนักพัฒนา Toptal ของเรา เราจะถือว่ามีความคุ้นเคยขั้นพื้นฐานกับสภาพแวดล้อม npm เนื่องจากมีการใช้อย่างกว้างขวางตลอดทั้งโพสต์นี้เพื่อติดตั้งแพ็คเกจ
การให้บริการสินทรัพย์ส่วนหน้า
ก่อนที่เราจะดำเนินการต่อ ย้อนกลับไปสองสามขั้นตอนเพื่อดูภาพรวมของปัญหาที่ Gulp.js สามารถแก้ไขให้เราได้ โปรเจ็กต์บนเว็บหลายโปรเจ็กต์มีไฟล์ JavaScript ส่วนหน้าที่ให้บริการกับไคลเอ็นต์เพื่อมอบฟังก์ชันการทำงานต่างๆ ให้กับหน้าเว็บ โดยปกติแล้วจะมีชุดของสไตล์ชีต CSS ที่ให้บริการกับไคลเอ็นต์ด้วยเช่นกัน บางครั้งเมื่อดูซอร์สโค้ดของเว็บไซต์หรือเว็บแอปพลิเคชัน เราจะเห็นโค้ดดังนี้:
<link href="css/main.css" rel="stylesheet"> <link href="css/custom.css" rel="stylesheet"> <script src="js/jquery.min.js"></script> <script src="js/site.js"></script> <script src="js/module1.js"></script> <script src="js/module2.js"></script>
รหัสนี้มีปัญหาเล็กน้อย มีการอ้างอิงถึงสไตล์ชีต CSS แยกกันสองไฟล์และไฟล์ JavaScript แยกกันสี่ไฟล์ ซึ่งหมายความว่าเซิร์ฟเวอร์ต้องส่งคำขอทั้งหมดหกรายการไปยังเซิร์ฟเวอร์ และแต่ละคำขอต้องโหลดทรัพยากรแยกต่างหากก่อนที่หน้าจะพร้อม นี่เป็นปัญหาน้อยกว่าสำหรับ HTTP/2 เนื่องจาก HTTP/2 นำเสนอความขนานและการบีบอัดส่วนหัว แต่ก็ยังเป็นปัญหาอยู่ จะเพิ่มปริมาณการรับส่งข้อมูลทั้งหมดที่จำเป็นในการโหลดหน้านี้ และลดคุณภาพของประสบการณ์ผู้ใช้เนื่องจากใช้เวลาในการโหลดไฟล์นานขึ้น ในกรณีของ HTTP 1.1 เครือข่ายดังกล่าวจะขัดขวางเครือข่ายและลดจำนวนช่องทางคำขอที่มีอยู่ คงจะดีกว่ามากที่จะรวมไฟล์ CSS และ JavaScript ไว้ในบันเดิลเดียวสำหรับแต่ละไฟล์ ด้วยวิธีนี้จะมีคำขอเพียงสองคำขอเท่านั้น ก็ยังดีที่จะให้บริการไฟล์เหล่านี้ในเวอร์ชันย่อ ซึ่งมักจะมีขนาดเล็กกว่าต้นฉบับมาก เว็บแอปพลิเคชันของเราอาจใช้งานไม่ได้หากมีการแคชเนื้อหา และไคลเอ็นต์จะได้รับเวอร์ชันที่ล้าสมัย
วิธีดั้งเดิมวิธีหนึ่งในการแก้ปัญหาเหล่านี้คือการรวมเนื้อหาแต่ละประเภทเข้าเป็นกลุ่มโดยใช้โปรแกรมแก้ไขข้อความ จากนั้นเรียกใช้ผลลัพธ์ผ่านบริการตัวย่อ เช่น http://jscompress.com/ สิ่งนี้พิสูจน์ให้เห็นว่าน่าเบื่อมากที่จะทำอย่างต่อเนื่องในระหว่างกระบวนการพัฒนา การปรับปรุงเล็กน้อยแต่น่าสงสัยคือการโฮสต์เซิร์ฟเวอร์ minifier ของเราเอง โดยใช้หนึ่งในแพ็คเกจที่มีอยู่ใน GitHub จากนั้นเราก็สามารถทำสิ่งที่ค่อนข้างคล้ายกับต่อไปนี้:
<script src="min/f=js/site.js,js/module1.js"></script>
สิ่งนี้จะให้บริการไฟล์ที่ถูกย่อขนาดให้กับลูกค้าของเรา แต่ไม่สามารถแก้ปัญหาการแคชได้ นอกจากนี้ยังทำให้เกิดการโหลดเพิ่มเติมบนเซิร์ฟเวอร์ เนื่องจากเซิร์ฟเวอร์ของเราจะต้องต่อและย่อไฟล์ต้นทางทั้งหมดซ้ำๆ กันในทุกคำขอ
ทำงานอัตโนมัติด้วย Gulp.js
แน่นอน เราสามารถทำได้ดีกว่าวิธีใดวิธีหนึ่งจากสองวิธีนี้ สิ่งที่เราต้องการจริงๆ คือการรวมกลุ่มโดยอัตโนมัติและรวมไว้ในขั้นตอนการสร้างของโครงการ เราต้องการลงเอยด้วยกลุ่มเนื้อหาที่สร้างไว้ล่วงหน้าซึ่งลดขนาดแล้วและพร้อมให้บริการ เรายังต้องการบังคับให้ลูกค้ารับเนื้อหาที่รวมไว้เวอร์ชันล่าสุดในทุกคำขอ แต่เรายังคงต้องการใช้ประโยชน์จากการแคชถ้าเป็นไปได้ โชคดีสำหรับเรา Gulp.js สามารถจัดการกับมันได้ ในบทความที่เหลือ เราจะสร้างโซลูชันที่จะใช้ประโยชน์จาก Gulp.js ในการต่อและย่อไฟล์ เราจะใช้ปลั๊กอินเพื่อทำลายแคชเมื่อมีการอัปเดต
เราจะสร้างไดเร็กทอรีและโครงสร้างไฟล์ต่อไปนี้ในตัวอย่างของเรา:
public/ |- build/ |- js/ |- bundle-{hash}.js |- css/ |- stylesheet-{hash}.css assets/ |- js/ |- vendor/ |- jquery.js |- site.js |- module1.js |- module2.js |- css/ |- main.css |- custom.css gulpfile.js package.json
ไฟล์ gulpfile.js คือที่ที่เราจะกำหนดงานที่อึกจะทำเพื่อเรา package.json
ถูกใช้โดย npm เพื่อกำหนดแพ็คเกจของแอปพลิเคชันของเราและติดตามการขึ้นต่อกันที่เราจะติดตั้ง ไดเร็กทอรีสาธารณะคือสิ่งที่ควรกำหนดค่าให้เผชิญกับเว็บ ไดเรกทอรีทรัพย์สินเป็นที่ที่เราจะจัดเก็บไฟล์ต้นฉบับของเรา ในการใช้ Gulp ในโครงการ เราจะต้องติดตั้งผ่าน npm และบันทึกเป็นการพึ่งพานักพัฒนาสำหรับโครงการ เรายังต้องการเริ่มต้นด้วยปลั๊กอิน concat
สำหรับอึก ซึ่งจะทำให้เราสามารถเชื่อมไฟล์หลายๆ ไฟล์เป็นไฟล์เดียวได้
ในการติดตั้งสองรายการนี้ เราจะเรียกใช้คำสั่งต่อไปนี้:
npm install --save-dev gulp gulp-concat
ต่อไป เราจะเริ่มเขียนเนื้อหาของ gulpfile.js
var gulp = require('gulp'); var concat = require('gulp-concat'); gulp.task('pack-js', function () { return gulp.src(['assets/js/vendor/*.js', 'assets/js/main.js', 'assets/js/module*.js']) .pipe(concat('bundle.js')) .pipe(gulp.dest('public/build/js')); }); gulp.task('pack-css', function () { return gulp.src(['assets/css/main.css', 'assets/css/custom.css']) .pipe(concat('stylesheet.css')) .pipe(gulp.dest('public/build/css')); }); gulp.task('default', ['pack-js', 'pack-css']);
ที่นี่ เรากำลังโหลดไลบรารีอึกและปลั๊กอิน concat จากนั้นเรากำหนดสามงาน
งานแรก ( pack-js
) กำหนดโพรซีเดอร์เพื่อบีบอัดซอร์สไฟล์ JavaScript หลายไฟล์เป็นบันเดิลเดียว เราแสดงรายการไฟล์ต้นทางซึ่งจะถูก globbed อ่านและต่อกันตามลำดับที่ระบุ เราไปป์ไปที่ปลั๊กอิน concat เพื่อรับไฟล์สุดท้ายชื่อ bundle.js
สุดท้าย เราบอกให้อึกเขียนไฟล์ไปยัง public/build/js
งานที่สอง ( pack-css
) ทำสิ่งเดียวกันกับด้านบน แต่สำหรับสไตล์ชีต CSS มันบอกให้อึกเก็บเอาต์พุตที่ต่อกันเป็น stylesheet.css
ใน public/build/css
งานที่สาม ( default
) คืองานที่ Gulp ทำงานเมื่อเราเรียกใช้โดยไม่มีข้อโต้แย้ง ในพารามิเตอร์ที่สอง เราส่งรายการงานอื่นๆ เพื่อดำเนินการเมื่อมีการเรียกใช้งานเริ่มต้น
มาวางโค้ดนี้ลงใน gulpfile.js โดยใช้โปรแกรมแก้ไขซอร์สโค้ดที่เราใช้ตามปกติ จากนั้นบันทึกไฟล์ลงในรูทของแอปพลิเคชัน
ต่อไปเราจะเปิดบรรทัดคำสั่งและเรียกใช้:
gulp
หากเราดูไฟล์ของเราหลังจากรันคำสั่งนี้ เราจะพบไฟล์ใหม่สองไฟล์: public/build/js/bundle.js
และ public/build/css/stylesheet.css
เป็นการต่อกันของไฟล์ต้นทางของเรา ซึ่งช่วยแก้ปัญหาเดิมบางส่วน อย่างไรก็ตาม พวกมันจะไม่ถูกย่อให้เล็กสุด และยังไม่มีการป้องกันแคช มาเพิ่มการลดขนาดอัตโนมัติกันเถอะ
การเพิ่มประสิทธิภาพสินทรัพย์ที่สร้างขึ้น
เราต้องการปลั๊กอินใหม่สองตัว ในการเพิ่มเราจะเรียกใช้คำสั่งต่อไปนี้:
npm install --save-dev gulp-clean-css gulp-minify
ปลั๊กอินแรกใช้สำหรับย่อ CSS และปลั๊กอินที่สองสำหรับย่อขนาด JavaScript อันแรกใช้แพ็คเกจ clean-css และอันที่สองใช้แพ็คเกจ UglifyJS2 เราจะโหลดสองแพ็คเกจนี้ใน gulpfile.js ของเราก่อน:
var minify = require('gulp-minify'); var cleanCss = require('gulp-clean-css');
จากนั้นเราจะต้องใช้มันในงานของเราก่อนที่เราจะเขียนผลลัพธ์ลงดิสก์:
.pipe(minify()) .pipe(cleanCss())
gulpfile.js ควรมีลักษณะดังนี้:
var gulp = require('gulp'); var concat = require('gulp-concat'); var minify = require('gulp-minify'); var cleanCss = require('gulp-clean-css'); gulp.task('pack-js', function () { return gulp.src(['assets/js/vendor/*.js', 'assets/js/main.js', 'assets/js/module*.js']) .pipe(concat('bundle.js')) .pipe(minify()) .pipe(gulp.dest('public/build/js')); }); gulp.task('pack-css', function () { return gulp.src(['assets/css/main.css', 'assets/css/custom.css']) .pipe(concat('stylesheet.css')) .pipe(cleanCss()) .pipe(gulp.dest('public/build/css')); }); gulp.task('default', ['pack-js', 'pack-css']);
มาวิ่งอึกกันอีกครั้ง เราจะเห็นว่าไฟล์ stylesheet.css
ถูกบันทึกในรูปแบบย่อเล็กสุด และไฟล์ bundle.js
ยังคงถูกบันทึกเหมือนเดิม เราจะสังเกตเห็นว่าตอนนี้เรายังมี bundle-min.js ซึ่งถูกย่อให้เล็กสุด เราต้องการเฉพาะไฟล์ที่ย่อเล็กสุด และเราต้องการบันทึกเป็น bundle.js
ดังนั้นเราจะแก้ไขโค้ดของเราด้วยพารามิเตอร์เพิ่มเติม:

.pipe(minify({ ext:{ min:'.js' }, noSource: true }))
ตามเอกสารประกอบปลั๊กอิน gulp-minify (https://www.npmjs.com/package/gulp-minify) สิ่งนี้จะตั้งชื่อที่ต้องการสำหรับเวอร์ชันย่อเล็กสุด และบอกปลั๊กอินว่าอย่าสร้างเวอร์ชันที่มีแหล่งที่มาดั้งเดิม หากเราลบเนื้อหาของไดเร็กทอรีบิลด์และเรียกใช้อึกจากบรรทัดคำสั่งอีกครั้ง เราจะลงเอยด้วยไฟล์ย่อสองไฟล์ เราเพิ่งเสร็จสิ้นการใช้ขั้นตอนการย่อขนาดของกระบวนการสร้างของเรา
แคช Busting
ต่อไป เราจะต้องการเพิ่มการป้องกันแคช และเราจะต้องติดตั้งปลั๊กอินสำหรับสิ่งนั้น:
npm install --save-dev gulp-rev
และต้องการมันในไฟล์อึกของเรา:
var rev = require('gulp-rev');
การใช้ปลั๊กอินค่อนข้างยุ่งยาก เราต้องไพพ์เอาต์พุตที่ย่อเล็กสุดผ่านปลั๊กอินก่อน จากนั้น เราต้องเรียกปลั๊กอินอีกครั้ง หลังจากที่เราเขียนผลลัพธ์ลงดิสก์ ปลั๊กอินเปลี่ยนชื่อไฟล์เพื่อให้แท็กด้วยแฮชที่ไม่ซ้ำกัน และสร้างไฟล์รายการ ไฟล์ Manifest เป็นแผนที่ที่แอปพลิเคชันของเราสามารถใช้เพื่อกำหนดชื่อไฟล์ล่าสุดที่เราควรอ้างถึงในโค้ด HTML ของเรา หลังจากที่เราแก้ไขไฟล์ gulp ไฟล์ควรมีลักษณะดังนี้:
var gulp = require('gulp'); var concat = require('gulp-concat'); var minify = require('gulp-minify'); var cleanCss = require('gulp-clean-css'); var rev = require('gulp-rev'); gulp.task('pack-js', function () { return gulp.src(['assets/js/vendor/*.js', 'assets/js/main.js', 'assets/js/module*.js']) .pipe(concat('bundle.js')) .pipe(minify({ ext:{ min:'.js' }, noSource: true })) .pipe(rev()) .pipe(gulp.dest('public/build/js')) .pipe(rev.manifest()) .pipe(gulp.dest('public/build')); }); gulp.task('pack-css', function () { return gulp.src(['assets/css/main.css', 'assets/css/custom.css']) .pipe(concat('stylesheet.css')) .pipe(cleanCss()) .pipe(rev()) .pipe(gulp.dest('public/build/css')) .pipe(rev.manifest()) .pipe(gulp.dest('public/build')); }); gulp.task('default', ['pack-js', 'pack-css']);
มาลบเนื้อหาของไดเร็กทอรีบิลด์ของเราและเรียกใช้อึกอีกครั้ง เราจะพบว่าตอนนี้เรามีไฟล์สองไฟล์ที่มีแฮชแท็กติดอยู่กับชื่อไฟล์แต่ละชื่อ และไฟล์ manifest.json ที่บันทึกเป็น public/build
หากเราเปิดไฟล์ Manifest เราจะเห็นว่ามีการอ้างอิงถึงไฟล์ย่อและแท็กของเราเท่านั้น สิ่งที่เกิดขึ้นคือแต่ละงานเขียนไฟล์รายการแยกกัน และหนึ่งในนั้นจบลงด้วยการเขียนทับอีกไฟล์หนึ่ง เราจะต้องแก้ไขงานด้วยพารามิเตอร์เพิ่มเติมที่จะบอกให้พวกเขาค้นหาไฟล์รายการที่มีอยู่และรวมข้อมูลใหม่เข้าไปหากมีอยู่ ไวยากรณ์สำหรับสิ่งนั้นค่อนข้างซับซ้อน ดังนั้น มาดูกันว่าโค้ดควรมีลักษณะอย่างไร แล้วจึงค่อยอธิบาย:
var gulp = require('gulp'); var concat = require('gulp-concat'); var minify = require('gulp-minify'); var cleanCss = require('gulp-clean-css'); var rev = require('gulp-rev'); gulp.task('pack-js', function () { return gulp.src(['assets/js/vendor/*.js', 'assets/js/main.js', 'assets/js/module*.js']) .pipe(concat('bundle.js')) .pipe(minify({ ext:{ min:'.js' }, noSource: true })) .pipe(rev()) .pipe(gulp.dest('public/build/js')) .pipe(rev.manifest('public/build/rev-manifest.json', { merge: true })) .pipe(gulp.dest('')); }); gulp.task('pack-css', function () { return gulp.src(['assets/css/main.css', 'assets/css/custom.css']) .pipe(concat('stylesheet.css')) .pipe(cleanCss()) .pipe(rev()) .pipe(gulp.dest('public/build/css')) .pipe(rev.manifest('public/build/rev-manifest.json', { merge: true })) .pipe(gulp.dest('')); }); gulp.task('default', ['pack-js', 'pack-css']);
เรากำลังส่งเอาต์พุตไปที่ rev.manifest()
ก่อน สิ่งนี้จะสร้างไฟล์ที่ติดแท็กแทนไฟล์ที่เรามีมาก่อน เรากำลังจัดเตรียมเส้นทางที่ต้องการของ rev-manifest.json
และบอก rev.manifest()
รวมเข้ากับไฟล์ที่มีอยู่ หากมี จากนั้นเรากำลังบอกให้อึกเขียนรายการไปยังไดเร็กทอรีปัจจุบัน ซึ่ง ณ จุดนั้นจะเป็นแบบสาธารณะ/บิวด์ ปัญหาเส้นทางเกิดจากจุดบกพร่องที่กล่าวถึงในรายละเอียดเพิ่มเติมบน GitHub
ขณะนี้เรามีการลดขนาดอัตโนมัติ ไฟล์ที่แท็ก และไฟล์รายการ ทั้งหมดนี้จะช่วยให้เราสามารถส่งไฟล์ไปยังผู้ใช้ได้รวดเร็วยิ่งขึ้น และทำลายแคชของไฟล์ทุกครั้งที่เราทำการแก้ไข มีเพียงสองปัญหาที่เหลืออยู่แม้ว่า
ปัญหาแรกคือถ้าเราทำการแก้ไขใด ๆ กับไฟล์ต้นฉบับของเรา เราจะได้รับไฟล์ที่ติดแท็กใหม่ แต่ไฟล์เก่าจะยังคงอยู่เช่นกัน เราต้องการวิธีที่จะลบไฟล์ย่อขนาดเก่าโดยอัตโนมัติ มาแก้ปัญหานี้โดยใช้ปลั๊กอินที่จะให้เราลบไฟล์:
npm install --save-dev del
เราจะต้องใช้มันในโค้ดของเราและกำหนดงานใหม่สองงาน งานหนึ่งสำหรับไฟล์ต้นฉบับแต่ละประเภท:
var del = require('del'); gulp.task('clean-js', function () { return del([ 'public/build/js/*.js' ]); }); gulp.task('clean-css', function () { return del([ 'public/build/css/*.css' ]); });
จากนั้นเราจะตรวจสอบให้แน่ใจว่างานใหม่ทำงานเสร็จก่อนงานหลักสองอย่างของเรา:
gulp.task('pack-js', ['clean-js'], function () { gulp.task('pack-css', ['clean-css'], function () {
หากเราเรียกใช้ gulp
อีกครั้งหลังจากการปรับเปลี่ยนนี้ เราจะมีเพียงไฟล์ย่อขนาดล่าสุด
ปัญหาที่สองคือเราไม่ต้องการให้อึกทึกทุกครั้งที่เราทำการเปลี่ยนแปลง เพื่อแก้ปัญหานี้ เราจะต้องกำหนดงานของผู้เฝ้าสังเกต:
gulp.task('watch', function() { gulp.watch('assets/js/**/*.js', ['pack-js']); gulp.watch('assets/css/**/*.css', ['pack-css']); });
เราจะเปลี่ยนคำจำกัดความของงานเริ่มต้นของเราด้วย:
gulp.task('default', ['watch']);
หากตอนนี้เราเรียกใช้อึกจากบรรทัดคำสั่ง เราจะพบว่ามันไม่ได้สร้างอะไรจากการเรียกใช้อีกต่อไป เนื่องจากตอนนี้เรียกใช้งานตัวตรวจสอบซึ่งจะคอยดูไฟล์ต้นฉบับของเราสำหรับการเปลี่ยนแปลงใดๆ และสร้างเมื่อตรวจพบการเปลี่ยนแปลงเท่านั้น หากเราลองเปลี่ยนซอร์สไฟล์ใดๆ ของเราแล้วดูที่คอนโซลของเราอีกครั้ง เราจะเห็นว่างาน pack-js
และ pack-css
ทำงานโดยอัตโนมัติพร้อมกับการขึ้นต่อกัน
ตอนนี้ สิ่งที่เราต้องทำคือโหลดไฟล์ manifest.json ในแอปพลิเคชันของเรา และรับชื่อไฟล์ที่แท็กจากนั้น วิธีที่เราดำเนินการนั้นขึ้นอยู่กับภาษาแบ็คเอนด์และสแต็กเทคโนโลยีของเราโดยเฉพาะ และจะค่อนข้างใช้งานไม่ได้ ดังนั้นเราจะไม่พูดถึงในรายละเอียด อย่างไรก็ตาม แนวคิดทั่วไปก็คือ เราสามารถโหลดไฟล์ Manifest ลงในอาร์เรย์หรืออ็อบเจ็กต์ จากนั้นจึงกำหนดฟังก์ชันตัวช่วยที่จะช่วยให้เราเรียกใช้เนื้อหาที่มีเวอร์ชันจากเทมเพลตของเราในลักษณะที่คล้ายกับต่อไปนี้:
gulp('bundle.js')
เมื่อเราทำเช่นนั้นแล้ว เราจะไม่ต้องกังวลกับแท็กที่เปลี่ยนไปในชื่อไฟล์ของเราอีกต่อไป และเราจะสามารถมุ่งเน้นไปที่การเขียนโค้ดคุณภาพสูง
ซอร์สโค้ดสุดท้ายของบทความนี้ พร้อมด้วยเนื้อหาตัวอย่างบางส่วน สามารถพบได้ในที่เก็บ GitHub นี้
บทสรุป
ในบทความนี้ เราได้พูดถึงวิธีการใช้ระบบอัตโนมัติที่ใช้ Gulp สำหรับกระบวนการสร้างของเรา ฉันหวังว่าสิ่งนี้จะเป็นประโยชน์กับคุณและช่วยให้คุณพัฒนากระบวนการสร้างที่ซับซ้อนยิ่งขึ้นในแอปพลิเคชันของคุณเอง
โปรดจำไว้ว่า Gulp เป็นเพียงหนึ่งในเครื่องมือที่สามารถใช้เพื่อจุดประสงค์นี้ และยังมีเครื่องมืออื่นๆ อีกมากมาย เช่น Grunt, Browserify และ Webpack พวกเขาแตกต่างกันไปตามวัตถุประสงค์และในขอบเขตของปัญหาที่พวกเขาสามารถแก้ไขได้ บางอย่างสามารถแก้ปัญหาที่ Gulp ไม่สามารถทำได้ เช่น การรวมโมดูล JavaScript ที่มีการพึ่งพาที่สามารถโหลดได้ตามต้องการ สิ่งนี้เรียกว่า "การแยกโค้ด" และเป็นการปรับปรุงแนวคิดในการให้บริการไฟล์ขนาดใหญ่ไฟล์เดียวกับทุกส่วนของโปรแกรมของเราในทุกหน้า เครื่องมือเหล่านี้ค่อนข้างซับซ้อนแต่อาจจะครอบคลุมในอนาคต ในโพสต์ต่อไปนี้ เราจะพูดถึงวิธีทำให้แอปพลิเคชันของเราใช้งานได้โดยอัตโนมัติ