Skip to content

Commit

Permalink
Merge pull request #4261 from storybooks/remove-packager-react-native
Browse files Browse the repository at this point in the history
Removing the packager from storybook.
  • Loading branch information
igor-dv authored Oct 8, 2018
2 parents c845723 + fdcfaf8 commit d1cae5e
Show file tree
Hide file tree
Showing 4 changed files with 27 additions and 129 deletions.
11 changes: 10 additions & 1 deletion MIGRATION.md
Original file line number Diff line number Diff line change
Expand Up @@ -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)
Expand All @@ -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

Expand Down Expand Up @@ -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.
Expand Down
2 changes: 0 additions & 2 deletions app/react-native/package.json
Original file line number Diff line number Diff line change
Expand Up @@ -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",
Expand Down
76 changes: 17 additions & 59 deletions app/react-native/readme.md
Original file line number Diff line number Diff line change
Expand Up @@ -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';
Expand All @@ -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
Expand All @@ -51,6 +51,15 @@ npm run storybook

Now, you can open <http://localhost:7007> 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 `<platform>` 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.)
Expand All @@ -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:
Expand All @@ -112,32 +86,16 @@ The following parameters can be passed to the start command:
host to listen on
-p, --port <port>
port to listen on
--haul <configFile>
use haul with config file
--platform <ios|android|all>
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 <packagerPort>
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
Expand Down
67 changes: 0 additions & 67 deletions app/react-native/src/bin/storybook-start.js
Original file line number Diff line number Diff line change
@@ -1,26 +1,17 @@
#!/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';

program
.option('-h, --host <host>', 'host to listen on')
.option('-p, --port <port>', 'port to listen on')
.option('--haul <configFile>', 'use haul with config file')
.option('--platform <ios|android|all>', '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 <packagerPort>', '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();
Expand Down Expand Up @@ -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 }
);
}

0 comments on commit d1cae5e

Please sign in to comment.