เริ่มต้นใช้งาน Webpack

เผยแพร่แล้ว: 2022-03-10
สรุปโดยย่อ ↬ เบราว์เซอร์สมัยใหม่รองรับโมดูล JavaScript ได้ดี แต่ตัวรวมโมดูล เช่น webpack ยังคงเป็นส่วนสำคัญของ toolchain JavaScript มาเจาะลึกกันว่า webpack คืออะไรและใช้งานอย่างไรในเวิร์กโฟลว์การพัฒนาของคุณ

ในช่วงแรกๆ ที่มีการแนะนำโมดูลาร์ใน JavaScript ไม่มีการสนับสนุนดั้งเดิมสำหรับการเรียกใช้โมดูลภายในเบราว์เซอร์ รองรับการเขียนโปรแกรมโมดูลาร์ใน Node.js โดยใช้พิมพ์เขียว CommonJS และถูกนำมาใช้โดยผู้ที่ใช้ JavaScript สำหรับการสร้างแอปพลิเคชันฝั่งเซิร์ฟเวอร์

นอกจากนี้ยังมีโอกาสสำหรับ เว็บแอปพลิเคชันขนาดใหญ่ เนื่องจากนักพัฒนาสามารถหลีกเลี่ยงการชนกันของเนมสเปซและสร้างฐานโค้ดที่บำรุงรักษาได้มากขึ้นโดยการเขียนโค้ดในรูปแบบโมดูลาร์มากขึ้น แต่ก็ยังมีความท้าทายอยู่: ไม่สามารถใช้โมดูลต่างๆ ใน เว็บเบราว์เซอร์ ซึ่งปกติแล้ว JavaScript จะถูกเรียกใช้งาน

เพื่อแก้ปัญหานี้ โมดูลบันเดิล เช่น webpack, Parcel, Rollup และ Closure Compiler ของ Google ถูกเขียนขึ้นเพื่อสร้างกลุ่มโค้ดที่ปรับให้เหมาะสมที่สุดสำหรับเบราว์เซอร์ของผู้ใช้ปลายทางเพื่อดาวน์โหลดและดำเนินการ

การ “รวมกลุ่ม” รหัสของคุณหมายความว่าอย่างไร

โค้ด การรวมหมายถึงการรวมและการเพิ่มประสิทธิภาพหลายโมดูลให้เป็น บันเดิลที่พร้อมสำหรับการผลิต ตั้งแต่หนึ่งชุดขึ้นไป บันเดิลที่กล่าวถึงในที่นี้สามารถเข้าใจได้ดีขึ้นว่าเป็นผลิตภัณฑ์สุดท้ายของกระบวนการมัดรวมทั้งหมด

ในบทความนี้ เราจะเน้นที่ webpack ซึ่งเป็นเครื่องมือที่เขียนโดย Tobias Koppers ซึ่งเมื่อเวลาผ่านไปได้เติบโตขึ้นจนกลายเป็นเครื่องมือหลักใน toolchain JavaScript ซึ่งมักใช้ในโครงการขนาดใหญ่และขนาดเล็ก

หมายเหตุ: เพื่อให้ได้ประโยชน์จากบทความนี้ ควรทำความคุ้นเคยกับโมดูล JavaScript คุณจะต้อง ติดตั้ง Node บนเครื่องของคุณ คุณจึงสามารถติดตั้งและใช้ webpack ในเครื่องได้

webpack คืออะไร?

webpack เป็นชุดรวมโมดูลสแตติกที่ ขยายได้สูงและกำหนดค่าได้สำหรับแอปพลิเคชัน JavaScript ด้วยลักษณะที่ขยายได้ คุณสามารถเสียบตัวโหลดภายนอกและปลั๊กอินเพื่อให้บรรลุเป้าหมายสุดท้ายของคุณ

ดังที่แสดงในภาพประกอบด้านล่าง webpack จะผ่านแอปพลิเคชันของคุณจาก จุดเริ่มต้นราก สร้างกราฟการพึ่งพาที่ประกอบด้วยการพึ่งพาที่ดำเนินการโดยตรงหรือโดยอ้อมกับไฟล์รูท และสร้างบันเดิลที่ปรับให้เหมาะสมของโมดูลที่รวมกัน

ภาพประกอบกราฟการพึ่งพา webpack
ภาพประกอบของกราฟกราฟการพึ่งพาอาศัยกันที่สร้างโดย webpack โดยเริ่มจากจุดเริ่มต้น (ตัวอย่างขนาดใหญ่)

