Skip to content

Commit

Permalink
Add support for multiple webpack chunks in iframe
Browse files Browse the repository at this point in the history
This allows an arbitrary number of files to be loaded into the iframe,
not just the single `preview.bundle.js` file.

Webpack plugins can output chunks in a separate file. In dev, since
file names are predictable, I can add the js file into a head.html file.
When building storybook statically, however, js files have a hash added
to them, so this doesn't work.

This change makes the static build parse all webpack chunks and load
them in the iframe (excluding the manager script), instead of only
including known files.
  • Loading branch information
apexskier authored and ndelangen committed May 21, 2017
1 parent 037ce6a commit 38b9dfa
Showing 1 changed file with 30 additions and 17 deletions.
47 changes: 30 additions & 17 deletions app/react/src/server/iframe.html.js
Original file line number Diff line number Diff line change
Expand Up @@ -11,31 +11,44 @@ import url from 'url';
const previewUrlsFromAssets = assets => {
if (!assets) {
return {
js: 'static/preview.bundle.js',
js: ['static/preview.bundle.js'],
css: [],
};
}

if (typeof assets.preview === 'string') {
return {
js: assets.preview,
};
}

return {
js: assets.preview.find(filename => filename.match(/\.js$/)),
css: assets.preview.find(filename => filename.match(/\.css$/)),
const urls = {
js: [],
css: [],
};

const re = /.+\.(\w+)$/;
Object.keys(assets)
// Don't load the manager script in the iframe
.filter(key => key !== 'manager')
.forEach(key => {
const asset = assets[key];
if (typeof asset === 'string') {
urls[re.exec(asset)[1]].push(asset);
} else {
const assetUrl = asset.find(u => re.exec(u)[1] !== 'map');
urls[re.exec(assetUrl)[1]].push(assetUrl);
}
});

return urls;
};

export default function(data) {
const { assets, headHtml, publicPath } = data;

const previewUrls = previewUrlsFromAssets(assets);
const urls = urlsFromAssets(assets);

let previewCssTag = '';
if (previewUrls.css) {
previewCssTag = `<link rel='stylesheet' type='text/css' href='${url.resolve(publicPath, previewUrls.css)}'>`;
}
const cssTags = urls.css
.map(u => `<link rel='stylesheet' type='text/css' href='${url.resolve(publicPath, u)}'>`)
.join('\n');
const scriptTags = urls.js
.map(u => `<script src="${url.resolve(publicPath, u)}"></script>`)
.join('\n');

return `
<!DOCTYPE html>
Expand All @@ -50,12 +63,12 @@ export default function(data) {
</script>
<title>Storybook</title>
${headHtml}
${previewCssTag}
${cssTags}
</head>
<body>
<div id="root"></div>
<div id="error-display"></div>
<script src="${url.resolve(publicPath, previewUrls.js)}"></script>
${scriptTags}
</body>
</html>
`;
Expand Down

0 comments on commit 38b9dfa

Please sign in to comment.