打包程式碼必備 bundler : Webpack


Posted by tzutzu858 on 2021-04-21

環境建設

官網的 Getting Started
安裝

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

通常 source code 不會直接寫在根目錄,而是會有個約定俗成的目錄叫做 src

  1. 所以先在專案開個資料夾叫 src
  2. webpack 預設設定會去找 ./src/index.js 這個檔案
    webpack 會把這個當作程式的入口點
  3. 打包完會放到 dist 這個資料夾,在這個資料夾底下,可以看到 main.js
    main.js就是 webpack 幫你打包完的東西
  4. 在 index.html 裡面加上<script src="dist/main.js"></script>

這樣就算寫 require 語法,也可以順利在瀏覽器上執行囉!


webpack 打包出來的檔案看不懂怎麼辦?

想看 webpack 打包出來的檔案,可以 google 關鍵字 js beautify
隨便點一個,例如 https://beautifier.io/
main.js 不太好看的 code,複製上去按 Beautify Code 就可以還原成比較好看的 code,但因為他本來就不是要讓你看得懂,所以還是不太好看


webpack.config.js 預設執行檔

如果不是預設可以新建一個設定檔,叫做 webpack.config.js 是 webpack 預設的設定檔檔名
把下面這段貼上去

const path = require('path');

module.exports = {
  entry: './src/index.js',
  output: {
    filename: 'main.js',
    path: path.resolve(__dirname, 'dist'),
  },
};

上面程式說明 :

  • entry : 程式入口點
  • output 的 filename : 輸出的檔案名稱
  • output 的 path : 輸出路徑
  • mode : 沒有給的話預設是 production(生產正式的版本),如果值是 development,開發可以用的模式,這個模式打包出來的 code 不會做壓縮,就比較看得懂

在 package.json 裡面的 scripts 裡面添加 "build" : "webpack"
這樣比較方便打字,輸入指令 npm run build
npx webpack 是找這個資料夾底下的指令


webpack 除了可以打包自己的程式碼,還可以打包從 npm 裝的程式碼

舉幾個開發上常用的例子,實際要用時還是要去看官網文件

jquery

npm install jquery --save-dev

css-Loader:用來解析 CSS 檔

https://webpack.js.org/loaders/css-loader/

npm install --save-dev css-loader
npm install --save-dev style-loader

webpack.config.js 添加

module.exports = {
  module: {
    rules: [
      {
        test: /\.css$/i,
        use: ["style-loader", "css-loader"],
      },
    ],
  },
};

test: /\.css$/i 這個是正規表達式
use: ["style-loader", "css-loader"]
這兩行代表對所有 .css 結尾的檔案套用 style-loader", "css-loader 這兩個 loader


babel-loader

https://webpack.js.org/loaders/babel-loader/

npm install -D babel-loader @babel/core @babel/preset-env

webpack.config.js 添加

module: {
  rules: [
    {
      test: /\.m?js$/,
      exclude: /(node_modules|bower_components)/,
      use: {
        loader: 'babel-loader',
        options: {
          presets: ['@babel/preset-env']
        }
      }
    }
  ]
}

sass-loader

https://v4.webpack.js.org/guides/getting-started/

npm install sass-loader sass --save-dev

引入

import "./style.scss";

webpack.config.js 添加

module.exports = {
  module: {
    rules: [
      {
        test: /\.s[ac]ss$/i,
        use: [
          // Creates `style` nodes from JS strings
          "style-loader",
          // Translates CSS into CommonJS
          "css-loader",
          // Compiles Sass to CSS
          "sass-loader",
        ],
      },
    ],
  },
};

webpack dev server

每次改東西都要自己再 compile 不是太累了嗎?
所以加了 webpack dev server ,他會自動偵測檔案是否變動,自動 compile ,自動把更動地方重新載入
https://webpack.js.org/guides/development/#using-webpack-dev-server

安裝

npm install --save-dev webpack-dev-server

