Webpack5+vscode搭建kintone开发环境(九)支持 Typescript

cybozu发表于:2021年01月07日 14:20:40更新于:2021年07月28日 14:32:33

目录

第一篇:初始化项目
第二篇:代码规范
第三篇:Webpack 基本配置
第四篇:开发环境设置
第五篇:生产环境设置
第六篇:css、less、scss、图片支持
第七篇:IE11 兼容
第八篇:支持 React
第九篇:支持 Typescript
第十篇:命令行工具


安装

TypeScript 是 JavaScript 的超集,这意味着他支持所有的 JavaScript 语法、并在此之上对 JavaScript 添加了一些扩展。
因此我们不光要安装 typescript 的本体,还必须安装它的 Babel 插件来进行语法转换。

npm install typescript @babel/preset-typescript -D

然后修改 .babelrc :

{
  "presets": [
    //others
    "@babel/preset-typescript"
  ],
  //others
}

之前提过,presets 的执行顺序是从后到前的,所以 typescript 的转换必须放在最后面,才能被最先执行。


配置

打开.vscode/setting.json,输入:

{
  //others
  "eslint.validate": ["javascript", "javascriptreact", "typescript", "typescriptreact"],
  "typescript.tsdk": "./node_modules/typescript/lib",
  //others
}
  • eslint.validate:eslint 插件配置

  • typescript.tsdk:替代 vscode 的 ts 语法智能提示

修改.eslintrc.js 增加新的规则:

module.exports = {
  parser: '@babel/eslint-parser',
  extends: [
    '@cybozu/eslint-config/globals/kintone',
    '@cybozu/eslint-config/presets/react-prettier',
    '@cybozu/eslint-config/presets/react-typescript-prettier',
  ],
  rules: {
    'react/jsx-filename-extension': [1, { extensions: ['.js', '.jsx', '.ts', '.tsx'] }],
  },
}
  • extends:追加了 react-typescript-prettier

  • typescript.tsdk:替代 vscode 的 ts 语法智能提示


修改 webpack.common.js 文件:

module.exports = {
  //others
  extensions: ['.tsx', '.ts', '.js', '.jsx', '.json'],
  //others
  module: {
    rules: [
      {
        test: /\.(tsx?|jsx?)$/,
        loader: 'babel-loader',
        options: { cacheDirectory: true },
        exclude: /node_modules/,
      },
      //others
    ],
  },
}
  • extensions:后缀名添加 tsx、ts

  • module.rules:修改 babel-loader 的匹配公式,即,匹配的文件后缀只有 .tsx 、.ts 、 .js、jsx

声明文件

TypeScript 作为 JavaScript 的超集,在开发过程中不可避免要引用其他第三方的 JavaScript 的库。

虽然通过直接引用可以调用库的类和方法,但是却无法使用TypeScript 诸如类型检查等特性功能。

为了解决这个问题,需要将这些库里的函数和方法体去掉后只保留导出类型声明,而产生了一个描述 JavaScript 库和模块信息的声明文件。

通过引用这个声明文件,就可以借用 TypeScript 的各种特性来使用库文件了。

声明文件以 .d.ts 为后缀,绝大部分第三方包的声明文件可以在这里找到。


安装 React 声明文件

npm install @types/react @types/react-dom -D


安装 kintone 声明文件

npm install @kintone/dts-gen -D

tsconfig

tsconfig.json 文件放在项目根目录下,作为 typescript 的编译配置,主要作用:

  • 编译指定文件

  • 定义编译选项

通俗来说,就是 tsc 编译命令的配置文件。

在我们的开发环境中,编译主要交给了 Babel,并不依赖于 tsc。

tsconfig 的作用更偏向与提供编辑器的错误提示。

在控制台输入以下代码来生成此文件:

npx tsc --init

生成的 tsconfig.json 注释内容较多,大家可以日后慢慢学习。先将以下内容覆盖到 tsconfig.json 中

