0%

[week 13] 前端工具之三 - gulp、webpack

本篇為 [FE201] 前端中階:那些前端會用到的工具們 這門課程的學習筆記。如有錯誤歡迎指正。

前言

在使用新工具之前,大致會依照下列步驟:

  1. 安裝工具
  2. 閱讀官方文件
  3. 更改設定檔

gulp:整合流程

gulp 是一個前端自動化構建工具,開發者可使用它來建構自動化工作流程。

為什麼需要 glup?

為了將工作流程自動化,也就是整合前端開發環境。藉由簡化工作量,可讓開發者將重點放在功能的開發上。

例如下列功能:

  • 讓網頁自動重新整理
  • 編譯 SASS 、程式碼檢測
  • 壓縮 CSS, JS, 圖檔
  • 自訂任務流程..

如何安裝

Node.js 是一個讓 Javascript 運行在服務端的開發平台。

由於 gulp 是基於 Node.js 進行開發,使用前必須先安裝 node.js、npm。接著即可按照官方文件 Quick Start 安裝 gulp:

  1. npm install --global gulp-cli:安裝 gulp-cli
  2. 開啟需使用 gulp 的專案資料夾
  3. npm init:進行初始化
  4. npm install --save-dev gulp:安裝 gulp package
  5. gulp --version:可使用指令檢查是否安裝成功

gulp 提供的 API

  • gulp.task 執行工作
  • gulp.src 執行資料來源
  • gulp.dest 執行結果位置
  • gulp.watch 監視執行過程中,資料是否變更

參考資料:

  • 什麼是gulp,怎麼使用gulp | 程式前沿
  • 前端中階:gulp. 介紹| by Hugh’s Program learning | Medium

uglify 與 minify

uglify

  • gulp-uglify:混淆並壓縮 JavaScript 檔案
  • 壓縮:減少代碼量,減少網絡下載時間以及瀏覽器的解析時間
  • 混淆:藉此提升代碼閱讀難度,有一定程度的保護代碼作用

配置範例:

let gulp = require('gulp'),               // 載入 gulp
let gulpUglify = require('gulp-uglify');  // 載入 gulp-uglify

gulp.task('script', function () {
    gulp.src('javascript/original/*.js')        // 指定要處理的原始 JavaScript 檔案目錄
        .pipe(gulpUglify())                     // 將 JavaScript 做最小化
        .pipe(gulp.dest('javascript/minify'));  // 指定最小化後的 JavaScript 檔案目錄
});

minify

  • gulp-minify-css:壓縮 CSS 檔案
  • 壓縮:藉由去掉空格、換行符號等,縮短變數跟 code 長度,以節省瀏覽器 Parse(解析)時間
  • 但更新的版本已經不太適用,改為使用 gulp-clean-css

配置範例:

let gulp = require('gulp');
let cleanCSS = require('gulp-clean-css');

gulp.task('minify-css', () => {
  return gulp.src('styles/*.css')
    .pipe(cleanCSS({compatibility: 'ie8'}))
    .pipe(gulp.dest('dist'));
});

參考資料:

  • 【gulp-uglify】最小化 JavaScript | gulp 學習筆記
  • 前端也需要編譯?Transpile、Compile、Minify、Uglify 基本介紹
  • 亦敵亦友的uglify
  • [試著把切版專案升級到 gulp4.0 吧] Day21 CSS 的處理:談壓縮 CSS 與 gulp-clean-css

Webpack:打包程式碼

什麼是 Webpack

Webpack 是一套模組整合工具。可將零散的 JavaScript 模組打包,然後在瀏覽器上運行,解決舊瀏覽器不支援部分新語法的問題,也利於後續管理與維護。

此外,Webpack 也提供了前端開發缺乏的模組化開發方式,可將各種靜態資源視為模組,例如 JS、CSS、SASS、圖片檔等,透過不同的 loader 將資源轉換並載入,再利用 Webpack 進行打包成 JS 檔,生成最佳化過的程式碼。

為什麼要使用 Webpack?

若不使用 Webpack,可能會遇到下列問題:

  1. 瀏覽器支援度:由於部分瀏覽器不支援 ES6 模組,例如 IE,若要使用 import、export 等語法,則需要其他工具來進行轉換。
  2. 不易引用套件:若想要引用他人撰寫的 library 套件,需考慮相容性問題,以及可能造成命名衝突。

如何安裝

