学习 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
  }
}

如果我们使用带有 ts-loader 的 webpack,则不需要选项 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 会监视代码仓库中的文件是否有更改,并在检测到任何更改时重新构建网页应用。

在另一个命令行中,我们现在可以启动一个 Web 服务器,在本地主机上提供 build/ 的内容

npm run serve

如果我们转到 Web 服务器打印出的 URL,就可以看到网页应用的运行情况。

请注意,简单的重新加载可能不足以看到更改后的结果 - 因为缓存的原因。您可能需要在重新加载时按住 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 代码运行单元测试。