Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Removing the packager from storybook. #4261

Merged
merged 3 commits into from
Oct 8, 2018
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension


Conversations
Failed to load comments.
Jump to
Jump to file
Failed to load files.
Diff view
Diff view
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 @@ -26,7 +27,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 @@ -57,6 +58,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')],
Copy link
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

do babel-register and babel-preset-flow still need to be installed?

Copy link
Member Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Good question. What were they used for in the first place?

Copy link
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

I have no idea =)

Copy link
Member Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Ah but it is flow and some other things. I will remove it.
Thanks @igor-dv .

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 }
);
}