เพื่อให้เข้าใจว่า webpack ทำงานอย่างไร เราต้องเข้าใจคำศัพท์บางคำที่ใช้ (ตรวจสอบอภิธานศัพท์ของ webpack คำศัพท์นี้มักใช้ในบทความนี้ และมักใช้อ้างอิงในเอกสารประกอบของ webpack ด้วย

  • ก้อน
    ก้อน หมายถึงรหัสที่แยกจากโมดูล รหัสนี้จะถูกเก็บไว้ใน ไฟล์ก้อน โดยทั่วไปจะใช้ Chunks เมื่อทำการแยกโค้ดด้วย webpack
  • โมดูล
    โมดูล เป็นส่วนย่อยของแอปพลิเคชันของคุณซึ่งคุณนำเข้าเพื่อทำงานหรือฟังก์ชันเฉพาะ Webpack รองรับโมดูลที่สร้างโดยใช้ไวยากรณ์ ES6, CommonJS และ AMD
  • ทรัพย์สิน
    คำว่า ทรัพย์สิน มักใช้ใน webpack และตัวรวมกลุ่มอื่น ๆ โดยทั่วไป หมายถึง ไฟล์สแตติกที่ รวมไว้ระหว่างกระบวนการสร้าง ไฟล์เหล่านี้อาจเป็นอะไรก็ได้ตั้งแต่รูปภาพไปจนถึงฟอนต์ หรือแม้แต่ไฟล์วิดีโอ เมื่อคุณอ่านบทความนี้ต่อไป คุณจะเห็นวิธีที่เราใช้ตัวโหลดเพื่อทำงานกับสินทรัพย์ประเภทต่างๆ

การอ่านที่แนะนำ : Webpack - A Detailed Introduction

เมื่อเราเข้าใจแล้วว่า webpack คืออะไรและใช้คำศัพท์อะไร เรามาดูกันว่ามันนำไปใช้อย่างไรในการรวบรวมไฟล์การกำหนดค่าสำหรับโปรเจ็กต์สาธิต

หมายเหตุ : คุณจะต้องติดตั้ง webpack-cli เพื่อใช้ webpack บนเครื่องของคุณ หากไม่ได้ติดตั้ง คุณจะได้รับแจ้งจากเทอร์มินัลให้ติดตั้ง

ไฟล์กำหนดค่า webpack

นอกจากการใช้ webpack-cli จากเทอร์มินัลแล้ว คุณยังสามารถใช้ webpack ในโครงการของคุณผ่านไฟล์การกำหนดค่าได้อีกด้วย แต่ด้วย webpack เวอร์ชันล่าสุด เราสามารถใช้งานได้ในโปรเจ็กต์ของเรา โดยไม่ต้อง มีไฟล์กำหนดค่า เราสามารถใช้ webpack เป็นค่าของหนึ่งในคำสั่งในไฟล์ package.json ของเราโดยไม่ต้องตั้งค่าสถานะใดๆ ด้วยวิธีนี้ webpack จะถือว่าไฟล์ entry point ของโปรเจ็กต์ของคุณอยู่ในไดเร็กทอรี src มันจะรวมไฟล์รายการและส่งออกไปยังไดเร็กทอรี dist

ตัวอย่างคือไฟล์ package.json ตัวอย่างด้านล่าง ที่นี่ เราใช้ webpack เพื่อรวมแอปพลิเคชันโดยไม่มีไฟล์กำหนดค่า:

 { "name" : "Smashing Magazine", "main": "index.js", "scripts": { "build" : "webpack" }, "dependencies" : { "webpack": "^5.24.1" } }

เมื่อรันคำสั่ง build ในไฟล์ด้านบน webpack จะรวมไฟล์ไว้ในไดเร็กทอรี src/index.js และส่งออกไปยังไฟล์ main.js ในไดเร็กทอรี dist อย่างไรก็ตาม webpack นั้นมีความยืดหยุ่นมากกว่านั้นมาก เราสามารถ เปลี่ยนจุดเริ่มต้น ปรับจุดส่งออก และปรับแต่งพฤติกรรมเริ่มต้นอื่น ๆ อีกมากมายโดยแก้ไขไฟล์การกำหนดค่าด้วยแฟล็ก -- config

ตัวอย่างคือคำสั่ง build ที่แก้ไขจากไฟล์ package.json ด้านบน:

 "build" : "webpack --config webpack.config.js"

ด้านบน เราได้เพิ่มแฟล็ก webpack.config.js --config ไฟล์ที่มีการกำหนดค่า webpack ใหม่

ไฟล์ webpack.config.js ยังไม่มีอยู่จริง ดังนั้นเราต้องสร้างมันในไดเร็กทอรีแอปพลิเคชันของเราและวางโค้ดต่อไปนี้ด้านล่างลงในไฟล์

 # webpack.config.js const path = require("path") module.exports = { entry : "./src/entry", output : { path: path.resolve(__dirname, "dist"), filename: "output.js" } }

ไฟล์ด้านบนยังคงกำหนดค่า webpack เพื่อรวมไฟล์ JavaScript ของคุณ แต่ตอนนี้เราสามารถกำหนดเส้นทางของไฟล์ รายการ และเอาต์พุตที่กำหนดเองได้ แทนที่จะเป็นเส้นทางเริ่มต้นที่ใช้โดย webpack

สิ่งที่ควรทราบเกี่ยวกับไฟล์การกำหนดค่า webpack:

  • ไฟล์คอนฟิกูเรชันของ webpack เป็นไฟล์ JavaScript ซึ่งเขียนเป็นโมดูล JavaScript CommonJS
  • ไฟล์คอนฟิกูเรชันของ webpack เอ็กซ์พอร์ตอ็อบเจ็กต์ที่ มีคุณสมบัติหลายอย่าง แต่ละคุณสมบัติเหล่านี้ถูกใช้เป็นตัวเลือกในการกำหนดค่า webpack เมื่อรวมโค้ดของคุณ ตัวอย่างคือตัวเลือก mode :
    • mode
      ในการกำหนดค่า ตัวเลือกนี้ใช้เพื่อตั้งค่า NODE_ENV ระหว่างการรวมกลุ่ม สามารถมีมูลค่า production หรือ development เมื่อไม่ได้ระบุ จะมี ค่าเริ่มต้น เป็น none สิ่งสำคัญที่ควรทราบคือ webpack จะรวมกลุ่มเนื้อหาของคุณ แตกต่างกันไป ตามค่าของ mode ตัวอย่างเช่น webpack จะแคชบันเดิลของคุณโดยอัตโนมัติในโหมดการพัฒนาเพื่อปรับให้เหมาะสมและลดเวลาบันเดิล อ้างถึงส่วนโหมดของเอกสารประกอบ webpack เพื่อดูบันทึกการเปลี่ยนแปลงของตัวเลือกที่ใช้โดยอัตโนมัติในแต่ละโหมด
เพิ่มเติมหลังกระโดด! อ่านต่อด้านล่าง↓

webpack Concepts

เมื่อกำหนดค่า webpack ผ่าน CLI หรือผ่านไฟล์การกำหนดค่า มี สี่แนวคิดหลัก ที่ใช้เป็น ตัวเลือก ส่วนถัดไปของบทความนี้เน้นที่แนวคิดเหล่านี้และนำไปใช้เมื่อสร้างการกำหนดค่าสำหรับเว็บแอปพลิเคชันตัวอย่าง

โปรดทราบว่าแนวคิดที่อธิบายด้านล่างมีความคล้ายคลึงกันกับชุดรวมโมดูลอื่นๆ ตัวอย่างเช่น เมื่อใช้ Rollup กับไฟล์การกำหนดค่า คุณสามารถกำหนดช่องใส่เพื่อระบุจุดเริ่มต้นของกราฟการพึ่งพา ออบเจ็กต์เอาต์พุตที่กำหนดค่าวิธีและตำแหน่งที่จะวางชิ้นส่วนที่ผลิตขึ้น และอ็อบเจ็กต์ปลั๊กอินสำหรับเพิ่มปลั๊กอินภายนอก

รายการ

ฟิลด์ รายการ ในไฟล์คอนฟิกูเรชันของคุณมีพาธไปยังไฟล์ที่ webpack เริ่มสร้าง กราฟการพึ่งพา จากไฟล์รายการนี้ webpack จะดำเนินการไปยังโมดูลอื่น ๆ ซึ่งขึ้นอยู่กับจุดเริ่มต้นโดยตรงหรือโดยอ้อม

จุดเริ่มต้นการกำหนดค่าของคุณสามารถเป็นประเภทรายการเดียวโดยมีค่าไฟล์ เดียว คล้ายกับตัวอย่างด้านล่าง:

 # webpack.configuration.js module.exports = { mode: "development", entry : "./src/entry" }

จุดเริ่มต้นยังสามารถเป็น ประเภทรายการหลักหลายรายการ ที่มีอาร์เรย์ที่มีเส้นทางไปยังไฟล์รายการต่างๆ คล้ายกับตัวอย่างด้านล่าง:

 # webpack.configuration.js const webpack = require("webpack") module.exports = { mode: "development", entry: [ './src/entry', './src/entry2' ], }

เอาท์พุต

เช่นเดียวกับชื่อที่สื่อถึง ฟิลด์ เอาต์พุต ของการกำหนดค่าคือที่ที่บันเดิลที่สร้างขึ้นจะใช้งานได้ ฟิลด์นี้มีประโยชน์เมื่อคุณมีหลายโมดูล แทนที่จะใช้ชื่อที่สร้างโดย webpack คุณสามารถ ระบุชื่อไฟล์ของคุณเอง ได้

 # webpack.configuration.js const webpack = require("webpack"); const path = require("path"); module.exports = { mode: "development", entry: './src/entry', output: { filename: "webpack-output.js", path: path.resolve(__dirname, "dist"), } }

รถตัก

ตามค่าเริ่มต้น webpack จะเข้าใจเฉพาะไฟล์ JavaScript ภายในแอปพลิเคชันของคุณ อย่างไรก็ตาม webpack จะถือว่าทุกไฟล์ที่นำเข้าเป็นโมดูลเป็นการ พึ่งพา และเพิ่มลงในกราฟการพึ่งพา ในการประมวลผลทรัพยากรแบบคงที่ เช่น รูปภาพ ไฟล์ CSS ไฟล์ JSON หรือแม้แต่ข้อมูลของคุณที่จัดเก็บไว้ใน CSV Webpack ใช้ตัวโหลดเพื่อ "โหลด" ไฟล์เหล่านี้ลงในบันเดิล

ตัวโหลดมีความยืดหยุ่นเพียงพอที่จะใช้สำหรับสิ่งต่างๆ มากมาย ตั้งแต่การแปลงรหัส ES ของคุณ ไปจนถึงการจัดการสไตล์แอปพลิเคชันของคุณ หรือแม้แต่การทับโค้ดของคุณด้วย ESLint

มี สามวิธีในการใช้ตัวโหลด ภายในแอปพลิเคชันของคุณ หนึ่งในนั้นคือผ่านวิธีการ อินไลน์ โดยการนำเข้าโดยตรงในไฟล์ ตัวอย่างเช่น เพื่อลดขนาดรูปภาพ เราสามารถใช้ตัว image-loader ในไฟล์ได้โดยตรงดังที่แสดงด้านล่าง:

 // main.js import ImageLoader from 'image-loader'

อีกตัวเลือกหนึ่งที่ต้องการใช้ตัวโหลดคือการใช้ไฟล์กำหนดค่า webpack ของคุณ ด้วยวิธีนี้ คุณสามารถทำสิ่งต่างๆ ได้มากขึ้นด้วยตัวโหลด เช่น การระบุประเภทไฟล์ที่ คุณต้องการใช้ตัวโหลด ในการทำเช่นนี้ เราสร้างอาร์เรย์ rules และระบุตัวโหลดในออบเจ็กต์ โดยแต่ละรายการจะมีฟิลด์ทดสอบที่มีนิพจน์ regex ที่ตรงกับเนื้อหาที่เราต้องการใช้ตัวโหลด

ตัวอย่างเช่น ด้วย image-loader เดอร์ที่นำเข้าโดยตรงในตัวอย่างก่อนหน้านี้ เราสามารถใช้มันในไฟล์คอนฟิกูเรชันของ webpack พร้อมตัวเลือกพื้นฐานที่สุดจากเอกสารประกอบ ซึ่งจะมีลักษณะดังนี้:

 # webpack.config.js const webpack = require("webpack") const path = require("path") const merge = require("webpack-merge") module.exports = { mode: "development", entry: './src/entry', output: { filename: "webpack-output.js", path: path.resolve(__dirname, "dist"), }, module: { rules: [ { test: /\.(jpe?g|png|gif|svg)$/i, use: [ 'img-loader' ] } ] } }

พิจารณาให้ละเอียดยิ่งขึ้นที่ฟิลด์ test ในออบเจ็กต์ที่มีตัว image-loader ด้านบน เราสามารถระบุนิพจน์ regex ที่ตรงกับไฟล์ภาพทั้งหมด: jp(e)g , png , gif และ svg format

วิธีสุดท้ายของการใช้ Loaders คือผ่าน CLI ด้วย --module-bind

Awesome-webpack readme มี รายการ ตัวโหลดอย่างละเอียดที่คุณสามารถใช้กับ webpack ได้ โดยแต่ละส่วนจะถูกจัดกลุ่มเป็นหมวดหมู่ของการดำเนินการที่พวกเขาดำเนินการ ด้านล่างนี้เป็นเพียงตัวอย่างบางส่วนที่คุณอาจพบว่ามีประโยชน์ในแอปพลิเคชันของคุณ:

  • ตัวโหลดแบบตอบสนอง คุณจะพบว่าตัวโหลดนี้มีประโยชน์มากเมื่อเพิ่มรูปภาพให้พอดีกับไซต์หรือแอปที่ตอบสนองของคุณ มันสร้างภาพหลายภาพขนาดต่างๆ จากภาพเดียวและส่งคืน srcset ที่ตรงกับภาพเพื่อใช้ในขนาดหน้าจอแสดงผลที่เหมาะสม
  • Babel-loader
    ใช้สำหรับแปลงรหัส JavaScript ของคุณจากไวยากรณ์ ECMA สมัยใหม่เป็น ES5
  • GraphQL-ตัวโหลด
    หากคุณเป็นคนที่คลั่งไคล้ GraphQL คุณจะพบว่าตัวโหลดนี้มีประโยชน์มากในขณะที่โหลดไฟล์ .graphql ของคุณที่มีสคีมา GraphQL การสืบค้น และการกลายพันธุ์ของคุณ — พร้อมด้วยตัวเลือกในการเปิดใช้งานการตรวจสอบความถูกต้อง

ปลั๊กอิน

การใช้ ปลั๊กอิน ช่วยให้คอมไพเลอร์ webpack ทำงานบนชิ้นส่วนที่ สร้างจากโมดูลที่รวมกลุ่มได้ แม้ว่า webpack จะไม่ใช่ task runner แต่ด้วยปลั๊กอิน เราสามารถดำเนินการบางอย่างที่กำหนดเองได้ ซึ่งตัวโหลดไม่สามารถทำได้เมื่อรวมโค้ดเข้าด้วยกัน

ตัวอย่างของปลั๊กอิน webpack คือ ProgressPlugin ในตัวของ webpack มีวิธีปรับแต่งความคืบหน้าซึ่งพิมพ์ออกมาในคอนโซลระหว่างการคอมไพล์

 # webpack.config.js const webpack = require("webpack") const path = require("path") const merge = require("webpack-merge") const config = { mode: "development", entry: './src/entry', output: { filename: "webpack-output.js", path: path.resolve(__dirname, "dist"), }, module: { rules: [ { test: /\.(jpe?g|png|gif|svg)$/i, use: [ 'img-loader' ] } ] }, plugins: [ new webpack.ProgressPlugin({ handler: (percentage, message ) => { console.info(percentage, message); }, }) ] } module.exports = config

ด้วยปลั๊กอิน Progress ในการกำหนดค่าด้านบน เราได้จัดเตรียม ฟังก์ชันตัวจัดการ ที่จะพิมพ์เปอร์เซ็นต์การคอมไพล์และข้อความไปยังคอนโซลระหว่างกระบวนการคอมไพล์

เอาต์พุตปลั๊กอินความคืบหน้าของ webpack
เอาต์พุตของเชลล์ที่แสดงข้อความจากปลั๊กอินความคืบหน้าของ webpack (ตัวอย่างขนาดใหญ่)

ด้านล่างนี้คือปลั๊กอินบางส่วนจาก Awesome-webpack readme ซึ่งคุณจะพบว่ามีประโยชน์ในแอปพลิเคชัน webpack ของคุณ

  • ออฟไลน์ปลั๊กอิน
    ปลั๊กอินนี้ใช้พนักงานบริการก่อนหรือ AppCache ที่พร้อมใช้งานเพื่อมอบประสบการณ์ออฟไลน์สำหรับโครงการที่มีการจัดการ webpack
  • Purgecss-webpack-plugin
    ปลั๊กอินนี้มีประโยชน์เมื่อพยายามเพิ่มประสิทธิภาพโปรเจ็กต์ webpack ของคุณ เนื่องจากจะลบ CSS ที่ไม่ได้ใช้ภายในแอปพลิเคชันของคุณในระหว่างการคอมไพล์

ณ จุดนี้ เรามีการกำหนดค่า webpack แรกของเราสำหรับแอปพลิเคชันขนาดค่อนข้างเล็กที่ตั้งค่าอย่างสมบูรณ์ มาพิจารณากันต่อไปว่าเราจะทำบางสิ่งกับ webpack ในแอปพลิเคชันของเราได้อย่างไร

การจัดการสภาพแวดล้อมที่หลากหลาย

ในแอปพลิเคชันของคุณ คุณอาจต้องกำหนดค่า webpack แตกต่างกันสำหรับ สภาพแวดล้อมการพัฒนาหรือการ ใช้งานจริง ตัวอย่างเช่น คุณอาจไม่ต้องการให้ webpack ส่งออกบันทึกการเตือนเล็กน้อยทุกครั้งที่มีการปรับใช้ใหม่กับไปป์ไลน์การรวมอย่างต่อเนื่องในสภาพแวดล้อมการผลิตของคุณ

มีหลายวิธีในการบรรลุเป้าหมายดังกล่าว ตามที่ webpack และชุมชนแนะนำ วิธีหนึ่งคือการ แปลงไฟล์การกำหนดค่าของคุณ เพื่อส่งออกฟังก์ชันที่ส่งคืนวัตถุ วิธีนี้ สภาพแวดล้อมปัจจุบันจะถูกส่งผ่านไปยังฟังก์ชันโดยคอมไพเลอร์ webpack เป็นพารามิเตอร์แรก และตัวเลือกอื่นๆ เป็นพารามิเตอร์ที่สอง

วิธีการจัดการสภาพแวดล้อม webpack ของคุณจะมีประโยชน์ หากมีการดำเนินการบางอย่างที่คุณต้องการดำเนินการแตกต่างออกไปตามสภาพแวดล้อมปัจจุบัน อย่างไรก็ตาม สำหรับแอปพลิเคชันขนาดใหญ่ที่มีการกำหนดค่าที่ซับซ้อนมากขึ้น คุณอาจลงเอยด้วยการกำหนดค่าที่มีข้อความสั่งแบบมีเงื่อนไขมากมาย

ข้อมูลโค้ดด้านล่างแสดงตัวอย่างวิธีจัดการสภาพแวดล้อม production และ development ในไฟล์เดียวกันโดยใช้วิธี functions

 // webpack.config.js module.exports = function (env, args) { return { mode : env.production ? 'production' : 'development', entry: './src/entry', output: { filename: "webpack-output.js", path: path.resolve(__dirname, "dist"), }, plugins: [ env.development && ( new webpack.ProgressPlugin({ handler: (percentage, message ) => { console.info(percentage, message); }, }) ) ] } }

เมื่อดูฟังก์ชันที่ส่งออกในข้อมูลโค้ดด้านบน คุณจะเห็นว่าพารามิเตอร์ env ที่ส่งผ่านไปยังฟังก์ชันนั้นใช้งานกับโอเปอเรเตอร์แบบไตรภาคเพื่อเปลี่ยนค่าอย่างไร มันถูกใช้เพื่อตั้งค่าโหมด webpack ก่อน จากนั้นจึงใช้เพื่อเปิดใช้งาน ProgressPlugin ในโหมดการพัฒนาเท่านั้น

อีกวิธีที่ยอดเยี่ยมในการจัดการกับสภาพแวดล้อม การผลิต และ การพัฒนา ของคุณคือการสร้าง ไฟล์การกำหนดค่าที่แตกต่างกัน สำหรับทั้งสองสภาพแวดล้อม เมื่อเราทำเสร็จแล้ว เราสามารถใช้คำสั่งเหล่านี้กับคำสั่งต่างๆ ในสคริปต์ package.json เมื่อรวมแอปพลิเคชันเข้าด้วยกัน ลองดูตัวอย่างด้านล่าง:

 { "name" : "smashing-magazine", "main" : "index.js" "scripts" : { "bundle:dev" : "webpack --config webpack.dev.config.js", "bundle:prod" : "webpack --config webpack.prod.config.js" }, "dependencies" : { "webpack": "^5.24.1" } }

ใน package.json ด้านบน เรามี คำสั่งสคริปต์สองคำสั่ง แต่ละคำสั่งใช้ไฟล์การกำหนดค่าที่แตกต่างกันซึ่งเขียนขึ้นเพื่อจัดการกับสภาพแวดล้อมเฉพาะเมื่อรวมเนื้อหาของแอปพลิเคชัน ตอนนี้คุณสามารถรวมกลุ่มแอปพลิเคชันของคุณโดยใช้ npm run bundle:dev ในโหมดการพัฒนา หรือ npm run bundle:prod เมื่อสร้างบันเดิลที่พร้อมสำหรับใช้งานจริง

เมื่อใช้วิธีที่สอง คุณจะ หลีกเลี่ยงคำสั่งเงื่อนไขที่ นำมาใช้เมื่อส่งคืนอ็อบเจ็กต์การกำหนดค่าจากฟังก์ชัน อย่างไรก็ตาม ตอนนี้คุณยังต้องรักษาไฟล์การกำหนดค่าไว้หลายไฟล์

แยกไฟล์กำหนดค่า

ณ จุดนี้ ไฟล์การกำหนดค่า webpack ของเราอยู่ที่ 38 บรรทัดของโค้ด (LOC) สิ่งนี้ค่อนข้างดีสำหรับแอปพลิเคชันสาธิตที่มีตัวโหลดเดียวและปลั๊กอินตัวเดียว

สำหรับแอปพลิเคชันขนาดใหญ่ ไฟล์การกำหนดค่า webpack ของเราจะยาวกว่านั้น มาก โดยจะมีตัวโหลดและปลั๊กอินหลายตัวพร้อมตัวเลือกที่กำหนดเองแต่ละตัว เพื่อให้ไฟล์การกำหนดค่าสะอาดและอ่านได้ เราสามารถ แบ่งการกำหนดค่าออกเป็นวัตถุขนาดเล็ก ในหลายไฟล์ จากนั้นใช้แพ็คเกจ webpack-merge เพื่อรวมออบเจ็กต์การกำหนดค่าเป็นไฟล์ฐานเดียว

เพื่อนำไปใช้กับโปรเจ็กต์ webpack ของเรา เราสามารถแบ่งไฟล์คอนฟิกูเรชันเดี่ยวออกเป็นไฟล์ขนาดเล็กสามไฟล์: ไฟล์หนึ่งสำหรับตัวโหลด ไฟล์หนึ่งสำหรับปลั๊กอิน และไฟล์สุดท้ายเป็นไฟล์คอนฟิกูเรชันพื้นฐานที่เรารวมไฟล์อื่นๆ อีกสองไฟล์ไว้ด้วยกัน

สร้างไฟล์ webpack.plugin.config.js และวางโค้ดด้านล่างลงในไฟล์เพื่อใช้ปลั๊กอินที่มีตัวเลือกเพิ่มเติม

 // webpack.plugin.config.js const webpack = require('webpack') const plugin = [ new webpack.ProgressPlugin({ handler: (percentage, message ) => { console.info(percentage, message); }, }) ] module.exports = plugin

ด้านบน เรามีปลั๊กอินตัวเดียวที่เราแยกจากไฟล์ webpack.configuration.js

จากนั้น สร้างไฟล์ webpack.loader.config.js ด้วยรหัสด้านล่างสำหรับ webpack loaders

 // webpack.loader.config.js const loader = { module: { rules: [ { test: /\.(jpe?g|png|gif|svg)$/i, use: [ 'img-loader' ] } ] } }

ในบล็อกโค้ดด้านบน เราย้าย webpack img-loader ไปเป็นไฟล์แยกต่างหาก

สุดท้าย ให้สร้างไฟล์ webpack.base.config.js โดยที่การกำหนดค่าอินพุตและเอาต์พุตพื้นฐานสำหรับแอปพลิเคชัน webpack จะถูกเก็บไว้ข้างๆ ไฟล์ที่สร้างขึ้นสองไฟล์ด้านบน

 // webpack.base.config.js const path = require("path") const merge = require("webpack-merge") const plugins = require('./webpack.plugin.config') const loaders = require('./webpack.loader.config') const config = merge(loaders, plugins, { mode: "development", entry: './src/entry', output: { filename: "webpack-output.js", path: path.resolve(__dirname, "dist"), } }); module.exports = config

เมื่อเหลือบมองที่ไฟล์ webpack ด้านบน คุณจะสังเกตเห็นได้ว่าไฟล์มีขนาดเล็กเพียงใดเมื่อเปรียบเทียบกับไฟล์ webpack.config.js ดั้งเดิม ตอนนี้ สามส่วนหลักของการกำหนดค่าถูกแบ่งออกเป็นไฟล์ขนาดเล็กลง และสามารถใช้แยกกันได้

การเพิ่มประสิทธิภาพงานสร้างขนาดใหญ่

ในขณะที่คุณทำงานบนแอปพลิเคชันของคุณต่อไปในช่วงระยะเวลาหนึ่ง แอปพลิเคชันของคุณจะมีคุณลักษณะและขนาดที่ใหญ่ขึ้นอย่างแน่นอน เมื่อเกิดเหตุการณ์นี้ขึ้น ไฟล์ใหม่จะถูกสร้างขึ้น ไฟล์เก่าจะถูกแก้ไขหรือจัดองค์ประกอบใหม่ และจะมีการติดตั้งแพ็คเกจภายนอกใหม่ ซึ่งทั้งหมดนี้นำไปสู่การ เพิ่มขนาดบันเดิ ลที่ปล่อยออกมาจากเว็บแพ็ค

ตามค่าเริ่มต้น webpack จะพยายามเพิ่มประสิทธิภาพบันเดิลในนามของคุณโดยอัตโนมัติ หากโหมดการกำหนดค่าของคุณถูกตั้งค่าเป็นการ production ตัวอย่างเช่น เทคนิคหนึ่งที่ webpack นำไปใช้โดยค่าเริ่มต้น (เริ่มต้นด้วย webpack 4+) เพื่อปรับให้เหมาะสมและลดขนาดบันเดิลของคุณคือ Tree-Shaking โดยพื้นฐานแล้ว มันคือเทคนิคการเพิ่มประสิทธิภาพที่ใช้ในการลบโค้ดที่ไม่ได้ใช้ ในระดับง่าย ๆ ระหว่างการรวมกลุ่ม คำสั่งนำเข้าและส่งออกจะถูกใช้เพื่อ ตรวจจับโมดูลที่ไม่ได้ใช้ ก่อนที่จะลบออกจากบันเดิลที่ปล่อยออกมา

คุณยังสามารถเพิ่มประสิทธิภาพบันเดิลแอปพลิเคชันของคุณ ด้วยตนเอง โดยเพิ่มออบเจ็กต์การปรับให้ optimization ด้วยฟิลด์บางฟิลด์ในไฟล์การกำหนดค่าของคุณ ส่วนการปรับให้เหมาะสมของเอกสารประกอบ webpack มีรายการฟิลด์ทั้งหมดที่คุณสามารถใช้ในออบเจ็กต์การ optimization ให้เหมาะสมเพื่อเพิ่มประสิทธิภาพแอปพลิเคชันของคุณ ลองพิจารณาหนึ่งใน 20 ฟิลด์เอกสาร

  • minimize
    ฟิลด์บูลีนนี้ใช้เพื่อสั่งให้ webpack ย่อขนาดบันเดิลให้เล็กสุด ตามค่าเริ่มต้น webpack จะพยายามทำให้สำเร็จโดยใช้ TerserPlugin ซึ่งเป็นแพ็คเกจการลดขนาดโค้ดที่มาพร้อมกับ webpack
การลดขนาดใช้กับการลดขนาดโค้ดของคุณโดยการลบข้อมูลที่ไม่จำเป็นออกจากโค้ด ซึ่งจะช่วยลดขนาดโค้ดที่สร้างขึ้นหลังจากกระบวนการ

นอกจากนี้เรายังสามารถใช้ minifiers ที่ต้องการอื่นๆ โดยการเพิ่มฟิลด์อาร์เรย์ minimizer ภายในออบเจ็กต์ optimization ตัวอย่างคือการใช้ Uglifyjs-webpack-plugin ด้านล่าง

 // webpack.config.js const Uglify = require("uglifyjs-webpack-plugin") module.exports = { optimization { minimize : true, minimizer : [ new Uglify({ cache : true, test: /\.js(\?.*)?$/i, }) ] } }

ด้านบน uglifyjs-webpack-plugin ถูกใช้เป็นตัวย่อที่มีสองตัวเลือกที่ค่อนข้างสำคัญ ขั้นแรก การเปิดใช้งาน cache หมายความว่า Uglify จะย่อขนาดไฟล์ที่มีอยู่เมื่อมีการเปลี่ยนแปลงใหม่เท่านั้น และตัวเลือก test จะระบุประเภทไฟล์เฉพาะที่เราต้องการลดขนาด

หมายเหตุ: uglifyjs-webpack-plugin แสดงรายการตัวเลือกที่พร้อมใช้งานเมื่อย่อขนาดโค้ดของคุณด้วย

การสาธิตการเพิ่มประสิทธิภาพเล็กน้อย

มาลองปรับแต่งแอปพลิเคชันสาธิตด้วยตนเองโดยใช้บางฟิลด์ในโครงการขนาดใหญ่เพื่อดูความแตกต่าง แม้ว่าเราจะไม่ลงลึกในการปรับแอปพลิเคชันให้เหมาะสม เราจะเห็นความแตกต่างของขนาดบันเดิลระหว่างเมื่อใช้งาน webpack ในโหมด development กับเมื่ออยู่ในโหมด production

สำหรับการสาธิตนี้ เราจะใช้แอปพลิเคชันเดสก์ท็อปที่สร้างด้วย Electron ซึ่งยังใช้ React.js สำหรับ UI ของมันด้วย ซึ่งทั้งหมดนั้นมาพร้อมกับ webpack Electron และ React.js ฟังดูเหมือนเป็นการรวมกันที่ค่อนข้างหนักและอาจสร้างบันเดิลที่ใหญ่กว่า

หมายเหตุ : หากคุณกำลังเรียนรู้เกี่ยวกับ อิเลคตรอน เป็นครั้งแรก บทความนี้ จะให้ข้อมูลเชิงลึกที่ดีว่า อิเลคตรอน คืออะไร และคุณจะใช้งานอิเลคตรอนเพื่อสร้างแอปพลิเคชันเดสก์ท็อปข้ามแพลตฟอร์มได้อย่างไร

หากต้องการลองใช้การสาธิตในเครื่อง ให้โคลนแอปพลิเคชันจากที่เก็บ GitHub และติดตั้งการพึ่งพาโดยใช้คำสั่งด้านล่าง

 # clone repository git clone https://github.com/vickywane/webpack-react-demo.git # change directory cd demo-electron-react-webpack # install dependencies npm install

แอปพลิเคชันเดสก์ท็อปค่อนข้างง่ายด้วยหน้าเดียวที่มีสไตล์โดยใช้องค์ประกอบที่มีสไตล์ เมื่อเปิดแอปพลิเคชันเดสก์ท็อปด้วยคำสั่ง yarn start หน้าเดียวจะแสดงรายการรูปภาพที่ดึงมาจาก CDN ดังที่แสดงด้านล่าง

แอปพลิเคชันอิเล็กตรอนพร้อมการแสดงตัวอย่างอินเทอร์เฟซ React.js
การแสดงตัวอย่างรูปภาพบนเดสก์ท็อปภายในแอปพลิเคชัน Electron พร้อมอินเทอร์เฟซ React.js (ตัวอย่างขนาดใหญ่)

มาสร้าง บันเดิลการพัฒนา ของแอปพลิเคชันนี้ก่อนโดยไม่ต้องปรับให้เหมาะสมด้วยตนเองเพื่อวิเคราะห์ขนาดบันเดิลสุดท้าย

การรัน yarn build:dev จากเทอร์มินัลในไดเร็กทอรีโครงการจะสร้างบันเดิลการพัฒนา นอกจากนี้ มันจะพิมพ์สถิติต่อไปนี้ไปยังเทอร์มินัลของคุณ:

คอมไพเลอร์ webpack บันทึกในโหมดการพัฒนา
บันทึกเทอร์มินัลจากคอมไพเลอร์ webpack เมื่อรันในโหมดการพัฒนาโดยไม่ต้องปรับให้เหมาะสมด้วยตนเอง (ตัวอย่างขนาดใหญ่)

คำสั่งจะแสดงสถิติของการคอมไพล์ทั้งหมดและบันเดิลที่ปล่อยออกมา

จดบันทึกกลุ่ม mainRenderer.js ที่ 1.11 Mebibyte (ประมาณ 1.16 MB) mainRenderer เป็นจุดเริ่มต้นสำหรับแอปพลิเคชันอิเล็กตรอน

ต่อไป ให้เพิ่ม uglifyjs-webpack-plugin เป็นปลั๊กอินที่ติดตั้งในไฟล์ webpack.base.config.js สำหรับการลดขนาดโค้ด

 // webpack.base.config.js const Uglifyjs = require("uglifyjs-webpack-plugin") module.exports = { plugins : [ new Uglifyjs({ cache : true }) ] }

สุดท้าย ให้รันบันเดิลแอปพลิเคชันด้วย webpack ในโหมด production การรันคำสั่ง yarn build:prod จากเทอร์มินัลของคุณจะส่งข้อมูลด้านล่างไปยังเทอร์มินัลของคุณ

บันทึกคอมไพเลอร์ webpack ในโหมดการผลิต
บันทึกจากคอมไพเลอร์ webpack เมื่อแอปพลิเคชันถูกรวมเข้าด้วยกันในโหมดใช้งานจริงพร้อมการลดขนาดโค้ด (ตัวอย่างขนาดใหญ่)

จดบันทึกกลุ่ม mainRenderer ในครั้งนี้ มันลดลงเหลือ 182 กิบิไบต์อย่างมาก (ประมาณ 186 KB) และนั่นคือมากกว่า 80% ของขนาดก้อน mainRenderer ที่ปล่อยออกมาก่อนหน้านี้!

มาดูภาพบันเดิลที่ปล่อยออกมาเพิ่มเติมโดยใช้ webpack-bundler-analyzer ติดตั้งปลั๊กอินโดยใช้คำสั่ง yarn add webpack-bundle-analyzer และแก้ไขไฟล์ webpack.base.config.js เพื่อให้มีโค้ดด้านล่างซึ่งเพิ่มปลั๊กอิน

 // webpack.base.config.js const Uglifyjs = require("uglifyjs-webpack-plugin"); const BundleAnalyzerPlugin = require("webpack-bundle-analyzer"); .BundleAnalyzerPlugin; const config = { plugins: [ new Uglifyjs({ cache : true }), new BundleAnalyzerPlugin(), ] }; module.exports = config;

รัน yarn build:prod จากเทอร์มินัลของคุณเพื่อให้แอปพลิเคชันถูกรวมเข้าด้วยกันใหม่ โดยค่าเริ่มต้น webpack-bundle-analyzer จะเริ่มต้นเซิร์ฟเวอร์ HTTP ที่ให้บริการภาพรวมของบันเดิลในเบราว์เซอร์ของคุณ

การแสดงตัววิเคราะห์บันเดิลของบันเดิลที่ปล่อยออกมา
ตัววิเคราะห์บันเดิล webpack แสดงการแสดงบันเดิลและไฟล์ที่ปล่อยออกมาภายใน (ตัวอย่างขนาดใหญ่)

จากภาพด้านบน เราจะเห็นการ แสดงภาพ ของบันเดิลที่ปล่อยออกมาและขนาดไฟล์ภายในบันเดิล ในวิชวล เราสามารถสังเกตได้ว่าในโฟลเดอร์ node_modules ไฟล์ที่ใหญ่ที่สุดคือ react-dom.production.min.js ตามด้วย stylis.min.js

ด้วยการใช้ขนาดไฟล์ที่แสดงโดยตัววิเคราะห์ เราจะมีความคิดที่ดีขึ้นว่าแพ็คเกจใดที่ติดตั้งไว้มีส่วนสำคัญของบันเดิล จากนั้นเราสามารถหาวิธีเพิ่มประสิทธิภาพหรือแทนที่ด้วยแพ็คเกจที่เบากว่า

หมายเหตุ: เอกสารประกอบ ของ webpack-analyzer-plugin แสดงรายการวิธีการอื่นๆ ที่ใช้ได้สำหรับการแสดงการวิเคราะห์ที่สร้างจากบันเดิลที่ปล่อยออกมาของคุณ

ชุมชน webpack

จุดแข็งอย่างหนึ่งของ webpack คือ ชุมชนนักพัฒนาขนาดใหญ่ที่ อยู่เบื้องหลัง และสิ่งนี้เป็นประโยชน์อย่างมากสำหรับนักพัฒนาที่ลองใช้ webpack เป็นครั้งแรก เช่นเดียวกับบทความนี้ มีบทความ คำแนะนำ และแหล่งข้อมูลมากมายพร้อมเอกสารประกอบที่ทำหน้าที่เป็นแนวทางที่ดีเมื่อใช้ webpack

ตัวอย่างเช่น คู่มือประสิทธิภาพบิลด์จากบล็อกของ webpack มีเคล็ดลับในการเพิ่มประสิทธิภาพการสร้าง webpack ของคุณและกรณีศึกษาของ Slack (แม้ว่าจะเก่าไปหน่อย) จะอธิบายว่า webpack ได้รับการปรับให้เหมาะสมที่ Slack อย่างไร

แหล่งข้อมูลของชุมชนหลายแห่งจะอธิบายส่วนต่างๆ ของเอกสารประกอบของ webpack โดยให้ตัวอย่างโปรเจ็กต์ตัวอย่างเพื่อแสดงว่ามีการใช้คุณสมบัติของ webpack อย่างไร ตัวอย่างคือบทความเกี่ยวกับ Webpack 5 Module Federation ซึ่งอธิบายวิธีใช้คุณลักษณะ Module Federation ใหม่ของ webpack ในแอปพลิเคชัน React

สรุป

หลังจากเจ็ดปีของการดำรงอยู่ webpack ได้พิสูจน์ตัวเองอย่างแท้จริงว่าเป็นส่วนสำคัญของ toolchain JavaScript ที่ใช้โดยโครงการจำนวนมาก บทความนี้ให้ข้อมูลคร่าวๆ เกี่ยวกับสิ่งที่เราสามารถทำได้ด้วยลักษณะที่ยืดหยุ่นและขยายได้ของ webpack

ครั้งต่อไปที่คุณต้องเลือกชุดรวมโมดูลสำหรับแอปพลิเคชันของคุณ หวังว่าคุณจะเข้าใจแนวคิดหลักบางประการของ Webpack ได้ดีขึ้น ปัญหาที่แก้ไขได้ และขั้นตอนในการตั้งค่าไฟล์การกำหนดค่าของคุณ

อ่านเพิ่มเติม เกี่ยวกับ SmashingMag:

  • Webpack - บทนำโดยละเอียด
  • สร้าง PWA ด้วย Webpack และ Workbox
  • การตั้งค่า TypeScript สำหรับโปรเจ็กต์ React สมัยใหม่โดยใช้ Webpack
  • วิธีควบคุมเครื่องจักร: ทำงานอย่างมีประสิทธิภาพ