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
文件。
现在,由于 lodash
定义中没有默认导出,让我们更改 ./index.ts
中 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
,因为它使启用其他 webpack 功能(例如导入其他 Web 资产)变得更加容易。
请注意,如果您已经使用 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
指令来声明它
/// <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
结尾的任何导入并定义模块的 content
为 any
来声明一个新的 SVG 模块。我们可以通过将类型定义为字符串来更明确地说明它是 URL。同样的概念也适用于其他资产,包括 CSS、SCSS、JSON 等等。
请参阅 构建性能 指南了解构建工具。