跟著官方教學步驟 Getting Started 安裝 webpack:

mkdir webpack-demo
cd webpack-demo
npm init -y
npm install webpack webpack-cli --save-dev

相關語法

dev:代表開發時才會使用,打包後就不會出現在裡面(記錄在 package.json -> devDependencies)

  • 下載 jquery
npm install jquery webpack-cli --save-dev
  • css-Loader:用來解析 CSS 檔
npm install --save-dev css-loader
npm install --save-dev style-loader
  • babel-loader
npm install -D babel-loader @babel/core @babel/preset-env
  • sass-loader
npm install sass-loader sass webpack --save-dev

執行步驟

  • 需要進行編譯的檔案,通常不會直接放在根目錄,而是會先放在 src(source code),使用工具轉換後再放到其他地方。
  • webpack 預設執行檔案路徑如下:
webpack-demo/src/index.js

以 index.js 引入 utils.js 為例:

utils.js

const Utils = {
  first: function(str) {
    return str[0]
  }
}

module.exports = Utils

index.js

const utils = require('./utils')

console.log(utils.first('abc'))

在 CLI 執行 npm src/index.js 後印出 a,代表成功引入檔案。

接著以 npx webpack 執行打包,完成會自動把檔案 main.js 放在資料夾 dist。

若執行檔案 npm dist/main.js 仍會得到相同結果:

接著在 index.html 引入:

<script src="dist/main.js"></script>

即可透過 webpack 打包 module,讓我們能夠在瀏覽器上執行使用 require 語法。

webpack.config.js:預設執行檔

在安裝好 loader 後,需設定執行檔,透過指定 rules 來執行檔案:

基本設定

// webpack.config.js
const path = require('path')

module.exports = {
   mode: '',
  entry: ['./src/index'], // 在 index 檔案後的 .js 副檔名是可選的
  output: {
    path: path.join(__dirname, 'dist'),
    filename: 'bundle.js'
  }
}

屬性介紹

  • mode:使用的模式。預設為 production,代表正式生產環境版本;開發使用 development 則不會進行壓縮
  • entry:是 bundle 的進入點,entry 是一個陣列。根據需求,webpack 允許可以有多個進入點,來產生多個 bundle 檔案。
  • output:宣告 webpack 輸出的形式
    • path:存放 bundle 檔案的位置
    • filename:bundle 檔案名稱

接著以打包 style.css 和 index.js 所需進行的設定為例:

const path = require('path');

module.exports = {
  mode: '',
  entry: './src/index.js',
  output: {
    filename: 'main.js',    // 輸出檔案名稱
    path: path.resolve(__dirname, 'dist'),     // 輸出位置
  },
  // 載入 loader
  module: {
    rules: [
      {
        test: /\.css$/i,      // .css 結尾的檔案均使用 css-loader 解析
        use: ['style-loader', 'css-loader'],
      },{
        test: /\.m?js$/,      // .mjs 結尾的檔案均使用 babel-loader 解析
        exclude: /(node_modules|bower_components)/,
        use: {
          loader: 'babel-loader',
          options: {
            presets: ['@babel/preset-env']
          }
        }
      }
    ],
  },
};

參考資料:

  • webpack 新手教學之淺談模組化與 snowpack
  • Webpack 初學者教學課程Part1 · Webpack Tutorial 繁體中文
  • Webpack教學 (一) :什麼是Webpack? 能吃嗎?

總結:gulp vs webpack

gulp

  • 是一套任務管理工具(task manager)
  • 目的:提供自動化與流程管理,整合前端開發環境,藉由簡化工作量,可讓開發者將重點放在功能的開發上
  • 功能:提供自訂任務流程,例如 babel、scss、壓縮、重新整理、校正時間等

Webpack

  • 是一套模組整合工具(module bundler)
  • 目的:利用模組化的概念,將各種資源打包成能在瀏覽器上執行的程式碼

由此可知,兩者目標其實並不相同,但是均能夠達到部分功能,因此容易被混淆,例如:

  1. 使用 Babel 將 ES6 編譯成 ES5 語法
  2. 將 SASS 檔編譯成 CSS 檔
  3. 壓縮 CSS, JS, 圖檔等

簡言之,gulp 是用來管理任務,建構自動化流程的工具;而 Webpack 則是將資源打包,提供模組化開發方式。

參考資料:

  • Gulp和webpack的區別,是一種工具嗎?