Webpack 打包 Javascript 詳細介紹

跡憶客 發表於 2021-12-06
JavaScript Webpack

本篇我們主要介紹Webpack打包 Javascript。當然,除了可以打包Javascript之外,webpack還可以打包html。但是這不是我們本篇的重點。我們可以參考 Webpack HTML 打包介紹

現在讓我們擴充套件一個專案——webpack-example(點選 Webpack 安裝 檢視該專案的初始化),併為 entry 和 output 屬性指定自定義名稱。 在 webpack.config.js 中,我們在 plugins 屬性之前新增以下內容:

entry: {
  main: path.resolve(__dirname, './src/app.js'),
},
output: {
  filename: '[name].bundle.js',
  path: path.resolve(__dirname, 'deploy')
},

 

完整程式碼如下所示

webpack.config.js 檔案

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

module.exports = {
    entry: {
        main: path.resolve(__dirname, './src/app.js'),
      },
      output: {
        filename: '[name].bundle.js',
        path: path.resolve(__dirname, 'deploy')
      },
    plugins: [
        new HtmlWebpackPlugin({
            hash: true,
            title: 'Webpack - 跡憶客(jiyik.com)',
        })
    ],
};

 

這裡我們不使用 html 模板

在這裡,我們將入口檔案更改為 app.js,並將輸出資料夾更改為 deploy 。 我們還稍微調整了生成的包檔案的名稱。 現在它將以條目的名稱(“main”)開頭,後跟單詞“bundle”和 .js 副檔名。

現在我們建立 src/component.js 檔案:

src/component.js

export default (text = "Hello, Webpack!!") => {
  const element = document.createElement("h1");

  element.innerHTML = text;

  return element;
};

 

接下來,我們將現在專案中的 index.js 重新命名為 app.js 以此反映我們的更改,並將其內容替換為以下內容:

app.js

import component from './component';

document.body.appendChild(component());

 

現在讓我們執行 webpack,看一下發生了什麼

$ npm run dev

> [email protected]1.0.0 dev /Users/jiyik/workspace/js/webpack-example
> webpack --mode development

asset main.bundle.js 4.33 KiB [emitted] (name: main)
asset index.html 552 bytes [emitted] [compared for emit]
runtime modules 670 bytes 3 modules
cacheable modules 235 bytes
  ./src/app.js 77 bytes [built] [code generated]
  ./src/component.js 158 bytes [built] [code generated]
webpack 5.54.0 compiled successfully in 142 ms

 

執行之後我們會在專案目錄中看到生成了deploy資料夾,其中包含靜態html檔案和js檔案

Webpack 打包 Javascript 詳細介紹

 

此時我們在瀏覽器中執行 deploy/index.html 檔案,結果如下:

Webpack 打包 Javascript 詳細介紹

 

此外,如果我們檢查 index.html 的原始碼,我們會看到 script 標籤中 src 屬性的值更新為 main.bundle.js

此時,我們可以刪除 webpack 最初生成的 dist 資料夾,因為我們不再需要它了。


將 ES6 轉換成 ES5

接下來我們將瞭解如何將 ES6 轉換為適用於所有瀏覽器的 ES5 的程式碼。 讓我們從執行以下命令開始:

$ npm run dev -- --devtool inline-source-map

在這裡,我執行 webpack 並將 devtool 選項設定為 inline-source-map 以使程式碼更具可讀性。 這樣可以更清楚地演示從 ES6 到 ES5 的程式碼轉換。

下面我們開啟 main.bundle.js

main.bundle.js 部分程式碼

/***/ "./src/component.js":
/*!**************************!*\
  !*** ./src/component.js ***!
  \**************************/
/***/ ((__unused_webpack_module, __webpack_exports__, __webpack_require__) => {

__webpack_require__.r(__webpack_exports__);
/* harmony export */ __webpack_require__.d(__webpack_exports__, {
/* harmony export */   "default": () => (__WEBPACK_DEFAULT_EXPORT__)
/* harmony export */ });
/* harmony default export */ const __WEBPACK_DEFAULT_EXPORT__ = ((text = "Hello, Webpack!") => {
    const element = document.createElement("h1");
  
    element.innerHTML = text;
  
    return element;
  });

/***/ })

/******/     });

 

如您所見,來自 component.js 模組的現代 ES6 特性(箭頭函式和 const 宣告)預設不會轉換為符合 ES5 的程式碼。 為了讓我們的程式碼在舊瀏覽器中工作,我們必須新增 Babel 載入器:

$ npm install babel-loader @babel/core @babel/preset-env --save-dev

 

Webpack 打包 Javascript 詳細介紹

 

然後在 webpack.config.js 檔案中,在 output 項之後新增 module 項,如下所示

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

 

當我們為 webpack loader 定義規則時,通常需要定義三個主要屬性:

  • test - 它描述了應該轉換什麼樣的檔案。
  • exclude - 它定義了不應該從載入器處理的檔案。
  • use - 它告訴應該對匹配的模組使用哪個載入器。 在這裡,我們還可以設定載入器選項,就像我們剛剛完成的 presets 選項一樣。

webpack.config.js

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

module.exports = {
    entry: {
        main: path.resolve(__dirname, './src/app.js'),
    },
    output: {
        filename: '[name].bundle.js',
        path: path.resolve(__dirname, 'deploy')
    },
    module: {
        rules: [
          {
            test: /\.js$/,
            exclude: /node_modules/,
            use: {
              loader: 'babel-loader',
              options: {
                presets: ['@babel/preset-env']
              }
            }
          },
        ]
    },
    plugins: [
        new HtmlWebpackPlugin({
            title: 'Webpack - 跡憶客(jiyik.com)',
        })
    ],
};

 

然後在執行 webpack 看會生成什麼樣的檔案

$ npm run dev -- --devtool inline-source-map

> [email protected]1.0.0 dev /Users/liuhanzeng/workspace/js/webpack-example
> webpack --mode development "--devtool" "inline-source-map"

asset main.bundle.js 7.02 KiB [emitted] (name: main)
asset index.html 257 bytes [compared for emit]
runtime modules 670 bytes 3 modules
cacheable modules 301 bytes
  ./src/app.js 76 bytes [built] [code generated]
  ./src/component.js 225 bytes [built] [code generated]
webpack 5.54.0 compiled successfully in 1340 ms

 

這次 main.bundle.js 中的程式碼:

/***/ "./src/component.js":
/*!**************************!*\
  !*** ./src/component.js ***!
  \**************************/
/***/ ((__unused_webpack_module, __webpack_exports__, __webpack_require__) => {

__webpack_require__.r(__webpack_exports__);
/* harmony export */ __webpack_require__.d(__webpack_exports__, {
/* harmony export */   "default": () => (__WEBPACK_DEFAULT_EXPORT__)
/* harmony export */ });
/* harmony default export */ const __WEBPACK_DEFAULT_EXPORT__ = (function () {
  var text = arguments.length > 0 && arguments[0] !== undefined ? arguments[0] : "Hello, Webpack!";
  var element = document.createElement("h1");
  element.innerHTML = text;
  return element;
});

/***/ })

/******/     });

非常完美。 現在我們可以使用現代 JS 功能(ES6),webpack 將轉換我們的程式碼,以便它可以被舊瀏覽器執行。

 

完整的Webpack可以參考 Webpack 教程