当组件具有非法类型时,Create React App withTypeScript 中的 Storybook 仍然可以编译

Eva*_*nss 5 storyboard typescript create-react-app

我正在尝试将 Storybook 添加到 Create React App 并在 TypeScript 中包含所有内容。但是,当我在 React 组件中有非法类型时,我已经编译了它,然后创建 React App 错误(应该如此)但 Storybook 仍然可以编译。

package.json 文件:

{
  "name": "hiit5",
  "version": "0.1.0",
  "private": true,
  "dependencies": {
    "@emotion/core": "^10.0.15",
    "@types/jest": "^24.0.17",
    "@types/node": "^12.7.2",
    "@types/react": "^16.9.1",
    "@types/react-dom": "^16.8.5",
    "prop-types": "^15.7.2",
    "react": "^16.9.0",
    "react-docgen-typescript-webpack-plugin": "^1.1.0",
    "react-dom": "^16.9.0",
    "react-scripts": "3.1.0",
    "typescript": "^3.5.3"
  },
  "scripts": {
    "start": "react-scripts start",
    "build": "react-scripts build",
    "test": "react-scripts test",
    "eject": "react-scripts eject",
    "storybook": "start-storybook -p 6006",
    "build-storybook": "build-storybook"
  },
  "eslintConfig": {
    "extends": "react-app"
  },
  "browserslist": {
    "production": [
      ">0.2%",
      "not dead",
      "not op_mini all"
    ],
    "development": [
      "last 1 chrome version",
      "last 1 firefox version",
      "last 1 safari version"
    ]
  },
  "devDependencies": {
    "@babel/core": "^7.5.5",
    "@storybook/addon-actions": "^5.1.11",
    "@storybook/addon-info": "^5.1.11",
    "@storybook/addon-knobs": "^5.1.11",
    "@storybook/addon-links": "^5.1.11",
    "@storybook/addons": "^5.1.11",
    "@storybook/react": "^5.1.11",
    "@types/storybook__react": "^4.0.2",
    "awesome-typescript-loader": "^5.2.1",
    "babel-core": "^6.26.3",
    "babel-loader": "^8.0.6",
    "prettier": "^1.18.2",
    "react-docgen-typescript-loader": "^3.1.1",
    "storybook-addon-jsx": "^7.1.5"
  }
}
Run Code Online (Sandbox Code Playgroud)

根 tsconfig.json:

{
  "compilerOptions": {
    "target": "es5",
    "lib": [
      "dom",
      "dom.iterable",
      "esnext"
    ],
    "allowJs": true,
    "skipLibCheck": true,
    "esModuleInterop": true,
    "allowSyntheticDefaultImports": true,
    "strict": false,
    "forceConsistentCasingInFileNames": true,
    "module": "esnext",
    "moduleResolution": "node",
    "resolveJsonModule": true,
    "isolatedModules": true,
    "noEmit": true,
    "jsx": "react"
  },
  "include": [
    "src"
  ]
}
Run Code Online (Sandbox Code Playgroud)

.storybook/config.ts

import { configure } from "@storybook/react";

// automatically import all files ending in *.stories.js
const req = require.context("../stories", true, /\.stories\.tsx$/);
function loadStories() {
  req.keys().forEach(filename => req(filename));
}

configure(loadStories, module);
Run Code Online (Sandbox Code Playgroud)

.storybook/tsconfig.ts

{
  "compilerOptions": {
    "outDir": "build/lib",
    "module": "commonjs",
    "target": "es5",
    "lib": ["es5", "es6", "es7", "es2017", "dom"],
    "sourceMap": true,
    "allowJs": false,
    "jsx": "react",
    "moduleResolution": "node",
    "rootDirs": ["src", "stories"],
    "baseUrl": "src",
    "forceConsistentCasingInFileNames": true,
    "noImplicitReturns": true,
    "noImplicitThis": true,
    "noImplicitAny": true,
    "strictNullChecks": true,
    "suppressImplicitAnyIndexErrors": true,
    "noUnusedLocals": true,
    "declaration": true,
    "allowSyntheticDefaultImports": true,
    "experimentalDecorators": true,
    "emitDecoratorMetadata": true
  },
  "include": ["src/**/*"],
  "exclude": ["node_modules", "build", "scripts"]
}
Run Code Online (Sandbox Code Playgroud)

.storybook/webpack.config.js

module.exports = ({ config, mode }) => {
  config.module.rules.push({
    test: /\.(ts|tsx)$/,
    loader: require.resolve("babel-loader"),
    options: {
      presets: [["react-app", { flow: false, typescript: true }]]
    }
  });
  config.resolve.extensions.push(".ts", ".tsx");
  return config;
};
Run Code Online (Sandbox Code Playgroud)

for*_*d04 5

尽管类型错误,Storybook 仍然可以编译的原因是"react-app"Create React App (CRA)中的 Babel 预设只会剥离 TypeScript 定义并发出所有文件,而无需进一步的编译器检查。

react-app/babel-preset-react-app可以将 CRA Babel 配置转移到其他版本,例如 Storybook。在内部,它是基于@通天/预设打字稿,它可以处理这样的.ts / TSX文件:

虽然 Babel 可以接管编译/转译——做一些事情,比如擦除你的类型和重写最新的 ECMAScript 特性以在旧的运行时工作——但它没有内置类型检查,仍然需要使用 TypeScript 来完成。因此,即使 Babel 构建成功,您也可能需要使用 TypeScript 来检查类型错误。关联

解决方案

1.) babel-preset-react-app

坚持babel-preset-react-app并用于tsc检查编译错误。在微软/打字稿,巴贝尔起动库展示了如何运行一个类型检查与配置NPM脚本tsc

"type-check": "tsc --noEmit",
"type-check:watch": "npm run type-check -- --watch",
Run Code Online (Sandbox Code Playgroud)

某些 IDE 任务可以进一步包装这些脚本(例如,如果您使用 VS Code)。

2.) 成熟的编译器,例如 awesome-typescript-loader

使用一些像awesome-typescript-loader这样的Webpack TypeScript 加载器在捆绑期间使用完整的编译器(Link)。

webpack.config.js:

module.exports = ({ config, mode }) => {
  config.module.rules.push({
    test: /\.(ts|tsx)$/,
    loader: "awesome-typescript-loader"
  });
  config.resolve.extensions.push(".ts", ".tsx");
  return config;
};
Run Code Online (Sandbox Code Playgroud)

设置

tsconfig.json:

{
  ...
  "compilerOptions": {
    // if you use awesome-typescript-loader
    "jsx": "react"
  },
  // include stories and src for type checking
  "include": ["src", "stories"]
}
Run Code Online (Sandbox Code Playgroud)