6

React Styleguidist 入门

 3 years ago
source link: https://segmentfault.com/a/1190000039868553
Go to the source link to view the article. You can view the picture content, updated content and better typesetting reading experience. If the link is broken, please click the button below to view the snapshot at that time.

React Styleguidist 入门

此文章是由个人对该技术的理解和解读官网翻译而来,不免有不太恰当的地方,望多多指教,共同学习。

react-styleguidist 会把所有组件都显示在一个页面上,包含 props 文档和用法示例,以及一个独立开发组件的环境。 在Styleguidist 中,可以在 Markdown 中编写示例,每个代码段都会立即呈现;

Styleguidist会加载组件,使用react-docgen生成文档,可能需要更改代码才能正常工作。

React-docgen会把组件作为静态文本文件读取,然后类似于查找React组件的模式去查找组件(例如类或函数声明)。React-docgen不会运行任何JavaScript代码,因此,如果组件是动态生成,或包装在高阶组件中,或拆分为多个文件,react-docgen可能无法理解。

React-docgen支持通过React.createClass,ES6 classes 和函数组件定义的组件;
React-docgen支持Flow和TypeScript注释;

在某些情况下,可以通过导出两个组件 欺骗 Styleguidist和react-docgen:

  • 作为命名导出的基本组件
  • 作为默认导出的增强组件
import React from 'react'
import CSSModules from 'react-css-modules'
import styles from './Button.css'

// Base component will be used by react-docgen to generate documentation
export function Button({ color, size, children }) {
  /* ... */
}

// Enhanced component will be used when you write <Button /> in your example files
export default CSSModules(Button, styles)

安装 Styleguidist:

// npm
npm install --save react-styleguidist

// yarn
yarn add react-styleguidist

配置package.json脚本

"scripts": {
  "styleguide": "NODE_ENV=development styleguidist server",
  "styleguide:build": "NODE_ENV=production styleguidist build",
}

运行Styleguidist

npm run styleguide  //启动styleguidist开发服务器
npm run styleguide:build  //构建生产HTML版本

组件生成文档

Styleguidist根据组件中的注释,propTypes声明和Readerme.md为组件生成文档。

解析props

默认行为:Styleguidist从propTypes中获取props并生成一个表格,并根据props的注释显示组件的说明,根据defaultProps获取props的默认值。

import React from 'react'
import PropTypes from 'prop-types'
/**
 * General component description in JSDoc format. Markdown is    *supported*.
 */
export default class Button extends React.Component {
  static propTypes = {
    /** Description of prop "foo". */
    foo: PropTypes.number,
    /** Description of prop "baz". */
    baz: PropTypes.oneOfType([PropTypes.number, PropTypes.string])
  }

  static defaultProps = {
    foo: 42
  }

  render() {
    /* ... */
  }
}

修改默认行为

可以使用propsParserresolver更改解析props默认行为;

propsParser: Function
此方法可以重新个从源文件如何解析props。默认是使用react-docgen进行解析。

module.exports = {
  propsParser(filePath, source, resolver, handlers) {
    return require('react-docgen').parse(source, resolver, handlers)
  }
}

resolver
此方法可以确定哪些类/组件需要解析。默认行为是在每个文件中查找所有导出的组件,可以配置它以让所有查找到的组件使用自定义解析方法。

module.exports = {
  resolver: require('react-docgen').resolver
    .findAllComponentDefinitions
}

组件的PropType和文档注释由react-docgen库解析, 可以使用updateDocs函数对其进行修改。有关解析props的更多信息,可参见react-docgen文档。

示例文件查找与编写

默认行为:Styleguidist默认在组件文件夹下查找Readme.md[ComponentName].md的文件并生成示例文件。
带有js,jsx或javascript标记的代码块将被呈现为带有交互式的React组件。为了向后兼容,不带语言标签的代码块也会展示成带有交互式的React组件。

React component example:

​```js
<Button size="large">Push Me</Button>
​```

You can add a custom props to an example wrapper:

​```js { "props": { "className": "checks" } }
<Button>I’m transparent!</Button>
​```

To render an example as highlighted source code add a `static` modifier:

