處理 TypeScript
請支持這本書:購買捐贈
(廣告,請不要封鎖。)

9 透過 TypeScript 和 webpack 建立網頁應用程式



本章說明如何透過 TypeScript 和 webpack 建立網頁應用程式。我們只會使用 DOM API,而不是特定的前端架構。

  GitHub 儲存庫:ts-demo-webpack

儲存庫 ts-demo-webpack 是我們在本章中使用的,可以從 GitHub 下載。

9.1 必要的知識

您應該大致熟悉

9.2 限制

在本章中,我們堅持 TypeScript 最佳支援的內容:CommonJS 模組,打包為腳本檔案。

9.3 儲存庫 ts-demo-webpack

儲存庫 ts-demo-webpack 的結構如下

ts-demo-webpack/
  build/   (created on demand)
  html/
    index.html
  package.json
  ts/
    src/
      main.ts
  tsconfig.json
  webpack.config.js

網頁應用程式建置方式如下

這兩個輸出工作都由 webpack 處理

9.4 package.json

package.json 包含專案的元資料

{
  "private": true,
  "scripts": {
    "tsc": "tsc",
    "tscw": "tsc --watch",
    "wp": "webpack",
    "wpw": "webpack --watch",
    "serve": "http-server build"
  },
  "dependencies": {
    "@types/lodash": "···",
    "copy-webpack-plugin": "···",
    "http-server": "···",
    "lodash": "···",
    "ts-loader": "···",
    "typescript": "···",
    "webpack": "···",
    "webpack-cli": "···"
  }
}

屬性的運作方式如下

9.5 webpack.config.js

這是我們設定 webpack 的方式

const path = require('path');
const CopyWebpackPlugin = require('copy-webpack-plugin');

module.exports = {
  ···
  entry: {
    main: "./ts/src/main.ts",
  },
  output: {
    path: path.resolve(__dirname, 'build'),
    filename: "[name]-bundle.js",
  },
  resolve: {
    // Add ".ts" and ".tsx" as resolvable extensions.
    extensions: [".ts", ".tsx", ".js"],
  },
  module: {
    rules: [
      // all files with a `.ts` or `.tsx` extension will be handled by `ts-loader`
      { test: /\.tsx?$/, loader: "ts-loader" },
    ],
  },
  plugins: [
    new CopyWebpackPlugin([
      {
        from: './html',
      }
    ]),
  ],
};

屬性

如需有關設定 webpack 的更多資訊,請參閱 webpack 網站

9.6 tsconfig.json

這個檔案設定 TypeScript 編譯器

{
  "compilerOptions": {
    "rootDir": "ts",
    "outDir": "dist",
    "target": "es2019",
    "lib": [
      "es2019",
      "dom"
    ],
    "module": "commonjs",
    "esModuleInterop": true,
    "strict": true,
    "sourceMap": true
  }
}

如果我們使用 webpack 搭配 ts-loader,就不需要 outDir 選項。不過,如果我們在沒有載入器的狀況下使用 webpack(如本章稍後說明),就需要它。

9.7 index.html

這是網頁應用程式的 HTML 頁面

<!doctype html>
<html>
<head>
  <meta charset="UTF-8">
  <title>ts-demo-webpack</title>
</head>
<body>
  <div id="output"></div>
  <script src="main-bundle.js"></script>
</body>
</html>

ID 為 "output"<div> 是網頁應用程式顯示其輸出的位置。main-bundle.js 包含已套件的程式碼。

9.8 main.ts

這是網頁應用程式的 TypeScript 程式碼

import template from 'lodash/template';

const outputElement = document.getElementById('output');
if (outputElement) {
  const compiled = template(`
    <h1><%- heading %></h1>
    Current date and time: <%- dateTimeString %>
  `.trim());
  outputElement.innerHTML = compiled({
    heading: 'ts-demo-webpack',
    dateTimeString: new Date().toISOString(),
  });
}

9.9 安裝、建置和執行網頁應用程式

首先,我們需要安裝網頁應用程式所依賴的所有 npm 套件

npm install

然後,我們需要透過 package.json 中的指令碼執行 webpack(已在先前步驟中安裝)

npm run wpw

從現在開始,webpack 會監控儲存庫中的檔案是否有變更,並在偵測到任何變更時重新建置網頁應用程式。

在另一個命令列中,我們現在可以啟動一個網頁伺服器,在 localhost 上提供 build/ 的內容

npm run serve

如果我們前往 Web 伺服器列印出的 URL,便可以看到 Web 應用程式執行中。

請注意,由於快取,單純重新載入可能不足以在變更後看到結果。您可能必須在重新載入時按下 Shift,強制重新載入。

9.9.1 在 Visual Studio Code 中建置

除了從命令行建置之外,我們也可以透過所謂的建置工作,在 Visual Studio Code 中執行建置

我們現在可以從「終端機」功能表中的「執行建置工作…」開始 webpack。

9.10 不使用載入器使用 webpack:webpack-no-loader.config.js

除了使用 ts-loader 之外,我們也可以先將 TypeScript 檔案編譯成 JavaScript 檔案,然後透過 webpack 將它們打包。這兩個步驟的第一個步驟如何運作,已在 前一章節 中說明。

我們現在不必組態 ts-loader,而且我們的 webpack 組態檔會更簡單

const path = require('path');

module.exports = {
  entry: {
    main: "./dist/src/main.js",
  },
  output: {
    path: path.join(__dirname, 'build'),
    filename: '[name]-bundle.js',
  },
  plugins: [
    new CopyWebpackPlugin([
      {
        from: './html',
      }
    ]),
  ],
};

請注意,entry.main 不同。在另一個組態檔中,它是

"./ts/src/main.ts"

我們為什麼要在打包之前產生中間檔案?一個好處是,我們可以使用 Node.js 為一些 TypeScript 程式碼執行單元測試。