-
Notifications
You must be signed in to change notification settings - Fork 106
Commit
This commit does not belong to any branch on this repository, and may belong to a fork outside of the repository.
Support
features.storyStoreV7
(#126)
Closes #125
- Loading branch information
1 parent
98c28a4
commit 496312e
Showing
12 changed files
with
764 additions
and
407 deletions.
There are no files selected for viewing
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
46 changes: 46 additions & 0 deletions
46
packages/storybook-builder-vite/codegen-importfn-script.js
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,46 @@ | ||
const glob = require('glob-promise'); | ||
const path = require('path'); | ||
const { normalizePath } = require('vite'); | ||
|
||
/** | ||
* This file is largely based on https://github.com/storybookjs/storybook/blob/d1195cbd0c61687f1720fefdb772e2f490a46584/lib/core-common/src/utils/to-importFn.ts | ||
*/ | ||
|
||
/** | ||
* This function takes an array of stories and creates a mapping between the stories' relative paths | ||
* to the working directory and their dynamic imports. The import is done in an asynchronous function | ||
* to delay loading. It then creates a function, `importFn(path)`, which resolves a path to an import | ||
* function and this is called by Storybook to fetch a story dynamically when needed. | ||
* @param stories An array of absolute story paths. | ||
* @returns {Promise<string>} | ||
*/ | ||
async function toImportFn(stories) { | ||
const objectEntries = stories | ||
.map(file => ` './${normalizePath(path.relative(process.cwd(),file))}': async () => import('/@fs/${file}')`); | ||
return ` | ||
const importers = { | ||
${objectEntries.join(',\n')} | ||
}; | ||
export async function importFn(path) { | ||
return importers[path](); | ||
} | ||
`; | ||
} | ||
|
||
module.exports.generateImportFnScriptCode = | ||
async function generateImportFnScriptCode(options) { | ||
// First we need to get an array of stories and their absolute paths. | ||
const stories = ( | ||
await Promise.all( | ||
( | ||
await options.presets.apply('stories', [], options) | ||
).map((storyEntry) => | ||
glob(path.isAbsolute(storyEntry) ? storyEntry : path.join(options.configDir, storyEntry)) | ||
) | ||
) | ||
).reduce((carry, stories) => carry.concat(stories), []); | ||
|
||
// We can then call toImportFn to create a function that can be used to load each story dynamically. | ||
return (await toImportFn(stories)).trim(); | ||
}; |
70 changes: 70 additions & 0 deletions
70
packages/storybook-builder-vite/codegen-modern-iframe-script.js
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,70 @@ | ||
const { loadPreviewOrConfigFile } = require('@storybook/core-common'); | ||
const { normalizePath } = require('vite'); | ||
|
||
module.exports.generateModernIframeScriptCode = | ||
async function generateModernIframeScriptCode(options, { storiesFilename }) { | ||
const { presets, configDir } = options; | ||
|
||
const previewOrConfigFile = loadPreviewOrConfigFile({ configDir }); | ||
const presetEntries = await presets.apply('config', [], options); | ||
const configEntries = [...presetEntries, previewOrConfigFile].filter( | ||
Boolean | ||
).map(configEntry => `/@fs/${normalizePath(configEntry)}`); | ||
|
||
/** | ||
* This code is largely taken from https://github.com/storybookjs/storybook/blob/d1195cbd0c61687f1720fefdb772e2f490a46584/lib/builder-webpack4/src/preview/virtualModuleModernEntry.js.handlebars | ||
* Some small tweaks were made to `getProjectAnnotations` (since `import()` needs to be resolved asynchronously) | ||
* and the HMR implementation has been tweaked to work with Vite. | ||
*/ | ||
const code = ` | ||
import fetch from 'unfetch'; | ||
import global from 'global'; | ||
import { composeConfigs, PreviewWeb } from '@storybook/preview-web'; | ||
import { ClientApi } from '@storybook/client-api'; | ||
import { addons } from '@storybook/addons'; | ||
import createPostMessageChannel from '@storybook/channel-postmessage'; | ||
import createWebSocketChannel from '@storybook/channel-websocket'; | ||
import { importFn } from '${storiesFilename}'; | ||
const { SERVER_CHANNEL_URL } = global; | ||
const getProjectAnnotations = async () => | ||
composeConfigs(await Promise.all([${configEntries.map(configEntry => `import('${configEntry}')`).join(',\n')}])); | ||
const channel = createPostMessageChannel({ page: 'preview' }); | ||
addons.setChannel(channel); | ||
if (SERVER_CHANNEL_URL) { | ||
const serverChannel = createWebSocketChannel({ url: SERVER_CHANNEL_URL, }); | ||
addons.setServerChannel(serverChannel); | ||
window.__STORYBOOK_SERVER_CHANNEL__ = serverChannel; | ||
} | ||
const preview = new PreviewWeb(); | ||
window.__STORYBOOK_PREVIEW__ = preview; | ||
window.__STORYBOOK_STORY_STORE__ = preview.storyStore; | ||
window.__STORYBOOK_ADDONS_CHANNEL__ = channel; | ||
window.__STORYBOOK_CLIENT_API__ = new ClientApi({ storyStore: preview.storyStore }); | ||
preview.initialize({ importFn, getProjectAnnotations }); | ||
if (import.meta.hot) { | ||
import.meta.hot.accept('${storiesFilename}', (newModule) => { | ||
// importFn has changed so we need to patch the new one in | ||
preview.onStoriesChanged({ importFn: newModule.importFn }); | ||
}); | ||
import.meta.hot.accept(${JSON.stringify(configEntries)}, ([...newConfigEntries]) => { | ||
const newGetProjectAnnotations = () => composeConfigs(newConfigEntries); | ||
// getProjectAnnotations has changed so we need to patch the new one in | ||
preview.onGetProjectAnnotationsChanged({ getProjectAnnotations: newGetProjectAnnotations }); | ||
}); | ||
} | ||
`.trim(); | ||
return code; | ||
}; |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -1,20 +1,24 @@ | ||
module.exports.transformIframeHtml = async function transformIframeHtml( | ||
html, | ||
{ title, framework, presets } | ||
{ configType, features, framework, presets, serverChannelUrl, title } | ||
) { | ||
const headHtmlSnippet = await presets.apply('previewHead'); | ||
const bodyHtmlSnippet = await presets.apply('previewBody'); | ||
const logLevel = await presets.apply('logLevel', undefined); | ||
const frameworkOptions = await presets.apply(`${framework}Options`, {}); | ||
const features = await presets.apply('features', {}); | ||
const coreOptions = await presets.apply('core'); | ||
|
||
return html | ||
.replace('<!-- [TITLE HERE] -->', title || 'Storybook') | ||
.replace('[CONFIG_TYPE HERE]', configType) | ||
.replace('[LOGLEVEL HERE]', logLevel) | ||
.replace( | ||
`'[FRAMEWORK_OPTIONS HERE]'`, | ||
JSON.stringify(frameworkOptions || {}) | ||
) | ||
.replace(`'[CHANNEL_OPTIONS HERE]'`, JSON.stringify(coreOptions && coreOptions.channelOptions ? coreOptions.channelOptions : {})) | ||
.replace(`'[FEATURES HERE]'`, JSON.stringify(features || {})) | ||
.replace(`'[SERVER_CHANNEL_URL HERE]'`, JSON.stringify(serverChannelUrl)) | ||
.replace('<!-- [HEAD HTML SNIPPET HERE] -->', headHtmlSnippet || '') | ||
.replace('<!-- [BODY HTML SNIPPET HERE] -->', bodyHtmlSnippet || ''); | ||
}; |
Oops, something went wrong.