Webpack 集成

Webpack 是流行的前端构建工具,可以与 TypeScript 无缝集成。通过 ts-loaderbabel-loader,Webpack 可以编译 TypeScript 代码。

安装依赖

安装 TypeScript 和相关依赖。

npm install typescript ts-loader webpack webpack-cli --save-dev

安装类型声明。

npm install @types/node --save-dev

基本配置

tsconfig.json

创建 TypeScript 配置文件。

{
  "compilerOptions": {
    "target": "ES2020",
    "module": "ESNext",
    "lib": ["ES2020", "DOM"],
    "moduleResolution": "node",
    "strict": true,
    "esModuleInterop": true,
    "skipLibCheck": true,
    "forceConsistentCasingInFileNames": true,
    "sourceMap": true,
    "outDir": "./dist",
    "rootDir": "./src"
  },
  "include": ["src/**/*"],
  "exclude": ["node_modules"]
}

webpack.config.js

创建 Webpack 配置文件。

const path = require("path")

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

ts-loader

ts-loader 是 TypeScript 官方推荐的 Webpack 加载器。

module.exports = {
  module: {
    rules: [
      {
        test: /\.ts$/,
        use: "ts-loader",
        exclude: /node_modules/
      }
    ]
  }
}

ts-loader 使用 tsconfig.json 配置,支持类型检查和 source map。

babel-loader

babel-loader 也可以编译 TypeScript。

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

配置 babel-loader

module.exports = {
  module: {
    rules: [
      {
        test: /\.ts$/,
        use: "babel-loader",
        exclude: /node_modules/
      }
    ]
  }
}

配置 Babel。

{
  "presets": [
    "@babel/preset-env",
    "@babel/preset-typescript"
  ]
}

babel-loader 编译速度快,但不进行类型检查。

类型检查

使用 fork-ts-checker-webpack-plugin 进行类型检查。

npm install fork-ts-checker-webpack-plugin --save-dev

配置插件。

const ForkTsCheckerWebpackPlugin = require("fork-ts-checker-webpack-plugin")

module.exports = {
  module: {
    rules: [
      {
        test: /\.ts$/,
        use: "ts-loader",
        exclude: /node_modules/
      }
    ]
  },
  plugins: [
    new ForkTsCheckerWebpackPlugin()
  ]
}

类型检查在单独的进程中进行,不影响编译速度。

路径映射

Webpack 支持路径映射。

module.exports = {
  resolve: {
    extensions: [".ts", ".js"],
    alias: {
      "@": path.resolve(__dirname, "src"),
      "@components": path.resolve(__dirname, "src/components"),
      "@utils": path.resolve(__dirname, "src/utils")
    }
  }
}

tsconfig.json 中也需要配置路径映射。

{
  "compilerOptions": {
    "baseUrl": ".",
    "paths": {
      "@/*": ["src/*"],
      "@components/*": ["src/components/*"],
      "@utils/*": ["src/utils/*"]
    }
  }
}

开发服务器

使用 webpack-dev-server 进行开发。

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

配置开发服务器。

module.exports = {
  devServer: {
    static: {
      directory: path.join(__dirname, "public")
    },
    compress: true,
    port: 3000,
    hot: true
  }
}

生产配置

生产环境配置优化。

const path = require("path")

module.exports = {
  mode: "production",
  entry: "./src/index.ts",
  output: {
    filename: "[name].[contenthash].js",
    path: path.resolve(__dirname, "dist"),
    clean: true
  },
  resolve: {
    extensions: [".ts", ".js"],
    alias: {
      "@": path.resolve(__dirname, "src")
    }
  },
  module: {
    rules: [
      {
        test: /\.ts$/,
        use: "ts-loader",
        exclude: /node_modules/
      }
    ]
  },
  optimization: {
    splitChunks: {
      chunks: "all"
    }
  }
}

实际应用

一个完整的 Webpack + TypeScript 项目配置。

const path = require("path")
const ForkTsCheckerWebpackPlugin = require("fork-ts-checker-webpack-plugin")

module.exports = {
  mode: process.env.NODE_ENV === "production" ? "production" : "development",
  entry: "./src/index.ts",
  output: {
    filename: "[name].[contenthash].js",
    path: path.resolve(__dirname, "dist"),
    clean: true
  },
  resolve: {
    extensions: [".ts", ".js"],
    alias: {
      "@": path.resolve(__dirname, "src")
    }
  },
  module: {
    rules: [
      {
        test: /\.ts$/,
        use: "ts-loader",
        exclude: /node_modules/
      },
      {
        test: /\.css$/,
        use: ["style-loader", "css-loader"]
      }
    ]
  },
  plugins: [
    new ForkTsCheckerWebpackPlugin()
  ],
  devServer: {
    static: {
      directory: path.join(__dirname, "public")
    },
    port: 3000,
    hot: true
  },
  devtool: "source-map"
}

小结

Webpack 可以通过 ts-loaderbabel-loader 编译 TypeScript。ts-loader 进行类型检查,babel-loader 编译速度快。fork-ts-checker-webpack-plugin 可以在单独进程中进行类型检查。Webpack 支持路径映射和开发服务器。生产配置需要优化代码分割和缓存。