webpack.config.js

 const path = require('path');
 const HtmlWebpackPlugin = require('html-webpack-plugin');

 module.exports = {
   mode: 'development',
   entry: {
     index: './src/index.js',
     print: './src/print.js',
   },
   devtool: 'inline-source-map',
  devServer: {  // 添加這行
    contentBase: './dist', // 添加這行
  }, // 添加這行
   plugins: [
     new HtmlWebpackPlugin({
       title: 'Development',
     }),
   ],
   output: {
     filename: '[name].bundle.js',
     path: path.resolve(__dirname, 'dist'),
     clean: true,
   },
 };
This tells webpack-dev-server to serve the files from the dist directory on localhost:8080.

Tip

package.json
在 scripts 裡多添加下面這行,代表把 webpack serve 打開而已

"start": "webpack serve --open",

source maps

https://webpack.js.org/guides/development/#using-source-maps
debug 時,因為經過 webpack 過可能會不太好看的懂,這樣不好 debug,所以在 webpack.config.js 檔案裡的 module.exports 裡添加一行

devtool: 'inline-source-map',

這樣 debug 時,就可以連到原本的 source code


總結 Webpack VS gulp

雖然他們做的事情有些蠻像的,但根本上定位是不同的

gulp 任務管理工具(task manager)

管理 task
自訂任務流程,像是 babel、壓縮、重新整理、校正時間等


Webpack 模組整合工具(module bundler)

bundle打包,做資源轉換
模組機制可能會有相容性、無法兼容 npm 等等的問題,將各種 module 打包成能在瀏覽器上執行的程式碼。在 bundle 之前需要先 loader,經過 loader 把資源載入進來,Webpack 在把它包起來,在 loader 過程就可以做額外事情,像是使用 Babel loader 將 ES6 編譯成 ES5 語法、其它 loader 壓縮 CSS, JS, 圖檔等。Webpack 有點像轉接頭,使用轉接頭讓不同電腦 Mac 或其它 PC 能順利接上投影機,達到投影的目的。


引用webpack 新手教學之淺談模組化與 snowpack這篇文章裡的問題及答案,讓自己之後可以回過頭再思考一下

Q:為什麼很多專案(例如說 React)在部署前都要先 build?這個步驟在幹嘛你知道嗎?

因為原始碼沒辦法直接放上去瀏覽器(會沒有辦法執行),所以一定要經過 webpack 打包處理,打包完的檔案才能讓瀏覽器執行。


Q:你知道 require/module.exports 與 import/export 的差別嗎?require/module.exports 是一套叫做 CommonJS 的規範,Node.js 有支援,瀏覽器沒有。

import/export 是 ES6 的規範,Node.js 部分支援,瀏覽器也是部分支援。


Q:你知道 import 與 export 這兩個語法在瀏覽器上面不是隨便就能使用嗎?

有使用限制,例如說要加上 type=module,而且也沒辦法直接引入 npm 裡的模組,要把路徑寫死才能使用。而瀏覽器支援度也是一個考量,IE11 並不支援此種寫法。


Q:你知道為什麼要用 webpack 嗎?

原因有很多,例如說:
我想使用 npm 上的第三方模組
我想把圖片當作資源 import 進來
我想把 CSS 當作資源 import 進來
我想在一個地方就處理好 uglify 與 minify
不過重點其實是第一個,因為瀏覽器原生的 ES6 模組支援度沒那麼高,尤其是引入第三方模組,所以才需要透過 webpack 或其他打包工具幫我們處理好這一段。


Q:你知道 webpack 為什麼要有 loader 嗎?

因為把圖片或是 CSS 當作資源引入這並不是正式的規範,而是 webpack 自己延伸的定義。為了支援這些資源,就必須特別寫一個 loader 去載入,否則預設的 loader 只能載入 JavaScript。










Related Posts

1045. Customers Who Bought All Products

1045. Customers Who Bought All Products

 [Node.js] call back queue運作機制

[Node.js] call back queue運作機制

[10] 虛擬環境建置

[10] 虛擬環境建置


Comments