{
  "compilerOptions": {
    "target": "es5",
    "module": "ESNext",
    "lib": ["dom", "dom.iterable", "esnext"],
    "allowJs": true,
    "jsx": "react",
    "declaration": true,
    "noEmit": true,
    "isolatedModules": true,
    "strict": true,
    "noImplicitAny": true,
    "noUnusedLocals": true,
    "noUnusedParameters": true,
    "noImplicitReturns": true,
    "noFallthroughCasesInSwitch": true,
    "moduleResolution": "node",
    "allowSyntheticDefaultImports": true,
    "esModuleInterop": true,
    "experimentalDecorators": true,
    "emitDecoratorMetadata": true,
    "skipLibCheck": true,
    "forceConsistentCasingInFileNames": true,
    "resolveJsonModule": true
  },
  "files": ["./node_modules/@kintone/dts-gen/kintone.d.ts"],
  "include": ["src/**/*"],
  "exclude": ["dist", "node_modules"]
}
  • target:编译成哪个版本的 es

  • module:指定生成哪个模块系统代码

  • lib:编译过程中需要引入的库文件的列表

  • allowJs:允许编译 js 文件

  • jsx:在 .tsx 文件里支持 JSX

  • declaration:生成相应的 .d.ts 文件

  • noEmit:不生成输出文件

  • isolatedModules:将每个文件作为单独的模块

  • strict:启用所有严格类型检查选项

  • noImplicitAny:在表达式和声明上有隐含的 any类型时报错

  • noUnusedLocals:若有未使用的局部变量则抛错

  • noUnusedParameters:若有未使用的参数则抛错

  • noImplicitReturns:不是函数的所有返回路径都有返回值时报错

  • noFallthroughCasesInSwitch:不允许switch的case语句贯穿

  • moduleResolution:指定模块解析策略

  • allowSyntheticDefaultImports:允许从没有设置默认导出的模块中默认导入

  • esModuleInterop:支持 CommonJS 和 ES 模块之间的互操作性

  • experimentalDecorators:启用实验性的 ES 装饰器

  • emitDecoratorMetadata:给源码里的装饰器声明加上设计类型元数据

  • skipLibCheck:忽略所有的声明文件( *.d.ts)的类型检查

  • forceConsistentCasingInFileNames:禁止对同一个文件的不一致的引用

  • resolveJsonModule:支持导入 json 模块

  • files:额外的文件

  • include:指定需要编译的文件

  • exclude:忽略文件


编译时的 Typescirpt 类型检查

之前提到过的@babel/preset-typescript,在编译 ts 的过程很粗暴,会直接去掉 ts 的类型声明,然后再用其他 babel 插件进行编译,速度快的同时也会造成一些隐患。

这里给它打上一个补丁,在我们打包或启动本地服务时给予错误提示。

npm install fork-ts-checker-webpack-plugin -D

修改 webpack.common.js 文件:

const ForkTsCheckerWebpackPlugin = require('fork-ts-checker-webpack-plugin')

module.exports = {
  //others
  plugins: [
    new ForkTsCheckerWebpackPlugin({
      typescript: {
        configFile: resolve(__dirname, '../tsconfig.json'),
      },
    }),
  ],
  //others
}


Demo

最后让我们来做个demo看看效果

在 src 目录下新建 index.tsx

import React from 'react'
import ReactDOM from 'react-dom'
import './app.css'

interface KintoneEvent {
  record: kintone.types.SavedFields
}

const App = () => {
  return (
    <div className="app">
      <h1>hello, kintone!</h1>
    </div>
  )
}

kintone.events.on('app.record.index.show', (event: KintoneEvent) => {
  ReactDOM.render(<App />, kintone.app.getHeaderSpaceElement())
  return event
})


接下来需要建立 kintone app 的声明文件,推荐大家使用下面的指令自动生成。

npx kintone-dts-gen --host https://${domain}.cybozu.cn -u ${username} -p ${password} --app-id ${appid} -o ./src/fields.d.ts


而这里为了方便直接写了一个最简单的声明文件 fields.d.ts

declare namespace kintone.types {
  interface Fields {}
  interface SavedFields extends Fields {
    $id: kintone.fieldTypes.Id
    $revision: kintone.fieldTypes.Revision
    更新人: kintone.fieldTypes.Modifier
    创建人: kintone.fieldTypes.Creator
    更新时间: kintone.fieldTypes.UpdatedTime
    创建时间: kintone.fieldTypes.CreatedTime
    key: kintone.fieldTypes.RecordNumber
  }
}


修改 webpack.common.js 中的入口文件,指向 index.tsx 

module.exports = {
  //others
  entry: {
    app: resolve(__dirname, '../src/index.tsx'),
  },
  //others
}


运行命令看看效果。