​```jsx static
import React from 'react';
​```

修改默认行为

可以通过getExampleFilename自定义md 文件名字,此方法通过提供的组建文件路径返回新的 md 文件路径。
例如:用 ComponentName.examples.md代替 Readme.md

module.exports = {
  getExampleFilename(componentPath) {
    return componentPath.replace(/\.jsx?$/, '.examples.md')
  }
}

关联其他示例文件

可以使用@example doclet语法将其他示例文件与组件关联。
例子:Button 组件有一个从extra.examples.md文件加载的示例

/**
 * Component is described here.
 *
 * @example ./extra.examples.md
 */
export default class Button extends React.Component {
  // ...
}

写 code

  • 导入依赖项: 通过import导入
  • 管理状态:每个示例都是一个function组件,可以使用useState Hook来处理状态。
// ```jsx inside Markdown
import React from 'react'
import Button from 'rsg-example/components/Button'
import Placeholder from 'rsg-example/components/Placeholder'
;<Button size="large">Push Me</Button>


// ```jsx inside Markdown
const [isOpen, setIsOpen] = React.useState(false)
;<div>
  <button onClick={() => setIsOpen(true)}>Open</button>
  <Modal isOpen={isOpen}>
    <h1>Hallo!</h1>
    <button onClick={() => setIsOpen(false)}>Close</button>
  </Modal>
</div>

moduleAliases
定义模块的别名,可以在示例文件中导入这些别名,以使示例代码更加实际和可复制;

const path = require('path');

module.exports = {
  moduleAliases: {
    'rsg-example': path.resolve(__dirname, 'src')
  }
}
  • Markdown语法都被支持;
  • 如果需要在文档中显示一些不想被呈现为交互式的JavaScript代码,则可以将static修饰符与语言标签一起使用;
  • Styleguidist 通过 Bublé 运行ES6代码, 大多数ES6功能都支持;
  • rsg-example模块是由moduleAliases 选项定义的别名;
  • 如果需要更复杂的演示,通常最好将其定义在一个单独的JavaScript文件中,然后将其导入Markdown中

默认情况下,组件所具有的任何方法均被视为私有方法,不会被发布。使用JSDoc @public标记方法,就可以使其成为公共方法并会在文档中发布。

/**
 * @param {string} name
 * @public
 */
getName(name) {
  // ...
}

隐藏props

默认情况下,组件所有的props都是公开并可发布。在某些情况下代码存在某props, 希望文档中不展示这个props,使用JSDoc @ignore标记props,就可以将其从文档中删除。

Button.propTypes = {
  /**
   * A prop that should not be visible in the documentation.
   * @ignore
   */
  hiddenProp: React.PropTypes.string
}

默认情况下,Styleguidist将使用此模式定位组件:src/components/**/*.{js,jsx,ts,tsx}
例如:

  • src/components/Button.js
  • src/components/Button/Button.js
  • src/components/Button/index.js

但是会忽略 tests 文件:

  • __tests__ 文件夹
  • 文件名里包含.test.js.spec.js (类似于: .jsx, .ts , .tsx)

修改默认查找方式

styleguide.config.js文件里的配置components可以修改组件查找方式来适应不同的项目;

例如:如果组件路径是components/Button/Button.js,为了简化导入在components/Button/index.js中再次导出(export { default } from './Button'),【为了让components/Button替代components/Button/Button】, 这时候需要跳过 index.js。

module.exports = {
  components: 'src/components/**/[A-Z]*.js'
}

使用ignore可将某些文件从样式指南中排除

ignore:String[]

[
  '**/__tests__/**', 
  '**/*.test.{js,jsx,ts,tsx}', 
  '**/*.spec.{js,jsx,ts,tsx}', 
  '**/*.d.ts'
]

使用getComponentPathLine更改组件导入路径

getComponentPathLine: Function
默认值: 组件文件名
返回值:返回组件路径

例如: 从components/Button中导入Button,而不是components/Button /Button.js

const path = require('path');
module.exports = {
  getComponentPathLine(componentPath) {
    const name = path.basename(componentPath, '.js')
    const dir = path.dirname(componentPath)
    return `import ${name} from '${dir}';`
  }
}

