diff --git a/MIGRATION.md b/MIGRATION.md index e0fe6cf12790..2e5b4eae8b12 100644 --- a/MIGRATION.md +++ b/MIGRATION.md @@ -5,6 +5,7 @@ - [From version 3.4.x to 4.0.x](#from-version-34x-to-40x) - [Keyboard shortcuts moved](#keyboard-shortcuts-moved) - [Removed addWithInfo](#removed-add-with-info) + - [Removed RN packager](#removed-rn-packager) - [Removed RN addons](#removed-rn-addons) - [Storyshots changes](#storyshots-changes) - [Webpack 4](#webpack-4) @@ -27,7 +28,7 @@ ## From version 3.4.x to 4.0.x -With 4.0 as our first major release in over a year, we've collected a lot of cleanup tasks. All deprecations have been marked for months, so we hope that there will be no significant impact on your project. +With 4.0 as our first major release in over a year, we've collected a lot of cleanup tasks. Most of the deprecations have been marked for months, so we hope that there will be no significant impact on your project. ### Generic addons @@ -58,6 +59,14 @@ import { number } from "@storybook/addon-knobs"; `Addon-info`'s `addWithInfo` has been marked deprecated since 3.2. In 4.0 we've removed it completely. See the package [README](https://github.com/storybooks/storybook/blob/master/addons/info/README.md) for the proper usage. +### Removed RN packager + +Since storybook version v4.0 packager is removed from storybook. The suggested storybook usage is to include it inside your app. +If you want to keep the old behaviour, you have to start the packager yourself with a different project root. +`npm run storybook start -p 7007 | react-native start --projectRoot storybook` + +Removed cli options: `--packager-port --root --projectRoots -r, --reset-cache --skip-packager --haul --platform --metro-config` + ### Removed RN addons The `@storybook/react-native` had built-in addons (`addon-actions` and `addon-links`) that have been marked as deprecated since 3.x. They have been fully removed in 4.x. If your project still uses the built-ins, you'll need to add explicit dependencies on `@storybook/addon-actions` and/or `@storybook/addon-links` and import directly from those packages. diff --git a/app/react-native/package.json b/app/react-native/package.json index f3113296f981..905ae51715f0 100644 --- a/app/react-native/package.json +++ b/app/react-native/package.json @@ -42,10 +42,8 @@ "babel-plugin-transform-regenerator": "^6.26.0", "babel-plugin-transform-runtime": "^6.23.0", "babel-preset-env": "^1.7.0", - "babel-preset-flow": "^6.23.0", "babel-preset-minify": "^0.4.2", "babel-preset-react": "^6.24.1", - "babel-register": "^6.26.0", "babel-runtime": "^6.26.0", "case-sensitive-paths-webpack-plugin": "^2.1.2", "commander": "^2.17.0", diff --git a/app/react-native/readme.md b/app/react-native/readme.md index a9d395801366..5c329aeb9686 100644 --- a/app/react-native/readme.md +++ b/app/react-native/readme.md @@ -15,14 +15,11 @@ npm -g i @storybook/cli storybook init ``` -After you have installed, there are additional steps for `create-react-native-app` apps. See the section for details, otherwise skip to [Start Storybook](#start-storybook) -to see the next step. +The next thing you need to do is make Storybook UI visible in your app. -## Create React Native App (CRNA) +### CRNA, React Native vanilla -If you run `storybook init` inside a CRNA app, you'll be notified that there is an extra step required to use Storybook. - -The easiest way to use Storybook inside CRNA is to simply replace your App with the Storybook UI, which is possible by replacing `App.js` with a single line of code: +The easiest way to use Storybook is to simply replace your App with the Storybook UI, which is possible by replacing `App.js` with a single line of code: ```js export default from './storybook'; @@ -39,10 +36,13 @@ import App from './app'; module.exports = __DEV__ ? StorybookUI : App; ``` -Alternatively, `StorybookUI` is simply a RN `View` component that can be embedded anywhere in your RN application, e.g. on a tab or within an admin screen. +### React Native Navigation, other complex use cases + +`StorybookUI` is simply a RN `View` component that can be embedded anywhere in your RN application, e.g. on a tab or within an admin screen. -## Start Storybook +## Start Storybook server (optional) +If you want to control storybook from browser/VS Code/websockets you need to start the server. After initial setup start the storybook server with the storybook npm script. ```shell @@ -51,6 +51,15 @@ npm run storybook Now, you can open to view your storybook menus in the browser. +## Old standalone behaviour +Since storybook version v4.0 packager is removed from storybook. +The suggested storybook usage is to include it inside your app. +If you want to keep the old behaviour, you have to start the packager yourself with a different project root. + +``` +npm run storybook start -p 7007 | react-native start --projectRoot storybook +``` + ## Start App To see your Storybook stories on the device, you should start your mobile app for the `` of your choice (typically `ios` or `android`). (Note that due to an implementation detail, your stories will only show up in the left pane of your browser window after your device has connected to this storybook server.) @@ -68,41 +77,6 @@ Once your app is started, changing the selected story in web browser will update If you are using Android and you get the following error after running the app: `'websocket: connection error', 'Failed to connect to localhost/127.0.0.1:7007'`, you have to forward the port 7007 on your device/emulator to port 7007 on your local machine with the following command: `adb reverse tcp:7007 tcp:7007` -## Using Haul-cli - -[Haul](https://github.com/callstack-io/haul) is an alternative to the react-native packager and has several advantages in that it allows you to define your own loaders, and handles symlinks better. - -If you want to use haul instead of the react-native packager, modify the storybook npm script to: - -```sh -storybook start -p 7007 --haul webpack.haul.storybook.js --platform android | ios | all -``` - -Where webpack.haul.storybook.js should look something like this: - -```js -module.exports = ({ platform }) => ({ - entry: `./storybook/index.${platform}.js`, - // any other haul config here. -}); -``` - -## Seamless Typescript Integration - -*Note: These instructions are for react-native >= 0.45, @storybook/react-native >= 4.0.0-alpha.2 or higher and the (default) [metro](https://github.com/facebook/metro) bundler* - -For seamless type integration (no intermediate build step) we use the custom rn cli config feature and the [react-native-typescript-transformer](https://github.com/ds300/react-native-typescript-transformer) project - -First follow the instructions [here](https://github.com/ds300/react-native-typescript-transformer#step-1-install). - -Now update your storybook `package.json` script to the following - - "scripts": { - "storybook": "storybook start --metro-config $PWD/rn-cli.config.js -p 7007" - } - -The metro bundler requires an absolute path to the config. The above setup assumes the `rn-cli.config.js` is in the root of your project or next to your `package.json` - ## Start Command Parameters The following parameters can be passed to the start command: @@ -112,32 +86,16 @@ The following parameters can be passed to the start command: host to listen on -p, --port port to listen on ---haul - use haul with config file ---platform - build platform-specific build -s, --secured whether server is running on https -c, --config-dir [dir-name] storybook config directory ---metro-config [relative-config-path] - Metro Bundler Custom config -e, --environment [environment] DEVELOPMENT/PRODUCTION environment for webpack --r, --reset-cache - reset react native packager ---skip-packager - run only storybook server -i, --manual-id allow multiple users to work with same storybook --smoke-test Exit after successful start ---packager-port - Custom packager port ---root [root] - Add additional root(s) to be used by the packager in this project ---projectRoots [projectRoots] - Override the root(s) to be used by the packager ``` ## getStorybookUI Options diff --git a/app/react-native/src/bin/storybook-start.js b/app/react-native/src/bin/storybook-start.js index 1ca027fd48c1..fb660525e743 100644 --- a/app/react-native/src/bin/storybook-start.js +++ b/app/react-native/src/bin/storybook-start.js @@ -1,6 +1,5 @@ #!/usr/bin/env node /* eslint-disable no-console */ -import { exec } from 'child_process'; import path from 'path'; import program from 'commander'; import Server from '../server'; @@ -8,19 +7,11 @@ import Server from '../server'; program .option('-h, --host ', 'host to listen on') .option('-p, --port ', 'port to listen on') - .option('--haul ', 'use haul with config file') - .option('--platform ', 'build platform-specific build') .option('-s, --secured', 'whether server is running on https') .option('-c, --config-dir [dir-name]', 'storybook config directory') - .option('--metro-config [relative-config-path]', 'Metro Bundler Custom config') .option('-e, --environment [environment]', 'DEVELOPMENT/PRODUCTION environment for webpack') - .option('-r, --reset-cache', 'reset react native packager') - .option('--skip-packager', 'run only storybook server') .option('-i, --manual-id', 'allow multiple users to work with same storybook') .option('--smoke-test', 'Exit after successful start') - .option('--packager-port ', 'Custom packager port') - .option('--root [root]', 'Add additional root(s) to be used by the packager in this project') - .option('--projectRoots [projectRoots]', 'Override the root(s) to be used by the packager') .parse(process.argv); const projectDir = path.resolve(); @@ -48,61 +39,3 @@ server.listen(...listenAddr, err => { process.exit(0); } }); - -if (!program.skipPackager) { - let symlinks = []; - - let roots = [projectDir]; - - if (program.root) { - roots = roots.concat(program.root.split(',').map(root => path.resolve(root))); - } - - try { - // eslint-disable-next-line global-require - require('babel-register')({ - presets: [require.resolve('babel-preset-flow')], - ignore: false, - babelrc: false, - }); - - // eslint-disable-next-line global-require - const findSymlinkedModules = require('react-native/local-cli/util/findSymlinkedModules'); - symlinks = roots.reduce((arr, rootPath) => arr.concat(findSymlinkedModules(rootPath, roots)), [ - ...roots, - ]); - } catch (e) { - console.warn(`Unable to load findSymlinksPaths: ${e.message}`, e); - } - - let projectRoots = (configDir === projectDir ? [] : [configDir]).concat(symlinks); - - if (program.projectRoots) { - projectRoots = projectRoots.concat( - program.projectRoots.split(',').map(root => path.resolve(root)) - ); - } - - let cliCommand = 'react-native start'; - - if (program.metroConfig) { - cliCommand += ` --config ${program.metroConfig}`; - } - - if (program.haul) { - const platform = program.platform || 'all'; - cliCommand = `haul start --config ${program.haul} --platform ${platform}`; - } - // RN packager - exec( - [ - cliCommand, - `--projectRoots ${projectRoots.join(',')}`, - program.resetCache && '--reset-cache', - program.packagerPort && `--port=${program.packagerPort}`, - ] - .filter(x => x) - .join(' '), - { async: true } - ); -}