sysgears / apollo-universal-starter-kit

Apollo Universal Starter Kit is a SEO-friendly, fully-configured, modular starter application that helps developers to streamline web, server, and mobile development with cutting-edge technologies and ultimate code reuse.
https://apollokit.org
MIT License
1.68k stars 323 forks source link

React Storybook integration example #1026

Closed larixer closed 5 years ago

larixer commented 5 years ago

spinjs supports Storybook now, check this code to integrate it: https://github.com/sysgears/spinjs/blob/master/docs/programmatic.md It will let storybook to utilize the same Webpack config used by the kit. So one will be able to import container components in storybook stories as well as presentational components. There still be a need to mock backend, but we can do it the same way as in the tests, that mocking code should work for storybook stories too.

eric-burel commented 5 years ago

Hi, I am trying to setup Storybook, here is my current process:

Now you need to improve the Storybook webpack build to take our own build context into account (mostly handle TypeScript).

Right now I get this code for webpack.config.js:

const createConfig = require('@larix/zen').createConfig;

module.exports = function (baseConfig, configType) {
  const webpackConfig =  createConfig({
    cmd: configType === 'DEVELOPMENT' ? 'watch' : 'build',
    builderOverrides: { stack: ['storybook'] },
    genConfigOverrides: Object.assign({ merge: { entry: 'replace', output: 'replace' } }, baseConfig)
  });
  // FIXES:
  webpackConfig.mode = webpackConfig.mode.toLowerCase()
  delete webpackConfig.config
  return webpackConfig
};

Sadly it does not reckognize .jsx files so I must be wrong somewhere. Still working on it.

Also storybook needs to be ignored somehow otherwise build will fail.

eric-burel commented 5 years ago

Hi, it does not seem to work with  ts files after your PR #1093. I've tested with the ClientCounterView component and the interface keyboard is not accepted. Can we configure Storybook so it gets a config similar to the client package?

larixer commented 5 years ago

@eric-burel Hi it actually uses the same config as client and you can see that index.stories.tsx is obviously written in TypeScript, so it should support both ES6 and TS

eric-burel commented 5 years ago

You are right for the index itself but it fails when I import a tsx component. Eg:

import React from 'react';

import { storiesOf } from '@storybook/react';
import { action } from '@storybook/addon-actions';
import { linkTo } from '@storybook/addon-links';
import { ClientCounterView } from '@gqlapp/counter-client-react/clientCounter/components/ClientCounterView';

const { Button, Welcome } = require('@storybook/react/demo');

interface Foo {
  bar: String
}

storiesOf('Counter test', module)
  .add('Counter', () => (
    <ClientCounterView text="hello">
      <div>Children</div>
    </ClientCounterView>
  ));

const bar :Foo = {bar:"hello"}
console.log(bar)

Using TS is ok in the index but it fails to parse ClientCounterView though, I get this error:

ERROR in /code/vos-talents-dexperts/node_modules/@gqlapp/counter-client-react/clientCounter/components/ClientCounterView.tsx 11:0
client: Module parse failed: The keyword 'interface' is reserved (11:0)
client: You may need an appropriate loader to handle this file type.
eric-burel commented 5 years ago

It behaves as if story build was using a different loader (eg jsx) than the top level import + stories import which will correctly us TypeScript. It fails as soon as I try to use ClientCounterView, be it in a console.log or a add(). You are right that it seems to use the same config as client though, I have stuffs related to TS in the config and the index story loads correctlty.

eric-burel commented 5 years ago

Note that I get a different error if I don't use the @gqlapp "shortcut" (import { ClientCounterView } from '../../../modules/counter/client-react/clientCounter/components/ClientCounterView'; ), then it seems to fail on JSX too:

ERROR in my-app/node_modules/@gqlapp/look-client-react/ui-bootstrap/components/Alert.jsx 10:4
Module parse failed: Unexpected token (10:4)
You may need an appropriate loader to handle this file type.
|   }
|   return (
>     <RSAlert {...props} color={color}>
|       {children}
|     </RSAlert>
ERROR in my-app/node_modules/@gqlapp/module-client-react/BaseModule.ts 10:7
Module parse failed: Unexpected token (10:7)
You may need an appropriate loader to handle this file type.
|  * Common module interface for React and React Native feature modules
|  */
> export interface BaseModuleShape extends GraphQLModuleShape {
|   // Redux reducers list
|   reducer?: ReducersMapObject[];

....
larixer commented 5 years ago

@eric-burel Should be fixed via: https://github.com/sysgears/apollo-universal-starter-kit/commit/9c125ecd9116dec59e49265c8482f1cf3af1fac6

eric-burel commented 5 years ago

Awesome! It's fixed, thanks a lot.

eric-burel commented 5 years ago

Storybook works but now my app itself won't build. Here are the errors:

webDll-webpack error ModuleNotFoundError: Module not found: Error: Can't resolve 'child_process' in '/home/my-app//packages/client/node_modules/cross-spawn'
    at factory.create (/home/my-app//node_modules/webpack/lib/Compilation.js:823:10)
    at factory (/home/my-app//node_modules/webpack/lib/NormalModuleFactory.js:397:22)
    at resolver (/home/my-app//node_modules/webpack/lib/NormalModuleFactory.js:130:21)
    at asyncLib.parallel (/home/my-app//node_modules/webpack/lib/NormalModuleFactory.js:224:22)
    at /home/my-app//node_modules/neo-async/async.js:2825:7
    at /home/my-app//node_modules/neo-async/async.js:6886:13
    at normalResolver.resolve (/home/my-app//node_modules/webpack/lib/NormalModuleFactory.js:214:25)
    at doResolve (/home/my-app//node_modules/enhanced-resolve/lib/Resolver.js:184:12)
    at hook.callAsync (/home/my-app//node_modules/enhanced-resolve/lib/Resolver.js:238:5)
    at _fn0 (eval at create (/home/my-app//node_modules/tapable/lib/HookCodeFactory.js:33:10), <anonymous>:15:1)

zen error Error: Build error
    at webpackReporter (/home/my-app//node_modules/@larix/zen/src/executor.ts:120:11)
    at reporter (/home/my-app//node_modules/@larix/zen/src/executor.ts:800:50)
    at finalCallback (/home/my-app//node_modules/webpack/lib/Compiler.js:220:39)
    at onCompiled (/home/my-app//node_modules/webpack/lib/Compiler.js:228:20)
    at hooks.make.callAsync.err (/home/my-app//node_modules/webpack/lib/Compiler.js:620:21)
    at _err0 (eval at create (/home/my-app//node_modules/tapable/lib/HookCodeFactory.js:33:10), <anonymous>:9:1)
    at _addModuleChain (/home/my-app//node_modules/webpack/lib/Compilation.js:1083:13)
    at processModuleDependencies.err (/home/my-app//node_modules/webpack/lib/Compilation.js:1006:25)
    at asyncLib.forEach.err (/home/my-app//node_modules/webpack/lib/Compilation.js:920:13)
    at /home/my-app//node_modules/neo-async/async.js:2825:7
Error: Cannot find module 'core-js/modules/es6.function.name'
    at Function.Module._resolveFilename (internal/modules/cjs/loader.js:571:15)
    at Function.Module._load (internal/modules/cjs/loader.js:497:25)
    at Module.require (internal/modules/cjs/loader.js:626:17)
    at require (internal/modules/cjs/helpers.js:20:18)
    at Object.<anonymous> (/home/eric-burel/Development_2018/vos-talents-dexperts/node_modules/extract-files/lib/index.js:7:1)
    at Module._compile (internal/modules/cjs/loader.js:678:30)
    at Object.Module._extensions..js (internal/modules/cjs/loader.js:689:10)
    at Module.load (internal/modules/cjs/loader.js:589:32)
    at tryModuleLoad (internal/modules/cjs/loader.js:528:12)
    at Function.Module._load (internal/modules/cjs/loader.js:520:3)

In particular the core-js error appears after I install the storybook packages. @larix/zen itself, apollo-upload-client and extract-files updates seems ok

larixer commented 5 years ago

@eric-burel webDll-webpack error ModuleNotFoundError: Module not found: Error: Can't resolve 'child_process' in '/home/my-app//packages/client/node_modules/cross-spawn' this message means some node module which uses child_process is included into web bundle. You shoulld not have node dependencies in your packages/client/package.json->dependencies

eric-burel commented 5 years ago

Hi here are reproduction steps:

Steps:

# On a fresh install
yarn -W add @larix/zen@0.1.22 # OK
cd packages/client

# OK
yarn add apollo-upload-client@10.0.0 extract-files@5.0.0 # still OK
yarn add babel-loader@8.0.6 # still OK

# First error with cross-env
yarn add cross-env@5.1.3 # KO child_process error on yarn watch
# Errors with storybook
yarn add @storybook/react@5.1.3 # KO Error: Cannot find module 'core-js/modules/es6.function.name

Minimal repro: https://github.com/lbke/apollo-universal-starter-kit/tree/storybook-stable

I understand that those are dependencies issues but the problem is that they come from the underlying packages (eg packages that don't provide a built version, server-side only etc...). Is that doable to have dependencies like storybook ignored?

The problem here is that indeed we are mixing 2 applications, a pure client side app and a client/server application Storybook. It seems that the build is based on all dependencies but does not necessarily detect unused ones (from the web app point of view, so Storybook related dependencies) that should be ignored.

larixer commented 5 years ago

Why do you add cross-env into dependencies of packages/client, it should be in devDependencies instead

eric-burel commented 5 years ago

Hmmm ok I added them as dependencies instead of devDependencies... not used to yarn. I'll try tomorrow I hope it was just that.

larixer commented 5 years ago

@larix/zen tries to put everything in packages/client/package.json->dependencies into web DLL to speed up webpack compilation and when some node module is in there the compilation breaks.

eric-burel commented 5 years ago

Ok got it eventually. What seems to happen is that if I "yarn add" the package in packages/client with a new version, it will add the latest version. But if I run yarn at the root of the project, it will respect the lock and install the old version.

So from the beginning I thought apollo-upload-client and extract-files were up to date, but they were not. Running yarn upgrade apollo-update-client and the same for extract-files at the root fixed it.

Now it works as expected. Thanks for the support, Storybook is a huge improvement for our productivity.