TypeScript

TypeScript 是 JavaScript 的型別超集,編譯成純 JavaScript。在本指南中,我們將學習如何將 TypeScript 與 webpack 整合。

基本設定

首先,透過執行以下指令來安裝 TypeScript 編譯器和載入器

npm install --save-dev typescript ts-loader

現在,我們將修改目錄結構和設定檔

專案

  webpack-demo
  |- package.json
  |- package-lock.json
+ |- tsconfig.json
  |- webpack.config.js
  |- /dist
    |- bundle.js
    |- index.html
  |- /src
    |- index.js
+   |- index.ts
  |- /node_modules

tsconfig.json

讓我們設定一個設定檔來支援 JSX,並將 TypeScript 編譯成 ES5...

{
  "compilerOptions": {
    "outDir": "./dist/",
    "noImplicitAny": true,
    "module": "es6",
    "target": "es5",
    "jsx": "react",
    "allowJs": true,
    "moduleResolution": "node"
  }
}

請參閱 TypeScript 文件 以深入了解 tsconfig.json 設定選項。

如需深入了解 webpack 設定,請參閱 設定概念

現在,讓我們設定 webpack 來處理 TypeScript

webpack.config.js

const path = require('path');

module.exports = {
  entry: './src/index.ts',
  module: {
    rules: [
      {
        test: /\.tsx?$/,
        use: 'ts-loader',
        exclude: /node_modules/,
      },
    ],
  },
  resolve: {
    extensions: ['.tsx', '.ts', '.js'],
  },
  output: {
    filename: 'bundle.js',
    path: path.resolve(__dirname, 'dist'),
  },
};

這會引導 webpack 進入 ./index.ts,透過 ts-loader 載入 所有 .ts.tsx 檔案,並在我們的目前目錄中 輸出 一個 bundle.js 檔案。

現在讓我們變更 ./index.ts 中的 lodash 匯入,因為 lodash 定義中沒有預設匯出。

./index.ts

- import _ from 'lodash';
+ import * as _ from 'lodash';

  function component() {
    const element = document.createElement('div');

    element.innerHTML = _.join(['Hello', 'webpack'], ' ');

    return element;
  }

  document.body.appendChild(component());

載入器

ts-loader

我們在本指南中使用 ts-loader,因為它讓啟用其他 webpack 功能(例如匯入其他網路資產)變得更簡單。

請注意,如果您已經使用 babel-loader 編譯您的程式碼,您可以使用 @babel/preset-typescript,並讓 Babel 處理您的 JavaScript 和 TypeScript 檔案,而不是使用其他載入器。請記住,與 ts-loader 相反,基礎的 @babel/plugin-transform-typescript 外掛不會執行任何類型檢查。

原始碼對應

若要深入了解原始碼對應,請參閱 開發指南

若要啟用原始碼對應,我們必須設定 TypeScript 將內嵌原始碼對應輸出到我們的已編譯 JavaScript 檔案。必須將下列程式碼加入我們的 TypeScript 設定

tsconfig.json

  {
    "compilerOptions": {
      "outDir": "./dist/",
+     "sourceMap": true,
      "noImplicitAny": true,
      "module": "commonjs",
      "target": "es5",
      "jsx": "react",
      "allowJs": true,
      "moduleResolution": "node",
    }
  }

現在我們需要告訴 webpack 擷取這些原始碼對應,並包含在我們的最終套件中

webpack.config.js

  const path = require('path');

  module.exports = {
    entry: './src/index.ts',
+   devtool: 'inline-source-map',
    module: {
      rules: [
        {
          test: /\.tsx?$/,
          use: 'ts-loader',
          exclude: /node_modules/,
        },
      ],
    },
    resolve: {
      extensions: [ '.tsx', '.ts', '.js' ],
    },
    output: {
      filename: 'bundle.js',
      path: path.resolve(__dirname, 'dist'),
    },
  };

有關更多資訊,請參閱 devtool 文件

客戶端類型

可以在 TypeScript 程式碼中使用 webpack 特定功能,例如 import.meta.webpack。而 webpack 也提供其類型,新增 TypeScript 參考 指令來宣告它

/// <reference types="webpack/module" />
console.log(import.meta.webpack); // without reference declared above, TypeScript will throw an error

使用第三方程式庫

從 npm 安裝第三方程式庫時,請務必記住安裝該程式庫的類型定義。

例如,如果要安裝 lodash,我們可以執行以下指令來取得其類型

npm install --save-dev @types/lodash

如果 npm 套件已在套件組中包含其宣告類型,則不需要下載對應的 @types 套件。有關更多資訊,請參閱 TypeScript 變更記錄部落格

匯入其他資源

若要將非程式碼資源與 TypeScript 搭配使用,我們需要延遲這些匯入的類型。這需要一個 custom.d.ts 檔案,用於表示專案中 TypeScript 的自訂定義。讓我們設定 .svg 檔案的宣告

custom.d.ts

declare module '*.svg' {
  const content: any;
  export default content;
}

在此,我們透過指定任何以 .svg 結尾的匯入,並將模組的 內容 定義為 any,來宣告 SVG 的新模組。我們可以透過將類型定義為字串,更明確地表示為 URL。相同概念適用於其他資源,包括 CSS、SCSS、JSON 等。

建置效能

請參閱建置效能指南中的建置工具。

7 貢獻者

morsdycekkamalimtriverabyzykEugeneHlushkochenxsansnitin315