当组件具有非法类型时,Create React App withTypeScript 中的 Storybook 仍然可以编译
Storybook in Create React App withTypeScript still compiles when component has illegal types
我正在尝试将 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"
}
}
根目录 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"
]
}
.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);
.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"]
}
.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;
};
尽管存在类型错误,Storybook 仍然编译的原因是 Create React App (CRA) 中的 Babel 预设 "react-app"
仅剥离 TypeScript 定义并发出所有文件,而无需进一步的编译器检查。
react-app
/ babel-preset-react-app
can carry the CRA Babel configuration over to other builds, like Storybook. Internally, it is based on @babel/preset-typescript,这样处理 .ts/tsx 文件:
While Babel can take over compiling/transpiling – doing things like erasing your types and rewriting the newest ECMAScript features to work in older runtimes – it doesn’t have type-checking built in, and still requires using TypeScript to accomplish that. So even if Babel builds successfully, you might need to check in with TypeScript to catch type errors. Link
解决方案
1.) babel-preset-react-app
坚持使用 babel-preset-react-app
并使用 tsc
检查编译错误。 Microsoft/TypeScript-Babel-Starter 存储库显示了如何配置 运行 使用 tsc
:
进行类型检查的 npm 脚本
"type-check": "tsc --noEmit",
"type-check:watch": "npm run type-check -- --watch",
这些脚本可以通过一些 IDE 任务进一步包装(例如,如果您使用 VS Code)。
2.) 成熟的编译器,例如awesome-typescript-loader
使用一些 Webpack TypeScript 加载器,例如 awesome-typescript-loader
,它在捆绑期间使用完整的编译器 (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;
};
设置
tsconfig.json:
{
...
"compilerOptions": {
// if you use awesome-typescript-loader
"jsx": "react"
},
// include stories and src for type checking
"include": ["src", "stories"]
}
我正在尝试将 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"
}
}
根目录 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"
]
}
.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);
.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"]
}
.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;
};
尽管存在类型错误,Storybook 仍然编译的原因是 Create React App (CRA) 中的 Babel 预设 "react-app"
仅剥离 TypeScript 定义并发出所有文件,而无需进一步的编译器检查。
react-app
/ babel-preset-react-app
can carry the CRA Babel configuration over to other builds, like Storybook. Internally, it is based on @babel/preset-typescript,这样处理 .ts/tsx 文件:
While Babel can take over compiling/transpiling – doing things like erasing your types and rewriting the newest ECMAScript features to work in older runtimes – it doesn’t have type-checking built in, and still requires using TypeScript to accomplish that. So even if Babel builds successfully, you might need to check in with TypeScript to catch type errors. Link
解决方案
1.) babel-preset-react-app
坚持使用 babel-preset-react-app
并使用 tsc
检查编译错误。 Microsoft/TypeScript-Babel-Starter 存储库显示了如何配置 运行 使用 tsc
:
"type-check": "tsc --noEmit",
"type-check:watch": "npm run type-check -- --watch",
这些脚本可以通过一些 IDE 任务进一步包装(例如,如果您使用 VS Code)。
2.) 成熟的编译器,例如awesome-typescript-loader
使用一些 Webpack TypeScript 加载器,例如 awesome-typescript-loader
,它在捆绑期间使用完整的编译器 (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;
};
设置
tsconfig.json:
{
...
"compilerOptions": {
// if you use awesome-typescript-loader
"jsx": "react"
},
// include stories and src for type checking
"include": ["src", "stories"]
}