ts-demo-webpack
package.json
webpack.config.js
tsconfig.json
index.html
main.ts
webpack-no-loader.config.js
本章介绍如何通过 TypeScript 和 webpack 创建网页应用。我们将只使用 DOM API,而不使用特定的前端框架。
GitHub 仓库:ts-demo-webpack
您应该大致熟悉以下内容
在本章中,我们坚持使用 TypeScript 最佳支持的内容:CommonJS 模块,捆绑为脚本文件。
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
网页应用的构建方式如下
ts/
中的 TypeScript 文件html/
中的 HTML 文件build/
build/main-bundle.js
。这个过程称为*捆绑*,main-bundle.js
是一个捆绑文件。build/
。这两个输出任务都由 webpack 处理
将 html/
中的文件复制到 build/
是通过 webpack *插件* copy-webpack-plugin
完成的。
本章探讨了两种不同的捆绑工作流程
ts-loader
的帮助下,直接将 TypeScript 文件编译到捆绑包中。dist/
目录下的 Javascript 文件(就像我们在上一章中所做的那样)。然后 webpack 不需要加载器,只需要捆绑 JavaScript 文件。本章的大部分内容都是关于将 webpack 与 ts-loader
一起使用。最后,我们将简要介绍一下另一种工作流程。
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": "···"
}
}
属性的工作方式如下
"private": true
意味着如果我们不提供包名称和包版本,npm 不会报错。tsc, tscw
:这些脚本直接调用 TypeScript 编译器。如果我们使用带有 ts-loader
的 webpack,就不需要它们。但是,如果我们使用不带 ts-loader
的 webpack(本章末尾将演示),它们就很有用。wp
:运行 webpack 一次,编译所有内容。wpw
:在监听模式下运行 webpack,它会监听输入文件,并且只编译发生变化的文件。serve
:运行服务器 http-server
,并使用完全组装好的网页应用服务目录 build/
。webpack
:webpack 的核心webpack-cli
:核心的命令行界面ts-loader
:用于 .ts
文件的*加载器*,它将这些文件编译成 JavaScriptcopy-webpack-plugin
:一个*插件*,用于将文件从一个位置复制到另一个位置ts-loader
所需:typescript
http-server
lodash
、@types/lodash
webpack.config.js
以下是我们配置 webpack 的方式
const path = require('path');
const CopyWebpackPlugin = require('copy-webpack-plugin');
.exports = {
module
···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',
},
]),
]; }
属性
entry
:*入口点*是 webpack 开始为输出捆绑包收集数据的起点文件。首先,它将入口点文件添加到捆绑包中,然后是入口点的导入,然后是导入的导入,等等。属性 entry
的值是一个对象,其属性键指定入口点的名称,其属性值指定入口点的路径。
output
指定输出捆绑包的路径。[name]
主要在有多个入口点(因此有多个输出捆绑包)时有用。在组装路径时,它将被替换为入口点的名称。
resolve
配置 webpack 如何将模块的*说明符*(ID)转换为文件的位置。
module
配置*加载器*(处理文件的插件)等等。
plugins
配置*插件*,这些插件可以通过各种方式改变和增强 webpack 的行为。
有关配置 webpack 的更多信息,请参阅webpack 网站。
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(本章稍后将解释),则需要它。
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
包含捆绑的代码。
main.ts
这是网页应用的 TypeScript 代码
import template from 'lodash/template';
= document.getElementById('output');
const outputElement if (outputElement) {
= template(`
const compiled <h1><%- heading %></h1>
Current date and time: <%- dateTimeString %>
`.trim());
.innerHTML = compiled({
outputElement: 'ts-demo-webpack',
heading: new Date().toISOString(),
dateTimeString;
}) }
template()
将具有自定义模板语法的字符串转换为函数 compiled()
,该函数将数据映射到 HTML。该字符串定义了两个要通过数据填充的空白<%- heading %>
<%- dateTimeString %>
compiled()
应用于数据(具有两个属性的对象)以生成 HTML。首先,我们需要安装我们的网页应用依赖的所有 npm 包
npm install
然后,我们需要通过 package.json
中的脚本运行 webpack(在上一步中安装)
npm run wpw
从现在开始,webpack 会监视代码仓库中的文件是否有更改,并在检测到任何更改时重新构建网页应用。
在另一个命令行中,我们现在可以启动一个 Web 服务器,在本地主机上提供 build/
的内容
npm run serve
如果我们转到 Web 服务器打印出的 URL,就可以看到网页应用的运行情况。
请注意,简单的重新加载可能不足以看到更改后的结果 - 因为缓存的原因。您可能需要在重新加载时按住 Shift 键强制重新加载。
除了从命令行构建之外,我们还可以通过 Visual Studio Code 中的所谓*构建任务*来构建
从“终端”菜单中执行“配置默认构建任务...”。
选择“npm: wpw”。
*问题匹配器*处理将工具输出转换为*问题*(信息、警告和错误)列表的操作。在这种情况下,默认设置效果很好。如果您想明确指定,可以在 .vscode/tasks.json
中指定一个值
"problemMatcher": ["$tsc-watch"],
我们现在可以通过“终端”菜单中的“运行构建任务...”启动 webpack。
webpack-no-loader.config.js
除了使用 ts-loader
之外,我们还可以先将 TypeScript 文件编译成 JavaScript 文件,然后再通过 webpack 将它们捆绑起来。这两个步骤中的第一步是如何工作的,在上一章中已经描述过。
我们现在不必配置 ts-loader
,我们的 webpack 配置文件也更简单
const path = require('path');
.exports = {
moduleentry: {
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 代码运行单元测试。