wisetc / practice

Practice conclusion
5 stars 0 forks source link

create-react-app 既有项目添加对 typescript 的支持 #28

Open wisetc opened 5 years ago

wisetc commented 5 years ago

情景

为 create-react-app 创建的 react 项目添加对 typescript 的支持,已经运行 npm run eject 弹出项目的 webpack 配置和 babel 配置。

原理

利用 babel-preset-typescript,实际该 babel preset 包含在 babel-preset-react-app 中。

更改配置和依赖

webpack

0x01. 更改 config/webpack.config.dev.jsconfig/webpack.config.prod.js 文件,增加对 ts 类型的支持。

配置项 extensions 中增加 '.ts' 和 '.tsx' 的模块。

{
    //...
    extensions: ['.web.js', '.mjs', '.js', '.ts', '.json', '.web.jsx', '.jsx', '.tsx'],
    //...
}

0x02. 配置项 module.rulesbabel-loader 的匹配中,增加 ts 文件的匹配。

{
  // ...
  module: {
    rules: [
      // ...
      {
        oneOf: [
          // ...
          {
            test: /\.(js|ts|jsx|tsx|mjs)$/,
            include: paths.appSrc,
            loader: require.resolve('babel-loader'),
            // ...
          },
        ],
      },
    ]
  }
 // ...
}

babel

更改 package.jsonbabel.presets 配置项。

原项目用到了 mobx 库,所以变更后的 babel.presets 配置为

{
  "babel": {
    "presets": [
      ["react-app", { "flow": false, "typescript": true }],
      "mobx"
    ],
    "_comment": "..."
  }
}

安装依赖

babel-preset-react-app@9.0.0, babel-core@7.0.0-bridge.0 @babel/core@7.5.4

$ npm i -D babel-preset-react-app@9.0.0 babel-core@7.0.0-bridge.0 @babel/core@7.5.4

升级 babel-preset-mobx 的版本到 2.0.0

$ npm i -D babel-preset-react-app@2.0.0

移除 dependencies 中的 babel 相关的依赖,相应更新后的 devDependencies

"devDependencies": {
    "babel-eslint": "7.2.3",
    "babel-jest": "20.0.3",
    "babel-loader": "7.1.2",
    "babel-polyfill": "^6.26.0",
    "babel-runtime": "6.26.0",
    "@babel/core": "^7.5.4",
    "babel-core": "^7.0.0-bridge.0",
    "babel-plugin-import": "^1.8.0",
    "babel-preset-mobx": "^2.0.0",
    "babel-preset-react-app": "^9.0.0",
    "_comment": "..."
}

咳咳,因为 babel-jest@20.0.3 依赖 babel-core@6,可能导致错误的 babel-core 版本加载,所以不太高兴的是,此时 babel 6babel-preset-react-app@9.0.0 中的某些 babel 配置不兼容😒,也就是 test 不可用。

$ npm i babel-jest@24.8.0

创建 tsconfig.json 文件

{
    "compilerOptions": {
        "baseUrl": ".",
        "target": "es5",
        "paths": {
            "components/*": [
                "./src/components/*"
            ],
            "src/*": [
                "./src/*"
            ]
        },
        "experimentalDecorators": true
    }
}

测试

创建一个 'test.ts' 文件并且引入 index.js 赶紧测试一下吧。

function add(a: number, b: number) {
  return a + b;
}

export const is666 = add(333, 333) === 666;
import { is666 } from './test';

console.log({ is666 });

如👇

image