简体   繁体   中英

React Styleguidist starting slooooooow

We use https://react-styleguidist.js.org/ to develop and display components for re-use. We used it for some years now and consists of JS and TS files. When starting with styleguidist server , the project is unbearable slow (approx. 4 mins). I tried many things to speed it up but nothing seems to make any difference.

I tried:

  • this workaround for react-docgen-typescript with no noticeable improvement.
  • the official configuration.
  • setting skipLibCheck: true in tsconfig.json from this recommendation.

Weird enough the startup seems a tad faster when just using default propsParser and not using react-docgen-typescript . But then not all props are included in the generated documentation.

So I'm really out of ideas... Our style guide is built on CRA v4.0.1. Maybe CRA is the problem? Or maybe the problem is that our style guide has both JS and TS files which "confuses" the TS compiler in some way....?

Any help, advice, or suggestion is most welcome...

package.json

{
  "name": "@xxx/core",
  "version": "2.7.0",
  "scripts": {
    "build:transpile-files": "NODE_ENV=production babel --config-file ./babel.config.js src --out-dir dist --extensions '.ts','.tsx','.js','.jsx' --ignore **/*.d.ts,**/*.spec.tsx,**/*.spec.js,**/styleguide.styled.js,**/setupTests.ts",
    "build:copy-files": "node ./scripts/copy-files.js",
    "build:ts-prod": " tsc --p tsconfig.build.json",
    "build:ts-dev": "tsc --p tsconfig.json",
    "build": "rm -rf dist && yarn build:ts-prod && yarn build:transpile-files && yarn build:copy-files",
    "styleguide": "styleguidist server",
    "styleguide:build": "styleguidist build",
    "test": "DEBUG_PRINT_LIMIT=100000 react-scripts test --env=jest-environment-jsdom-sixteen --color --bail",
    "test:coverage": "CI=true react-scripts test --env=jest-environment-jsdom-sixteen --color --bail --coverage",
    "lint": "eslint src --ext .js,.jsx,.ts,.tsx,.snap",
    "prettier": "npx prettier \"src/**/*.{js,jsx,ts,tsx,scss}\"",
    "format": "yarn prettier --write"
  },
  "dependencies": {
    "@material-ui/lab": "^4.0.0-alpha.57",
    "@tippyjs/react": "^4.2.0",
    "antd": "^4.9.1",
    "fix-webm-duration": "1.0.0",
    "react-dates": "^21.8.0",
    "react-draggable": "^4.3.1",
    "react-virtualized-auto-sizer": "^1.0.2",
    "react-window": "^1.8.5",
    "react-window-infinite-loader": "^1.0.5",
    "recharts": "^1.8.5",
    "tippy.js": "^6.2.7",
    "underscore": "^1.9.1"
  },
  "peerDependencies": {
    "@material-ui/core": "4.11.0",
    "@material-ui/icons": "4.9.1",
    "moment": "^2.29.0",
    "prop-types": "^15.7.2",
    "react": "^16.13.1",
    "react-dom": "^16.13.1",
    "react-select": "^3.1.0",
    "styled-components": "^5.0.1"
  },
  "devDependencies": {
    "@babel/cli": "7.5.5",
    "@material-ui/core": "4.11.0",
    "@material-ui/icons": "4.9.1",
    "@testing-library/jest-dom": "^5.11.9",
    "@testing-library/react": "^11.2.3",
    "@testing-library/react-hooks": "^5.0.0",
    "@testing-library/user-event": "^12.6.0",
    "@types/dom-mediacapture-record": "^1.0.7",
    "@types/jest": "^26.0.20",
    "@types/node": "^14.14.22",
    "@types/react": "^16.14.2",
    "@types/react-dates": "^21.8.1",
    "@types/react-dom": "^16.9.10",
    "@types/react-select": "^3.1.2",
    "@types/recharts": "^1.8.19",
    "@types/styled-components": "^5.1.7",
    "@types/testing-library__react": "^10.2.0",
    "@types/testing-library__react-hooks": "^3.4.1",
    "@types/underscore": "^1.11.0",
    "@typescript-eslint/eslint-plugin": "^4.14.0",
    "@typescript-eslint/parser": "^4.14.0",
    "babel-loader": "^8.1.0",
    "enzyme": "3.10.0",
    "enzyme-adapter-react-16": "1.14.0",
    "eslint-config-airbnb": "^18.2.1",
    "eslint-config-prettier": "^6.11.0",
    "eslint-config-react-app": "^6.0.0",
    "eslint-plugin-babel": "5.3.1",
    "eslint-plugin-import": "^2.22.1",
    "eslint-plugin-jest": "^24.1.3",
    "eslint-plugin-jest-dom": "^3.6.5",
    "eslint-plugin-jsx-a11y": "6.4.1",
    "eslint-plugin-prettier": "^3.1.3",
    "eslint-plugin-react": "^7.22.0",
    "eslint-plugin-testing-library": "^3.10.1",
    "fs-extra": "^8.1.0",
    "jest-canvas-mock": "^2.3.0",
    "jest-environment-jsdom-sixteen": "^1.0.3",
    "jest-enzyme": "7.0.2",
    "jest-styled-components": "^7.0.3",
    "moment": "^2.29.0",
    "prettier": "^1.19.1",
    "prop-types": "^15.7.2",
    "react": "^16.13.1",
    "react-docgen-typescript": "^1.21.0",
    "react-dom": "^16.13.1",
    "react-scripts": "^4.0.1",
    "react-select": "^3.1.0",
    "react-styleguidist": "^11.1.5",
    "react-test-renderer": "^16.13.1",
    "styled-components": "^5.0.1",
    "typescript": "^4.1.3"
  },
  "resolutions": {
    "acorn": "^7.1.1",
    "kind-of": "^6.0.3"
  },
  "jest": {
    "collectCoverageFrom": [
      "src/**/*.{js,tsx,ts}",
      "!src/**/{constants,styled,models}.{js,ts}",
      "!src/theme/illustrations/**",
      "!src/theme/icons/**"
    ]
  }
}

