翻译 | 开始使用 TypeScript 和 React
Tom Dale 和其他人有一些关于 TypeScript 比较好的博文,跟随这些博文,我最近开始使用 TypeScript。今天,我将展示如何从零开始建立一个 TypeScript 工程,以及如何使用 Webpack 管理构建过程。我也将陈述关于 TypeScript 的第一印象,尤其是使用 TypeScript 和 ReactJS。 我不会深入到 TypeScript 语法的具体细节,你可以阅读 TypeScript handbook 或者免费书籍 TypeScript Deep Dive,它们是关于 TypeScript 比较好的入门材料。 更新:如果你想用德语阅读这篇文章,你可以 thanks to the awesome folks at Reactx.de 安装配置 TypeScript第一步要做的事情是使用 Yarn 将 TypeScript 安装到本地的 yarn init yarn add typescript 当你安装了 TypeScript,你就可以使用 注意:你可以在我的点开头的配置文件中看到,我将
{ "compilerOptions": { "module": "es6",// 使用 ES2015 模块 "target": "es6",// 编译成 ES2015 (Babel 将做剩下的事情) "allowSyntheticDefaultImports": true,// 看下面 "baseUrl": "src",// 可以相对这个目录 import 文件 "sourceMap": true,// 使 TypeScript 生成 sourcemaps "outDir": "ts-build",// 构建输出目录 (因为我们大部分时间都在使用 Webpack,所以不太相关) "jsx": "preserve",// 开启 JSX 模式,但是 "preserve" 告诉 TypeScript 不要转换它(我们将使用 Babel) "strict": true,},"exclude": [ "node_modules" // 这个目录下的代码不会被 typescript 处理 ] } allowSyntheticDefaultImports将这个属性的值设置为 true,它允许你使用 ES2015 默认的 imports 风格,即使你导入的代码没有使用 ES2015 默认的 export。 举个例子,当你 import 不是用 ES2015 编写的 React 时(虽然源码是,但是 React 使用一个构建好的版本),就可以利用上面的属性设置。这意味着,严格意义上来讲,它没有使用 ES2015 默认的 export,所以当你使用 import 的时候, TypeScript 会警告你。尽管如此,像 Webpack 这样的构建工具能够导入正确的代码,所以我将这个属性设置为 true,相比使用 strict:trueTypeScript 2.3 版本引入了一种新的配置选项, noImplicitAny将 TypeScript 引入一个现有的项目,当你不声明变量的类型时,TypeScript 不会抛出错误。但是,当我从零开始新建一个 TypeScript 项目,我希望编译器尽可能地严格。 function log(thing) { console.log('thing',thing) } 如果你想了解更多关于 noImplicitAny 的信息,可以阅读 TypeScript Deep Dive strictNullChecks这是另一个使 TypeScript 编译器更严格的选项。TypeScript Deep Dive 这本书有一个很好的章节介绍这个选项。如果将这个选项设置为true,TypeScript 会更容易识别出你引用的一个可能是 undefined 值的地方,并将展示这个错误。例如: person.age.increment() 当将 strictNullChecks 设置为 true,TypeScript 会认为 person 或者 person.age 可能是 undefined,它会报个错以确保你处理它。这会防止出现运行时错误,所以这看起来是一个从一开始就要打开的很棒的选项。 配置 Webpack,Babel and TypeScript我是 Webpack 的脑残粉;我喜欢它的插件生态系统、开发者工作流,喜欢它擅长管理复杂的应用和构建流程。所以,即使我们可能仅仅使用 TypeScript 编译器,我仍然喜欢引入 Webpack。因为 TypeScript 输出 React 和 es6(也就是 es2015,babel 把 es6 转成 es5,所以我们还需要 babel。让我们安装 Webpack,Babel 和相关的 presets 及 ts-loader,ts-loader 是 TypeScript 在 Webpack 中的插件。 还有 awesome-typescript-loader ,也是 TypeScript 在 Webpack 中的插件,但是我首先找到的是 yarn add webpack babel-core babel-loader babel-preset-es2015 babel-preset-react ts-loader webpack-dev-server 此时此刻,我必须感谢 Tom Duncalf,他在博客中发表的 TypeScript 1.9 + React,对我来说,是一个特别好的开始,我极力推荐它。 在 Webpack 中没有特别的配置,但是我还是在代码中列出一些注释来解释它: const webpack = require('webpack') const path = require('path') module.exports = { // 设置 sourcemaps 为 eval 模式,将模块封装到 eval 包裹起来 devtool: 'eval',// 我们应用的入口,在 `src` 目录 (我们添加到下面的 resolve.modules): entry: [ 'index.tsx' ],// 配置 devServer 的输出目录和 publicPath output: { filename: 'app.js',publicPath: 'dist',path: path.resolve('dist') },// 配置 devServer devServer: { port: 3000,historyApiFallback: true,inline: true,// 告诉 Webpack 加载 TypeScript 文件 resolve: { // 首先寻找模块中的 .ts(x) 文件,然后是 .js 文件 extensions: ['.ts','.tsx','.js'],// 在模块中添加 src,当你导入文件时,可以将 src 作为相关路径 modules: ['src','node_modules'],module: { loaders: [ // .ts(x) 文件应该首先经过 Typescript loader 的处理,然后是 babel 的处理 { test: /.tsx?$/,loaders: ['babel-loader','ts-loader'],include: path.resolve('src') } ] },} 我们按照上面的方式配置 loaders ,从而使 { "presets": ["es2015","react"] } 现在我们已经做好了写 TypeScript 应用的准备。 写一个 TypeScript React 组件现在,我们准备好建立 import React from 'react' import ReactDOM from 'react-dom' const App = () => { return ( <div> <p>Hello world!</p> </div> ) } ReactDOM.render(<App />,document.getElementById('app')) 如果你运行 webpack,会看到下面的错误: ERROR in ./src/index.tsx (1,19): error TS2307: Cannot find module 'react'. ERROR in ./src/index.tsx (2,22): error TS2307: Cannot find module 'react-dom'. 发生上面的错误是因为 TypeScript 试图确认 React 的类型、React 导出了什么。对于 React DOM,TypeScript 会做同样的事情。React 并不是使用 TypeScript 编写的,所以它并没有包含那些信息。幸运地是,为了应对这种情况,社区已经创建了 DefinitelyTyped,这是一个大型的组件类型库。 最近,安装机制改变了;所有的类型被发布到 npm @types scope 下。为了获得 React 和 ReactDOM 的类型,我们运行下面的命令: yarn add @types/react yarn add @types/react-dom 通过上面的处理,错误不见了。无论何时,你安装一个依赖时,都应该试着安装 本地运行 app为了在本地运行 app,我们只需要运行 "scripts": { "start": "webpack-dev-server" } 服务会找到 webpack.config.json 这个文件,使用它创建我们的应用。 如果你运行 $ webpack-dev-server Project is running at http://localhost:3000/ webpack output is served from /dist 404s will fallback to /index.html ts-loader: Using typescript@2.3.0 and /Users/jackfranklin/git/interactive-react-introduction/tsconfig.json Version: webpack 2.4.1 Time: 6077ms Asset Size Chunks Chunk Names app.js 1.14 MB 0 [emitted] [big] main webpack: Compiled successfully. 为了能够在本地看到效果,我创建了一个 index.html 文件,让它加载编译后的代码: <!DOCTYPE html> <html lang="en"> <head> <meta charset="UTF-8"> <title>My Typescript App</title> </head> <body> <div id="app"></div> <script src="dist/app.js"></script> </body> 在端口 3000,我们将会看到 定义一个模块类型在现在的工程中,我想使用 React Ace module 包含一个代码编辑器。但是这个模块并不提供 types,并且也没有 定义一个只包含类型的文件,后缀是 我创建了 declare module 'react-ace' { interface ReactAceProps { mode: string theme: string name: string editorProps?: {} showPrintMargin?: boolean minLines?: number maxLines?: number wrapEnabled?: boolean value: string highlightActiveLine?: boolean width?: string fontSize?: number } const ReactAce: React.ComponentClass<ReactAceProps> export = ReactAce } 我首先创建了一个 TypeScript 接口,这个接口包含组件的属性, 测试最后,使用 TypeScript,我也想有一个很好的测试方案。我是 Facebook 的 Jest 的超级粉丝,我在 google 上做了一些搜索,确认它是否能用 TypeScript 运行。结果发现,这是可行的, 非常感谢 "jest": { "moduleFileExtensions": [ "ts","tsx","js" ],"transform": { ".(ts|tsx)$": "<rootDir>/node_modules/ts-jest/preprocessor.js" },"testRegex": "/*.spec.(ts|tsx|js)$" }, 第一个配置告诉 Jest 寻找 通过上面这些配置,我可以运行 使用 TSLint 规范代码尽管 TypeScript 在代码中会给出很多检查提示,我仍然想要一个规范器,做些代码风格和质量检查。就像 JavaScript 的 ESLint,TSLint 是检查 TypeScript 的最好选择。它和 ESlint 的工作方式相同 - 用一系列生效或不生效的规则,还有一个 TSLint-React 包增加 React 的具体规则。 你可以通过 { "defaultSeverity": "error","extends": ["tslint:latest","tslint-react"],"jsRules": {},"rules": { // 用单引号,但是在 JSX 中,强制使用双引号 "quotemark": [true,"single","jsx-double"],// 我更喜欢没有分号 :) "semicolon": [true,"never"],// 这个规则使每个接口以 I 开头,这点我不喜欢 "interface-name": [true,"never-prefix"],// 这个规则强制对象中的 key 按照字母顺序排列 "object-literal-sort-keys": false },"rulesDirectory": [] } 我可以运行 结论总之,到目前为止,用 TypeScript 开发我很高兴。我肯定会发表更多博文来描述这门语言的细节和我是如何使用 TypeScript 的。但仅就如下操作而言,构建过程、配置所有的工具、开始使用类型,这真是一种享受。如果你正在将你的 JS 应用结构化,想要一个更强大的编译器避免错误并减少调试时间,我极力推荐你尝试 TypeScript。 如果你想看源码或者以本文中的例子作为开始,我在 GitHub 上放了一个例子,如果你有任何问题,可以提 issue。
(编辑:李大同) 【声明】本站内容均来自网络,其相关言论仅代表作者个人观点,不代表本站立场。若无意侵犯到您的权利,请及时与联系站长删除相关内容! |