reactjs - 设置 react-styleguidist、创建 React App、Typescript、Material UI 和 styled-components

标签 reactjs typescript material-ui styled-components react-styleguidist

我试图从 Create React App 3 (CRA)、Typescript、Material UI 和 styled-components 设置 react-styleguidist (RSG)。我被这个错误困住了:

./node_modules/react-styleguidist/lib/client/rsg-components/ReactExample/ReactExample.js
Module not found: Can't resolve 'rsg-components/Wrapper' in '/Users/ofj/code/new-core-web/node_modules/react-styleguidist/lib/client/rsg-components/ReactExample'

我按照文档为 MUI 主题和样式组件设置了一个包装器:
https://react-styleguidist.js.org/docs/thirdparties.html#styled-components

/styleguidist/MuiThemeWrapper.tsx

const muiTheme = getMuiTheme({});
const MuiThemeWrapper = ({ children, ...rest }) => (
    <MuiThemeProvider muiTheme={muiTheme}>
        <ThemeProvider theme={theme}>
            {children}
        </ThemeProvider>
    </MuiThemeProvider>
);

export default MuiThemeWrapper;

我的 styleguidist 配置:

/styleguidist.config.js
const path = require('path');
module.exports = {
    components: "src/components/**/layout.{js,jsx,ts,tsx}",
    propsParser: require('react-docgen-typescript').withCustomConfig(
        './tsconfig.json'
      ).parse,
    serverPort: 6161,
    styleguideComponents: {
      Wrapper: path.join(__dirname, 'styleguidist/MuiThemeWrapper.jsx')
    }
};

我的 tsconfig 遵循标准的 CRA/MUI 建议
https://material-ui.com/guides/typescript/

tsconfig.json
{
  "compilerOptions": {
    "noImplicitAny": true,
    "noImplicitThis": true,
    "strictNullChecks": true,
    "baseUrl": "src",
    "target": "es5",
    "lib": [
      "dom",
      "dom.iterable",
      "esnext"
    ],
    "allowJs": true,
    "checkJs": false,
    "pretty": true,
    "skipLibCheck": true,
    "esModuleInterop": true,
    "allowSyntheticDefaultImports": true,
    "strict": true,
    "forceConsistentCasingInFileNames": true,
    "module": "esnext",
    "moduleResolution": "node",
    "resolveJsonModule": true,
    "isolatedModules": true,
    "noEmit": true,
    "jsx": "react"
  },
  "exclude": [
    "node_modules"
  ],
  "types": [
    "./node_modules/@types/"
  ]
}

我没有自定义的 webpack/babel 配置设置,因为我不知道如何也不会弄乱 TS 转译。也许这就是 RSG 工作所缺少的......?
或者 rsg-components/ReactExample/ReactExample.js 的错误是一个错误?

最佳答案

