React Native Web

为 react-native-web 配置 React storybook

在 Github 上查看

Storybook 的 React Native Web 附加组件

此附加组件配置 @storybook/react 以使用 React Native for Web (RNW) 显示 React Native (RN) 项目。

有关常见问题,请参阅 常见问题解答

您可以在 这篇博文中 阅读有关此包的更多信息。

要做出贡献,请参阅贡献指南 此处

以下是从以下 入门代码 中获取的图片,展示了您如何将它与 storybook/react-native 一起使用。

image with storybook on mobile and web

入门

假设您已经拥有一个现有的 RN 项目,请从项目根目录中运行以下命令

npx sb init --type react
yarn add react-dom react-native-web babel-plugin-react-native-web @storybook/addon-react-native-web @react-native/babel-preset --dev

然后编辑您的 .storybook/main.js

module.exports = {
  addons: [/*existing addons,*/ '@storybook/addon-react-native-web'],
};

从这里开始,您应该能够根据 React 的 Storybook 说明编写包含您的 RN 组件的故事。

常见问题

有关“未找到加载器”错误等常见问题,请参阅 常见问题解答

配置选项

大多数包应该可以在没有额外更改的情况下工作,但在某些情况下,需要额外步骤。一个常见的例子是“reanimated”,它需要一些 Babel 配置和额外的转译。

选项 类型 描述
modulesToTranspile Array<string> 需要转译的 node_modules
modulesToAlias {[key: string]: string} 需要添加别名的 node_modules
babelPlugins Array<string | [string, Record<string, string>]> 您要应用的 Babel 插件
projectRoot string 您项目的根目录路径,如果您在单仓库中,则可能需要设置它。
babelPresets Array<string | [string, Record<string, string>]> 您要应用的 Babel 预设
babelPresetReactOptions Record<string, any> 要传递给 @babel/preset-react 的选项
babelPresetReactNativeOptions Record<string, any> 要传递给 @react-native/babel-preset 的选项

未转译的 React Native 库

许多 React Native 包是未转译的,这在 Web 平台上不起作用。如果您在添加包后收到类似“未找到适当的加载器”的错误,请尝试将其添加到此附加组件的 modulesToTranspile 选项中。

您可以像这样操作

module.exports = {
  addons: [
    /*existing addons,*/
    {
      name: '@storybook/addon-react-native-web',
      options: {
        modulesToTranspile: ['react-native-package-name'],
      },
    },
  ],
};

为 React Native Web 库添加别名

一些 React Native 包建议模块别名作为导入和使用现有包的 Web 变体的方法。如果您需要向 webpack 的 config.resolve.alias 添加额外的键值对,请使用此附加组件的 modulesToAlias 选项。您不需要将 react-native-web 添加到此列表,因为它默认已包含在内。

您可以像这样操作

module.exports = {
  addons: [
    /*existing addons,*/
    {
      name: '@storybook/addon-react-native-web',
      options: {
        modulesToAlias: {
          'react-native-package-name': 'react-native-web-package-name',
        },
      },
    },
  ],
};

react-native-package-name 替换为实际包的名称。

添加 Babel 插件

通常需要为 React Native 生态系统中的某些包提供 Babel 插件,您可以将这些插件的列表传递给附加组件。

module.exports = {
  addons: [
    /*existing addons,*/
    {
      name: '@storybook/addon-react-native-web',
      options: {
        babelPlugins: ['babel-plugin-name'],
      },
    },
  ],
};

配置流行库

许多库无需额外配置即可工作,以下是一些需要配置的库的示例。

注意:react-native-vector-icons 由于需要字体,因此需要一些额外的步骤,并且将来会发布一个包含该配置的附加组件。

module.exports = {
  addons: [
    /*existing addons,*/
    {
      name: '@storybook/addon-react-native-web',
      options: {
        modulesToTranspile: ['react-native-reanimated'],
        babelPlugins: [
          '@babel/plugin-proposal-export-namespace-from',
          'react-native-reanimated/plugin',
        ],
      },
    },
  ],
};
module.exports = {
  addons: [
    /*existing addons,*/
    {
      name: '@storybook/addon-react-native-web',
      options: {
        modulesToTranspile: ['react-native-vector-icons'],
      },
    },
  ],
};
module.exports = {
  addons: [
    /*existing addons,*/
    {
      name: '@storybook/addon-react-native-web',
      options: {
        modulesToTranspile: ['react-native-vector-icons'],
      },
    },
  ],
};
module.exports = {
  addons: [
    /*existing addons,*/
    {
      name: '@storybook/addon-react-native-web',
      options: {
        modulesToTranspile: [
          'react-native-reanimated',
          'nativewind',
          'react-native-css-interop',
        ],
        babelPresets: ['nativewind/babel'],
        babelPresetReactOptions: { jsxImportSource: 'nativewind' },
        babelPlugins: [
          'react-native-reanimated/plugin',
           [
            '@babel/plugin-transform-react-jsx',
            {
              runtime: 'automatic',
              importSource: 'nativewind',
            },
          ],
         ],
      },
    },
  ],
};

添加对静态资产和 SVG 的支持

安装 @svgr/webpackurl-loader

module.exports = {
  /*existing config*/
  // to provide a public export for assets
  staticDirs: ['<path_to_assets>'],
  webpackFinal: async (config) => {
    const fileLoaderRule = config.module.rules.find(
      (rule) => rule.test && rule.test.test('.svg'),
    );

    if (fileLoaderRule) {
      fileLoaderRule.exclude = /\.svg$/;
    }

    config.module.rules.push({
      test: /\.svg$/,
      use: ['@svgr/webpack', 'url-loader'],
    });

    return config;
  },
};

Webpack 5 的 Node polyfill

安装 node-polyfill-webpack-plugin

const NodePolyfillPlugin = require('node-polyfill-webpack-plugin');

module.exports = {
  /*existing config*/
  core: {
    builder: 'webpack5',
  },
  webpackFinal: async (config) => {
    config.plugins.push(new NodePolyfillPlugin());

    return config;
  },
};

已知限制

  • 不支持 React Native Web 的库将无法工作
  • 组件将在 Web 上显示,因此可能与移动设备上的组件不同,因为可能会使用这些组件的 DOM 版本(如 <div>span)。
    • 当使用 View/Text 等基本组件或其他跨平台组件时,差异应该很小。
由以下人员开发
  • domyen
    domyen
  • kasperpeulen
    kasperpeulen
  • valentinpalkovic
    valentinpalkovic
  • jreinhold
    jreinhold
  • kylegach
    kylegach
  • ndelangen
    ndelangen
与以下内容协同工作
    React Native
标签