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 polyfills

安裝 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
標籤