From 97f854ff90ac83b5b6bac903c3c2c2e1b48251cc Mon Sep 17 00:00:00 2001 From: Muhammed Thanish Date: Tue, 26 Jul 2016 14:34:22 +0530 Subject: [PATCH] Support requireing from node Wrap calls to browser only features to allow storybook module to be required from node. This can be used to build CLI tools. --- dist/client/preview/client_api.js | 10 ++++++++-- dist/client/preview/config_api.js | 7 ++++++- dist/client/preview/index.js | 25 ++++++++++++++++++------- dist/client/preview/render.js | 9 ++++++++- src/client/preview/client_api.js | 10 ++++++++-- src/client/preview/config_api.js | 7 ++++++- src/client/preview/index.js | 21 ++++++++++++++------- src/client/preview/render.js | 9 ++++++++- 8 files changed, 76 insertions(+), 22 deletions(-) diff --git a/dist/client/preview/client_api.js b/dist/client/preview/client_api.js index 03cd26ae651e..f537df62f337 100644 --- a/dist/client/preview/client_api.js +++ b/dist/client/preview/client_api.js @@ -36,6 +36,7 @@ var ClientApi = function () { var storyStore = _ref.storyStore; (0, _classCallCheck3.default)(this, ClientApi); + // pageBus can be null this._pageBus = pageBus; this._storyStore = storyStore; this._addons = {}; @@ -139,7 +140,9 @@ var ClientApi = function () { var id = _uuid2.default.v4(); var data = { name: name, args: args }; - pageBus.emit('addAction', { action: { data: data, id: id } }); + if (pageBus) { + pageBus.emit('addAction', { action: { data: data, id: id } }); + } }; } }, { @@ -150,8 +153,11 @@ var ClientApi = function () { return function linkTo() { var resolvedKind = typeof kind === 'function' ? kind.apply(undefined, arguments) : kind; var resolvedStory = typeof story === 'function' ? story.apply(undefined, arguments) : story; + var selection = { kind: resolvedKind, story: resolvedStory }; - pageBus.emit('selectStory', { kind: resolvedKind, story: resolvedStory }); + if (pageBus) { + pageBus.emit('selectStory', selection); + } }; } }]); diff --git a/dist/client/preview/config_api.js b/dist/client/preview/config_api.js index 64b04680da89..994ff89388d1 100644 --- a/dist/client/preview/config_api.js +++ b/dist/client/preview/config_api.js @@ -25,6 +25,7 @@ var ConfigApi = function () { var reduxStore = _ref.reduxStore; (0, _classCallCheck3.default)(this, ConfigApi); + // pageBus can be null this._pageBus = pageBus; this._storyStore = storyStore; this._reduxStore = reduxStore; @@ -74,7 +75,11 @@ var ConfigApi = function () { }); } - render(); + if (this._pageBus) { + render(); + } else { + loaders(); + } } }]); return ConfigApi; diff --git a/dist/client/preview/index.js b/dist/client/preview/index.js index a7667fb7b263..2739e47d2dff 100644 --- a/dist/client/preview/index.js +++ b/dist/client/preview/index.js @@ -5,6 +5,10 @@ Object.defineProperty(exports, "__esModule", { }); exports.configure = exports.clearDecorators = exports.addDecorator = exports.setAddon = exports.linkTo = exports.action = exports.storiesOf = undefined; +var _assign = require('babel-runtime/core-js/object/assign'); + +var _assign2 = _interopRequireDefault(_assign); + require('es6-shim'); var _story_store = require('./story_store'); @@ -43,19 +47,24 @@ var _reducer2 = _interopRequireDefault(_reducer); function _interopRequireDefault(obj) { return obj && obj.__esModule ? obj : { default: obj }; } -var queryParams = _qs2.default.parse(window.location.search.substring(1)); +// check whether we're running on node/browser +var isBrowser = typeof window !== 'undefined'; var storyStore = new _story_store2.default(); var reduxStore = (0, _redux.createStore)(_reducer2.default); -var pageBus = new _page_bus2.default(queryParams.dataId, reduxStore); -pageBus.init(); +var context = { storyStore: storyStore, reduxStore: reduxStore }; + +if (isBrowser) { + var queryParams = _qs2.default.parse(window.location.search.substring(1)); + var pageBus = new _page_bus2.default(queryParams.dataId, reduxStore); + (0, _assign2.default)(context, { pageBus: pageBus, window: window, queryParams: queryParams }); + pageBus.init(); + (0, _init2.default)(context); +} -var context = { storyStore: storyStore, reduxStore: reduxStore, pageBus: pageBus, window: window, queryParams: queryParams }; var clientApi = new _client_api2.default(context); var configApi = new _config_api2.default(context); -(0, _init2.default)(context); - // do exports var storiesOf = exports.storiesOf = clientApi.storiesOf.bind(clientApi); var action = exports.action = clientApi.action.bind(clientApi); @@ -67,7 +76,9 @@ var configure = exports.configure = configApi.configure.bind(configApi); // initialize the UI var renderUI = function renderUI() { - (0, _render2.default)(context); + if (isBrowser) { + (0, _render2.default)(context); + } }; reduxStore.subscribe(renderUI); \ No newline at end of file diff --git a/dist/client/preview/render.js b/dist/client/preview/render.js index d7a4ef725cdf..02ad5f1d0c76 100644 --- a/dist/client/preview/render.js +++ b/dist/client/preview/render.js @@ -23,10 +23,17 @@ var _error_display2 = _interopRequireDefault(_error_display); function _interopRequireDefault(obj) { return obj && obj.__esModule ? obj : { default: obj }; } -var rootEl = document.getElementById('root'); +// check whether we're running on node/browser +var isBrowser = typeof window !== 'undefined'; + +var rootEl = null; var previousKind = ''; var previousStory = ''; +if (isBrowser) { + rootEl = document.getElementById('root'); +} + function renderError(error) { // We always need to render redbox in the mainPage if we get an error. // Since this is an error, this affects to the main page as well. diff --git a/src/client/preview/client_api.js b/src/client/preview/client_api.js index fd4b42171198..095b909555e0 100644 --- a/src/client/preview/client_api.js +++ b/src/client/preview/client_api.js @@ -2,6 +2,7 @@ import UUID from 'uuid'; export default class ClientApi { constructor({ pageBus, storyStore }) { + // pageBus can be null this._pageBus = pageBus; this._storyStore = storyStore; this._addons = {}; @@ -93,7 +94,9 @@ export default class ClientApi { const id = UUID.v4(); const data = { name, args }; - pageBus.emit('addAction', { action: { data, id } }); + if (pageBus) { + pageBus.emit('addAction', { action: { data, id } }); + } }; } @@ -103,8 +106,11 @@ export default class ClientApi { return function linkTo(...args) { const resolvedKind = typeof kind === 'function' ? kind(...args) : kind; const resolvedStory = typeof story === 'function' ? story(...args) : story; + const selection = { kind: resolvedKind, story: resolvedStory }; - pageBus.emit('selectStory', { kind: resolvedKind, story: resolvedStory }); + if (pageBus) { + pageBus.emit('selectStory', selection); + } }; } } diff --git a/src/client/preview/config_api.js b/src/client/preview/config_api.js index 2cdf7595f0bf..05b3f3497a93 100644 --- a/src/client/preview/config_api.js +++ b/src/client/preview/config_api.js @@ -8,6 +8,7 @@ import { clearDecorators } from './'; export default class ConfigApi { constructor({ pageBus, storyStore, reduxStore }) { + // pageBus can be null this._pageBus = pageBus; this._storyStore = storyStore; this._reduxStore = reduxStore; @@ -49,6 +50,10 @@ export default class ConfigApi { }); } - render(); + if (this._pageBus) { + render(); + } else { + loaders(); + } } } diff --git a/src/client/preview/index.js b/src/client/preview/index.js index 9f4706f6b559..b07c9b536b31 100644 --- a/src/client/preview/index.js +++ b/src/client/preview/index.js @@ -10,19 +10,24 @@ import init from './init'; import { createStore } from 'redux'; import reducer from './reducer'; -const queryParams = qs.parse(window.location.search.substring(1)); +// check whether we're running on node/browser +const isBrowser = typeof window !== 'undefined'; const storyStore = new StoryStore(); const reduxStore = createStore(reducer); -const pageBus = new PageBus(queryParams.dataId, reduxStore); -pageBus.init(); +const context = { storyStore, reduxStore }; + +if (isBrowser) { + const queryParams = qs.parse(window.location.search.substring(1)); + const pageBus = new PageBus(queryParams.dataId, reduxStore); + Object.assign(context, { pageBus, window, queryParams }); + pageBus.init(); + init(context); +} -const context = { storyStore, reduxStore, pageBus, window, queryParams }; const clientApi = new ClientApi(context); const configApi = new ConfigApi(context); -init(context); - // do exports export const storiesOf = clientApi.storiesOf.bind(clientApi); export const action = clientApi.action.bind(clientApi); @@ -34,7 +39,9 @@ export const configure = configApi.configure.bind(configApi); // initialize the UI const renderUI = () => { - render(context); + if (isBrowser) { + render(context); + } }; reduxStore.subscribe(renderUI); diff --git a/src/client/preview/render.js b/src/client/preview/render.js index 5ecec3ea0b14..bf1dbc1b61d6 100644 --- a/src/client/preview/render.js +++ b/src/client/preview/render.js @@ -3,10 +3,17 @@ import React from 'react'; import ReactDOM from 'react-dom'; import ErrorDisplay from './error_display'; -const rootEl = document.getElementById('root'); +// check whether we're running on node/browser +const isBrowser = typeof window !== 'undefined'; + +let rootEl = null; let previousKind = ''; let previousStory = ''; +if (isBrowser) { + rootEl = document.getElementById('root'); +} + export function renderError(error) { // We always need to render redbox in the mainPage if we get an error. // Since this is an error, this affects to the main page as well.