作者:Dr. Axel Rauschmayer翻译:疯狂的技术宅
原文:https://2ality.com/2020/04/we...
未经允许严禁转载
本文介绍了如何通过 TypeScript 和 webpack 创建 Web 应用程序。我们仅使用 DOM API,而不使用特定的前端框架。源码文件 ts-demo-webpack
可以从 GitHub 下载。
必需的知识:如果你对 TypeScript,webpack 和 npm 的工作原理有一个大概的了解,那么它会有所帮助。
局限性
通过 TypeScript 和 npm 使用 ES 模块仍然很脆弱。所以我们将会坚持将 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
为了构建 Web 应用程序,我们需要将两组文件编译到目录 build/
中:
- TypeScript 文件存储在
ts/
中。 - HTML 文件存储在
html/
中。
这两个任务都由 webpack 处理:
- 对于 TypeScript,webpack 从
main.ts
开始处理,找到所有使用的 TypeScript 和 JavaScript 文件,并将它们编译成单个脚本文件build/main-bundle.js
。此过程称为 bundling。为了将 TypeScript 编译为JavaScript,webpack 使用了 loader(插件)ts-loader
。 - 通过 webpack plugin
copy-webpack-plugin
复制html/
中的文件。
安装、构建和运行 Web 应用
首先需要安装我们的网络应用依赖的所有 npm 软件包:
npm install
然后,需要通过 package.json
中的脚本来运行 webpack(在上一步中也已安装):
npm run wpw
从现在开始,webpack 会监视存储库中的文件是否有更改,并在检测到任何修改时重新构建该 Web 应用。
在另一个命令行中,我们现在可以启动一个在本地主机上提供 build/
内容的 Web 服务器:
npm run serve
如果转到 Web 服务器输出的 URL,则可以看到正在运行的 Web 应用程序。
请注意,由于缓存的原因,简单的重新加载可能看不到更改后的结果。重新加载时,可能需要按 shift 键来强制重新加载。
在 Visual Studio Code 中构建
除了可以用命令行进行构建外,我们还可以在 Visual Studio Code 中通过所谓的 build task 进行构建:
- 从 “Terminal” 菜单中执行 “Configure Default Build Task...”。
- 选择 “npm: wpw”.
- 可选:在
.vscode/tasks.json
设置适当的问题匹配器:
"problemMatcher": ["$tsc-watch"],
现在我们可以从 “Terminal” 菜单执行 “Run Build Task...”。
package.json
package.json
指定项目所依赖的脚本和 npm 软件包:
{
"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 不会报错。 - Scripts:
-
tsc,tscw
:如果我们将 webpack 与ts-loader
一起使用,可能不会直接调用 TypeScript 编译器tsc
。-
wp
:运行 webpack 一次编译所有内容。
-
-
wpw
:用 webpack 监视,并仅编译修改过的文件。-
serve
:运行服务器http-server
并提供目录build/
的内容。
-
-
依赖项:
- Webpack incl 支持通过 CLI(命令行界面)和插件使用:
webpack
、webpack-cli
、ts-loader
、copy-webpack-plugin
- 需要
ts-loader
:typescript
- Web 应用的 Web 服务器:
http-server
- 库以及 TypeScript 代码使用的类型定义:
lodash
、@ types/lodash
- Webpack incl 支持通过 CLI(命令行界面)和插件使用:
webpack.config.js
这是我们配置 webpack 的方式:
const path = require('path');
const CopyWebpackPlugin = require('copy-webpack-plugin');
module.exports = {
mode: "development",
devtool: "inline-source-map",
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 网站。
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,则需要(如本文稍后所述)。
index.html
这是 Web 应用的 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>
是 web 应用显示其输出的位置。 main-bundle.js
包含捆绑的代码。
main.ts
这是 Web 应用的 TypeScript 代码:
import template from 'lodash/template';
const outputElement = document.getElementById('output');
if (outputElement) {
var compiled = template(`
<h1><%- heading %></h1>
Current date and time: <%- dateTimeString %>
`.trim());
outputElement.innerHTML = compiled({
heading: 'ts-demo-webpack',
dateTimeString: new Date().toISOString(),
});
}
有关 template()
的更多信息,请参见 Lodash 的文档。
在没有加载器的情况下使用 webpack:webpack-no-loader.config.js
除了依赖于 ts-loader
之外,我们还可以先将所有 TypeScript 文件编译为 JavaScript 文件(通过 TypeScript 编译器),然后通过 webpack 捆绑这些文件。有关其工作原理的更多信息,请参见博客文章“通过TypeScript创建基于CommonJS 的 npm 软件包”。
现在,我们不必配置 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',
}
]),
],
};
为什么要在捆绑中间文件之前产生中间文件?好处是我们可以用 Node.js 对某些 TypeScript 代码运行单元测试。
本文首发微信公众号:前端先锋
欢迎扫描二维码关注公众号,每天都给你推送新鲜的前端技术文章
欢迎继续阅读本专栏其它高赞文章:
- 深入理解Shadow DOM v1
- 一步步教你用 WebVR 实现虚拟现实游戏
- 13个帮你提高开发效率的现代CSS框架
- 快速上手BootstrapVue
- JavaScript引擎是如何工作的?从调用栈到Promise你需要知道的一切
- WebSocket实战:在 Node 和 React 之间进行实时通信
- 关于 Git 的 20 个面试题
- 深入解析 Node.js 的 console.log
- Node.js 究竟是什么?
- 30分钟用Node.js构建一个API服务器
- Javascript的对象拷贝
- 程序员30岁前月薪达不到30K,该何去何从
- 14个最好的 JavaScript 数据可视化库
- 8 个给前端的顶级 VS Code 扩展插件
- Node.js 多线程完全指南
- 把HTML转成PDF的4个方案及实现
**粗体** _斜体_ [链接](http://example.com) `代码` - 列表 > 引用
。你还可以使用@
来通知其他用户。