所有路径都相对于config文件夹;

Styleguidist加载组件并暴露在全局以供示例使用。

Styleguidist默认使用组件的displayName作为标识符。如果它不能理解displayName(displayName动态生成),它将退回到它可以理解的东西。

Sections

Sections: Array[{}]

将组件分组,或将额外的Markdown文档添加到样式指南中。

Sections数组的每一项有:

  • name — Sections 标题;
  • content — 包含概述内容的Markdown文件的位置;
  • components — 可以是glob模式字符串,组件路径数组,glob模式字符串数组,返回一个组件数组的函数或返回glob模式字符串的函数。规则与根选项components相同;
  • sections — 嵌套的Sections数组(可以再嵌套);
  • description — section描述;
  • sectionDepth — 单个页面的小节数,仅在pagePerSection中可用;
  • exampleMode — 代码示例的初始状态,使用 exampleMode.
  • usageMode — props和方法的初始状态, 使用 usageMode.
  • ignore — 需要忽略的文件,值可以是字符串或数组;
  • href - navigate的URL(不是导航到Sections 内容的URL);
  • external - 如果设置,会打开一个新页面;
  • expand - 在常规设置中将tocMode设置为collapse折叠时,确认是否应该被展开;

上述所有字段都是可选的;

// styleguide.config.js

module.exports = {
  sections: [
    {
      name: 'Introduction',
      content: 'docs/introduction.md'
    },
    {
      name: 'Documentation',
      sections: [
        {
          name: 'Installation',
          content: 'docs/installation.md',
          description: 'The description for the installation section'
        },
        {
          name: 'Configuration',
          content: 'docs/configuration.md'
        },
        {
          name: 'Live Demo',
          external: true,
          href: 'http://example.com'
        }
      ]
    },
    {
      name: 'UI Components',
      content: 'docs/ui.md',
      components: 'lib/components/ui/*.js',
      exampleMode: 'expand', // 'hide' | 'collapse' | 'expand'
      usageMode: 'expand' // 'hide' | 'collapse' | 'expand'
    }
  ]
}

配置webpack

Styleguidist依赖webpack,使用webpack确定如何加载项目的文件,但项目也不一定非要配置webpack。
默认情况下,Styleguidist会在项目的根目录中查找webpack.config.js并使用它。

自定义Webpack配置

如果webpack配置在其他位置,则需要手动加载:

module.exports = {
  webpackConfig: require('./configs/webpack.js')
}

也可以merge多个webpack配置:

module.exports = {
  webpackConfig: Object.assign({}, require('./configs/webpack.js'), {
    /* Custom config options */
  })
}
  • 配置entry, externals, output, watch, 和 stats .会被忽略。生产上,devtool 也会被忽略;
  • 插件 CommonsChunkPlugins, HtmlWebpackPlugin, MiniHtmlWebpackPlugin, UglifyJsPlugin, TerserPlugin, HotModuleReplacementPlugin 会被忽略, 因为 Styleguidist 已经引入了他们,再次引入会影响 Styleguidist;
  • 如果loaders 不起作用,请尝试包含和排除绝对路径;

styleguide配置

title: String

serverPort: Number
端口号

require: Array
添加用户自定义的js, CSS 或 polyfills

assetsDir: String
资源文件名

styleguideDir: String
默认值:styleguide
定义styleguidist构建命令生成的静态HTML的文件夹;

getComponentPathLine: Function
获取组件加载路径

template: Object | Function
更改应用程序的HTML。 一个可以添加favicon,meta 标签, 内嵌JavaScript或CSS的对象。

styles: Object | String | Function
自定义Styleguidist组件的样式。

theme: Object | String
配置值可以是对象或导出此类对象的文件的路径实现自定义UI字体,颜色等;
配置的文件路径是相对配置文件或者绝对路径。

sections
设置组件分组;

styleguideComponents: Object
重写被用于渲染到浏览器的React组件;

webpackConfig
自定义webpack配置;

更多配置选项查看官方文档:configuration


About Joyk


Aggregate valuable and interesting links.
Joyk means Joy of geeK