我让它工作了,希望其他人也可能会发现这很有用,因为到目前为止,只有很少的非 typescript 示例配置可以找到。
我的设置需要注意的事项:

  • react mui 应用程序在 src/ , 组件在 src/components/ ,使用 modules:要查看的 webpack 配置 src/对于绝对进口。
  • 应用程序是使用 react 应用程序创建器创建的。
  • tsconfig.json自动创建(覆盖 noEmit 稍后专门用于“ts-loader”,见下文);下面显示了一个重要的异常(exception)/添加。
  • 单独的 webpack 和 babel 配置,包含在 styleguide.config.js 中.
  • tsconfig.json是样板,除了这个 gem paths:'rsg-components/*'这里需要手动添加——隐藏在React Styleguidist's Cookbook中.没有它,我们需要在 webpack 配置中使用别名定义,包括替换包装器!用正确的 paths tsconfig.json 中的定义事情终于开始正确地落实到位。
    {
      "compilerOptions": {
        "paths": {
          "rsg-components/*": [
            "node_modules/react-styleguidist/lib/client/rsg-components/*"
          ]
        }
      }
    }
    
    styleguide.config.js位于项目的顶级目录中:
    const path = require('path')
    
    module.exports = {
        components: [
            'src/components/**/*.{ts,tsx}',
            'src/models/**/*.ts',
        ],
        ignore: [
            'src/**/index.{ts,tsx}',
        ],
        // We need to override how to decide on what an example file is, in order
        // to remove default which tries to document undocumented components. Ugh.
        // So, only document components for which we also have an explicit
        // documentation file named the same as the component file, but ending in
        // ".md" instead.
        getExampleFilename: (cpath) => {
            return cpath.replace(/\.(tsx?)$/, '.md')
        },
        // Show import commands without the component filename extension and only
        // for the module; also remove the first "src/" path component.
        getComponentPathLine: (cpath) => {
            const cname = ['.tsx', '.ts'].reduce((name, ext) => path.basename(name, ext), cpath)
            const cdir = path.dirname(cpath).replace(/^src\//, '')
            return `import { ${cname} } from ${cdir}`
        },
        // How uncivilized: do not list components lacking an example.
        skipComponentsWithoutExample: true,
        // Always expand the props and methods of components.
        usageMode: 'expand',
        // Support rendering prop types of typescript components.
        propsParser: require('react-docgen-typescript').withCustomConfig(
            './tsconfig.json',
            {
                "compilerOptions": { "noEmit": false },
            }
        ).parse,
        // Replace the standard wrapper for example component usage code with our
        // own wrapper which brings in the Material UI theme.
        styleguideComponents: {
            Wrapper: path.join(__dirname, 'styleguidist/MuiThemeWrapper.tsx')
        },
        // Tell webpack what to look for and where and how to load it.
        webpackConfig: {
            resolve: {
                extensions: ['.tsx', '.ts', '.js'],
                // https://webpack.js.org/configuration/resolve/#resolvemodules;
                // we're allowing absolute imports to be satisfied from the src/
                // directory.
                modules: [
                    path.resolve(__dirname, 'src/'), 
                    'node_modules'
                ],
                alias: {
                    // Could also be covered by a modules clause, but we are
                    // sticking with an alias instead to cover only exactly
                    // absolute "styleguidist/..." imports.
                    'styleguidist': path.join(__dirname, 'styleguidist'),
                }
            },
            module: {
                rules: [
                    {
                        test: /\.tsx?$/,
                        exclude: /node_modules/,
                        use: [
                            {
                                loader: 'babel-loader',
                                options: {
                                    presets: [
                                        "@babel/preset-env",
                                        "@babel/react",
                                    ]
                                },
                            },
                            {
                                loader: 'ts-loader',
                                options: {
                                    // Important! Avoids "Error: TypeScript emitted no output for..." errors
                                    compilerOptions: {
                                        noEmit: false,
                                    },
                                },
                            },
                        ],
                    },
                    {
                        test: /\.css$/,
                        loader: 'style-loader!css-loader?modules',
                    },
                    {
                        test: /\.svg$/,
                        loader: 'url-loader',
                    },
                    {
                        test: /\.(woff(2)?|ttf|eot|svg)(\?v=\d+\.\d+\.\d+)?$/,
                        use: [
                            {
                                loader: 'url-loader',
                                options: {
                                    name: '[name].[ext]',
                                    outputPath: 'fonts/',
                                }
                            },
                        ]
                    }
                ]
            },
        }
    }
    
  • 覆盖styleguidist/ modules: 可以涵盖绝对进口子句,但在这种情况下,我选择了别名。你可能会有不同的判断:)
  • 我正在设置一个相当严格的制度,只记录带有示例的组件;如果你不想要,就摆脱它。
  • 困难在于使用正确的加载程序配置 webpack;我启用了 typescript 、TSX 和 JSX,并引入了字体资源。
  • 重要 : 包装在 styleguidist/MuiThemeWrapper.tsx .

  • 那是我的 wrapper styleguidist/MuiThemeWrapper.tsx :
    import React from 'react'
    
    import "fontsource-roboto/400.css"
    import "fontsource-roboto/500.css"
    import "fontsource-roboto/700.css"
    import "fontsource-roboto-mono/400.css"
    
    import { createMuiTheme, ThemeProvider } from '@material-ui/core/styles'
    import CssBaseline from '@material-ui/core/CssBaseline'
    
    const muiTheme = createMuiTheme({})
    
    const MuiThemeWrapper = ({children}) => (
        <ThemeProvider theme={muiTheme}>
            <CssBaseline />
            {children}
        </ThemeProvider>
    )
    
    export default MuiThemeWrapper
    
  • 在我的 react+Material UI 项目中明确引入我需要的 Roboto 字体。
  • 应用 CSS 基线定义,否则 font-family s 不会被正确定义。
  • 关于reactjs - 设置 react-styleguidist、创建 React App、Typescript、Material UI 和 styled-components,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/57976044/

    相关文章:

    reactjs - 在 redux-router 中记录路由变化

    android - 在 ubuntu 16.04 上设置 react-native 时出错

    css - 在 Angular 中更新自定义复选框组件 View

    Typescript 泛型扩展类和接口(interface)

    reactjs - 如何扩展 React 组件?

    reactjs - 我应该在 React : functional components or class base components? 中使用什么类型的组件

    reactjs - 在 React Native 中,多个标记未显示在 map 上

    java - 如何将自定义 HTTP header 发送到端点?

    标题中的 CSS 定位元素

    css - 如何将这个 material-ui 的选择列表与输入 block 的底线对齐?