tsconfig.json

{
  "compilerOptions": {
    "baseUrl": "src",
    "target": "es6",
    "lib": [
      "dom",
      "dom.iterable",
      "es6"
    ],
    "skipLibCheck": true,
    "esModuleInterop": true,
    "allowSyntheticDefaultImports": true,
    "noImplicitAny": false,
    "strict": true,
    "forceConsistentCasingInFileNames": true,
    "module": "esnext",
    "moduleResolution": "node",
    "resolveJsonModule": true,
    "isolatedModules": true,
    "jsx": "react",
    "allowJs": true,
    "outDir": "dist",
    "sourceMap": true,
    "declaration": true,
    "noEmit": true,
    "noFallthroughCasesInSwitch": true
  },
  "include": [
    "src"
  ]
}

styleguide.config.js

const path = require('path')

module.exports = {
  title: 'CoreWeb',
  propsParser: require('react-docgen-typescript').withCustomConfig('./tsconfig.json').parse,
  pagePerSection: true,
  skipComponentsWithoutExample: true,
  styleguideComponents: {
    Wrapper: path.join(__dirname, './src/utils/styleguidist/ThemeWrapper'),
  },
  template: {
    head: {
      links: [
        {
          rel: 'stylesheet',
          href: 'https://fonts.googleapis.com/css?family=Source+Sans+Pro:300,400,600,700',
        },
      ],
    },
  },
  sections: [
    {
      name: 'Charts',
      components: () => [
        'src/components/Charts/BarChart/index.tsx',
        'src/components/Charts/LineChart/index.tsx',
        'src/components/Charts/PieChart/index.tsx',
        'src/components/GoalCharts/TaskGoalMetrics/index.tsx',
        'src/components/RegistrationCharts/PainBarChart/index.tsx',
        'src/components/RegistrationCharts/MoodBarChart/index.tsx',
        'src/components/RegistrationCharts/SleepBarChart/index.tsx',
        'src/components/RegistrationCharts/AlcoholBarChart/index.tsx',
        'src/components/RegistrationCharts/BloodPressureBarChart/index.tsx',
        'src/components/RegistrationCharts/ExerciseBarChart/index.tsx',
        'src/components/RegistrationCharts/StepsBarChart/index.tsx',
        'src/components/RegistrationCharts/SmokingBarChart/index.tsx',
        'src/components/RegistrationCharts/WeightLineChart/index.tsx',
        'src/components/RegistrationCharts/WaistHipLineChart/index.tsx',
      ],
    },
    {
      name: 'Data display',
      components: () => [
        'src/components/Avatar/layout.tsx',
        'src/components/Chip/layout.tsx',
        'src/components/DefinitionItem/layout.js',
        'src/components/Graphs/Donut/layout.js',
        'src/components/Image/layout.js',
        'src/components/Lightbox/layout.js',
        'src/components/LinkifyText/layout.js',
        'src/components/ListItemIcon/layout.js',
        'src/components/MediaMosaic/layout.js',
        'src/components/Person/index.tsx',
        'src/components/Table/layout.tsx',
        'src/components/TableSelection/layout.js',
        'src/components/Tag/layout.js',
        'src/components/TruncateWithShow/layout.js',
        'src/components/Typography/layout.tsx',
        'src/components/UnreadItems/index.tsx',
        'src/components/Video/layout.tsx',
        'src/components/CircleWithContent/layout.tsx',
      ],
    },
    {
      name: 'Inputs',
      components: () => [
        'src/components/Button/layout.tsx',
        'src/components/ButtonDropdownSelector/layout.js',
        'src/components/Checkbox/layout.tsx',
        'src/components/DatePickers/InlineDatePicker/layout.js',
        'src/components/DatePickers/Range/layout.js',
        'src/components/DatePickers/Single/index.tsx',
        'src/components/DatePickers/HourMin/index.tsx',
        'src/components/EmojiInputBase/layout.js',
        'src/components/EmojiPicker/layout.js',
        'src/components/FilePicker/layout.tsx',
        'src/components/FilledInput/layout.js',
        'src/components/GenderSelector/layout.tsx',
        'src/components/InputButton/layout.js',
        'src/components/MenuButton/index.tsx',
        'src/components/MultiSelectDropdown/layout.js',
        'src/components/RadioGroup/layout.tsx',
        'src/components/SearchTextField/layout.js',
        'src/components/Select/layout.tsx',
        'src/components/Slider/layout.js',
        'src/components/Switch/layout.js',
        'src/components/TextField/layout.tsx',
        'src/components/TimeSelect/layout.js',
        'src/components/ToggleButtonGroup/layout.tsx',
      ],
    },
    {
      name: 'Surfaces',
      components: () => [
        'src/components/Card/index.tsx',
        'src/components/CardContent/layout.tsx',
        'src/components/ProfileCard/layout.js',
        'src/components/MenuList/layout.js',
      ],
    },
    {
      name: 'Navigation',
      components: () => [
        'src/components/CardTabs/layout.tsx',
        'src/components/Tabs/layout.tsx',
        'src/components/SideNavigation/layout.tsx',
      ],
    },
    {
      name: 'Feedback',
      components: () => [
        'src/components/Confirm/index.tsx',
        'src/components/Dialog/layout.js',
        'src/components/EmptyState/index.tsx',
        'src/components/ErrorBoundary/layout.js',
        'src/components/FormDrawer/layout.js',
        'src/components/InfiniteScroller/layout.js',
        'src/components/Inform/layout.js',
        'src/components/InformDialog/layout.js',
        'src/components/Loading/layout.js',
        'src/components/LoadingV2/layout.js',
        'src/components/LoadingV2/layout.js',
        'src/components/SystemMessage/layout.js',
        'src/components/Tooltip/index.tsx',
      ],
    },
    {
      name: 'Drafts',
      components: () => ['src/components/DraftStatus/layout.tsx'],
    },
    {
      name: 'Goals',
      components: () => [
        'src/components/ExerciseActivityForm/index.tsx',
        'src/components/ExerciseIcon/layout.js',
        'src/components/MoodIcon/layout.js',
        'src/components/PainIcon/layout.js',
        'src/components/GoalIcon/index.tsx',
      ],
    },
    {
      name: 'Groups',
      components: () => [
        'src/components/GroupForm/layout.js',
        'src/components/GroupItem/layout.js',
        'src/components/MessageActionComment/layout.js',
        'src/components/MessageActionLike/layout.js',
        'src/components/GroupPost/index.tsx',
        'src/components/MessageComment/layout.tsx',
        'src/components/MessageStatusComments/layout.js',
        'src/components/MessageStatusLikes/layout.js',
      ],
    },
    {
      name: 'Messages',
      components: () => [
        'src/components/MessageAttachmentLinkForm/layout.js',
        'src/components/MessageEditor/layout.js',
        'src/components/MessageMediaAttachment/layout.js',
      ],
    },
    {
      name: 'Notes',
      components: () => ['src/components/Note/layout.js'],
    },
    {
      name: 'Registrations',
      components: () => [
        'src/components/RegistrationInputTag/layout.js',
        'src/components/RegistrationItem/layout.js',
      ],
    },
    {
      name: 'Media',
      components: () => [
        'src/components/CaptureWebcamImageDialog/index.tsx',
        'src/components/RecordWebcamVideoDialog/index.tsx',
        'src/components/VideoAudioUnavailable/layout.js',
      ],
    },
    {
      name: 'Theme',
      components: () => ['src/theme/colors/layout.js', 'src/theme/borderRadius/layout.tsx'],
    },
    {
      name: 'Icons',
      components: ['src/theme/icons/**/layout.tsx'],
    },
    {
      name: 'Illustrations',
      components: ['src/theme/illustrations/**/layout.js', 'src/theme/illustrations/**/layout.tsx'],
    },
    {
      name: 'Utilities',
      components: () => ['src/utils/**/layout.js'],
    },
  ],
}

Since you are using TypeScript and probably using ts-loader (and babel-loader ), you could try using a faster TS transpiler like SWC-loader . For me, it reduced the initial load time roughly in half.

It is pretty simple to implement, just install the dependencies ( @swc/core and swc-loader ) and add the loader to the webapckConfig in your styleguide.config.js ( custom webpack config ).

webpackConfig: {
    ... // your other config here
    module: {
      rules: [
        {
          test: /\.tsx?$/,
          exclude: /(node_modules)/,
          use: {
            loader: "swc-loader",
          }
        },
      ... // your other rules here
      ],
    },
  }

Did you come across any solution to fix the issue?

The technical post webpages of this site follow the CC BY-SA 4.0 protocol. If you need to reprint, please indicate the site URL or the original address.Any question please contact:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM