Skip to content

Commit

Permalink
Merge pull request #1775 from thomasbertet/fix-ordering-chunk-load
Browse files Browse the repository at this point in the history
Use HtmlWebpackPlugin to import all assets (importing chunks in order)
  • Loading branch information
ndelangen authored Sep 6, 2017
2 parents db01fac + 99e9ab3 commit 40c652d
Show file tree
Hide file tree
Showing 55 changed files with 733 additions and 883 deletions.
2 changes: 1 addition & 1 deletion addons/links/README.md
Original file line number Diff line number Diff line change
Expand Up @@ -43,7 +43,7 @@ linkTo('Toggle') // Links to the first story in the 'Toggle' kind
With that, you can link an event in a component to any story in the Storybook.

- First parameter is the the story kind name (what you named with `storiesOf`).
-   Second (optional) parameter is the story name (what you named with `.add`). If the second parameter is omitted, the link will point to the first story in the given kind.
-   Second (optional) parameter is the story name (what you named with `.add`). If the second parameter is omitted, the link will point to the first story in the given kind.

> You can also pass a function instead for any of above parameter. That function accepts arguments emitted by the event and it should return a string. <br/>
> Have a look at [PR86](https://github.com/kadirahq/react-storybook/pull/86) for more information.
1 change: 1 addition & 0 deletions app/react-native/package.json
Original file line number Diff line number Diff line change
Expand Up @@ -53,6 +53,7 @@
"file-loader": "^0.11.1",
"find-cache-dir": "^1.0.0",
"global": "^4.3.2",
"html-webpack-plugin": "^2.30.1",
"json-loader": "^0.5.4",
"json5": "^0.5.1",
"postcss-loader": "^2.0.5",
Expand Down
8 changes: 5 additions & 3 deletions app/react-native/src/preview/index.js
Original file line number Diff line number Diff line change
Expand Up @@ -91,9 +91,11 @@ export default class Preview {
this._sendGetCurrentStory();

// finally return the preview component
return params.onDeviceUI
? <OnDeviceUI stories={this._stories} events={this._events} url={webUrl} />
: <StoryView url={webUrl} events={this._events} />;
return params.onDeviceUI ? (
<OnDeviceUI stories={this._stories} events={this._events} url={webUrl} />
) : (
<StoryView url={webUrl} events={this._events} />
);
};
}

Expand Down
14 changes: 11 additions & 3 deletions app/react-native/src/server/config/webpack.config.js
Original file line number Diff line number Diff line change
@@ -1,9 +1,10 @@
import path from 'path';
import webpack from 'webpack';
import CaseSensitivePathsPlugin from 'case-sensitive-paths-webpack-plugin';
import HtmlWebpackPlugin from 'html-webpack-plugin';
import { OccurenceOrderPlugin, includePaths, excludePaths } from './utils';

const config = {
const getConfig = options => ({
devtool: '#cheap-module-eval-source-map',
entry: {
manager: [require.resolve('../../manager')],
Expand All @@ -14,6 +15,13 @@ const config = {
publicPath: '/',
},
plugins: [
new HtmlWebpackPlugin({
filename: 'index.html',
data: {
options: JSON.stringify(options),
},
template: require.resolve('../index.html.ejs'),
}),
new OccurenceOrderPlugin(),
new webpack.HotModuleReplacementPlugin(),
new CaseSensitivePathsPlugin(),
Expand All @@ -29,6 +37,6 @@ const config = {
},
],
},
};
});

export default config;
export default getConfig;
112 changes: 62 additions & 50 deletions app/react-native/src/server/config/webpack.config.prod.js
Original file line number Diff line number Diff line change
@@ -1,57 +1,69 @@
import path from 'path';
import webpack from 'webpack';
import HtmlWebpackPlugin from 'html-webpack-plugin';
import { OccurenceOrderPlugin, includePaths, excludePaths } from './utils';

const config = {
bail: true,
devtool: '#cheap-module-source-map',
entry: {
manager: [path.resolve(__dirname, '../../manager')],
},
output: {
path: path.join(__dirname, 'dist'),
filename: 'static/[name].bundle.js',
// Here we set the publicPath to ''.
// This allows us to deploy storybook into subpaths like GitHub pages.
// This works with css and image loaders too.
// This is working for storybook since, we don't use pushState urls and
// relative URLs works always.
publicPath: '/',
},
plugins: [
new webpack.DefinePlugin({ 'process.env.NODE_ENV': '"production"' }),
new webpack.optimize.DedupePlugin(),
new webpack.optimize.UglifyJsPlugin({
compress: {
screw_ie8: true,
warnings: false,
},
mangle: {
screw_ie8: true,
},
output: {
comments: false,
screw_ie8: true,
},
}),
],
module: {
loaders: [
{
test: /\.jsx?$/,
loader: require.resolve('babel-loader'),
query: require('./babel.prod.js'), // eslint-disable-line
include: includePaths,
exclude: excludePaths,
},
const getConfig = options => {
const config = {
bail: true,
devtool: '#cheap-module-source-map',
entry: {
manager: [path.resolve(__dirname, '../../manager')],
},
output: {
path: path.join(__dirname, 'dist'),
filename: 'static/[name].bundle.js',
// Here we set the publicPath to ''.
// This allows us to deploy storybook into subpaths like GitHub pages.
// This works with css and image loaders too.
// This is working for storybook since, we don't use pushState urls and
// relative URLs works always.
publicPath: '/',
},
plugins: [
new HtmlWebpackPlugin({
filename: 'index.html',
data: {
options: JSON.stringify(options),
},
template: require.resolve('../index.html.ejs'),
}),
new webpack.DefinePlugin({ 'process.env.NODE_ENV': '"production"' }),
new webpack.optimize.DedupePlugin(),
new webpack.optimize.UglifyJsPlugin({
compress: {
screw_ie8: true,
warnings: false,
},
mangle: {
screw_ie8: true,
},
output: {
comments: false,
screw_ie8: true,
},
}),
],
},
};
module: {
loaders: [
{
test: /\.jsx?$/,
loader: require.resolve('babel-loader'),
query: require('./babel.prod.js'), // eslint-disable-line
include: includePaths,
exclude: excludePaths,
},
],
},
};

// Webpack 2 doesn't have a OccurenceOrderPlugin plugin in the production mode.
// But webpack 1 has it. That's why we do this.
if (OccurenceOrderPlugin) {
config.plugins.unshift(new OccurenceOrderPlugin());
}
// Webpack 2 doesn't have a OccurenceOrderPlugin plugin in the production mode.
// But webpack 1 has it. That's why we do this.
if (OccurenceOrderPlugin) {
config.plugins.unshift(new OccurenceOrderPlugin());
}

return config;
};

export default config;
export default getConfig;
34 changes: 34 additions & 0 deletions app/react-native/src/server/index.html.ejs
Original file line number Diff line number Diff line change
@@ -0,0 +1,34 @@
<!DOCTYPE html>
<html>
<head>
<meta charset="utf-8">
<meta name="viewport" content="width=device-width, initial-scale=1">
<title>Storybook for React</title>
<style>
/* Styling the fuzzy search box placeholders */
.searchBox::-webkit-input-placeholder { /* Chrome/Opera/Safari */
color: #ddd;
font-size: 16px;
}
.searchBox::-moz-placeholder { /* Firefox 19+ */
color: #ddd;
font-size: 16px;
}
.searchBox:focus{
border-color: #EEE !important;
}
.btn:hover{
background-color: #eee
}
</style>
</head>
<body style="margin: 0;">
<div id="root"></div>
<script>
window.storybookOptions = <%= htmlWebpackPlugin.options.data.options %>;
</script>
</body>
</html>
41 changes: 0 additions & 41 deletions app/react-native/src/server/index.html.js

This file was deleted.

11 changes: 3 additions & 8 deletions app/react-native/src/server/middleware.js
Original file line number Diff line number Diff line change
Expand Up @@ -7,7 +7,6 @@ import webpackHotMiddleware from 'webpack-hot-middleware';
import baseConfig from './config/webpack.config';
import baseProductionConfig from './config/webpack.config.prod';
import loadConfig from './config';
import getIndexHtml from './index.html';

function getMiddleware(configDir) {
const middlewarePath = path.resolve(configDir, 'middleware.js');
Expand All @@ -26,7 +25,7 @@ export default function({ projectDir, configDir, ...options }) {
// custom `.babelrc` file and `webpack.config.js` files
const environment = options.environment || 'DEVELOPMENT';
const isProd = environment === 'PRODUCTION';
const currentWebpackConfig = isProd ? baseProductionConfig : baseConfig;
const currentWebpackConfig = isProd ? baseProductionConfig(options) : baseConfig(options);
const config = loadConfig(environment, currentWebpackConfig, projectDir, configDir);

// remove the leading '/'
Expand All @@ -53,12 +52,8 @@ export default function({ projectDir, configDir, ...options }) {
}

router.get('/', (req, res) => {
res.send(
getIndexHtml(publicPath, {
manualId: options.manualId,
secured: options.secured,
})
);
res.set('Content-Type', 'text/html');
res.sendFile(path.join(`${__dirname}/public/index.html`));
});

return router;
Expand Down
1 change: 1 addition & 0 deletions app/react/package.json
Original file line number Diff line number Diff line change
Expand Up @@ -50,6 +50,7 @@
"glamor": "^2.20.40",
"glamorous": "^4.1.2",
"global": "^4.3.2",
"html-webpack-plugin": "^2.30.1",
"json-loader": "^0.5.4",
"json-stringify-safe": "^5.0.1",
"json5": "^0.5.1",
Expand Down
5 changes: 4 additions & 1 deletion app/react/src/client/preview/client_api.test.js
Original file line number Diff line number Diff line change
Expand Up @@ -80,7 +80,10 @@ describe('preview.client_api', () => {
},
});

api.storiesOf('none', module).aa().bb();
api
.storiesOf('none', module)
.aa()
.bb();
expect(data).toEqual(['foo', 'bar']);
});

Expand Down
19 changes: 1 addition & 18 deletions app/react/src/server/build.js
Original file line number Diff line number Diff line change
Expand Up @@ -9,9 +9,7 @@ import shelljs from 'shelljs';
import packageJson from '../../package.json';
import getBaseConfig from './config/webpack.config.prod';
import loadConfig from './config';
import getIndexHtml from './index.html';
import getIframeHtml from './iframe.html';
import { getPreviewHeadHtml, getManagerHeadHtml, parseList, getEnvConfig } from './utils';
import { parseList, getEnvConfig } from './utils';

process.env.NODE_ENV = process.env.NODE_ENV || 'production';

Expand Down Expand Up @@ -86,19 +84,4 @@ webpack(config).run((err, stats) => {
stats.hasErrors() && stats.toJson().errors.forEach(e => logger.error(e));
process.exit(1);
}

const data = {
publicPath: config.output.publicPath,
assets: stats.toJson().assetsByChunkName,
};

// Write both the storybook UI and IFRAME HTML files to destination path.
fs.writeFileSync(
path.resolve(outputDir, 'index.html'),
getIndexHtml({ ...data, headHtml: getManagerHeadHtml(configDir) })
);
fs.writeFileSync(
path.resolve(outputDir, 'iframe.html'),
getIframeHtml({ ...data, headHtml: getPreviewHeadHtml(configDir) })
);
});
10 changes: 7 additions & 3 deletions app/react/src/server/config/utils.js
Original file line number Diff line number Diff line change
Expand Up @@ -23,11 +23,15 @@ export function loadEnv(options = {}) {
PUBLIC_URL: JSON.stringify(options.production ? '.' : ''),
};

Object.keys(process.env).filter(name => /^STORYBOOK_/.test(name)).forEach(name => {
env[name] = JSON.stringify(process.env[name]);
});
Object.keys(process.env)
.filter(name => /^STORYBOOK_/.test(name))
.forEach(name => {
env[name] = JSON.stringify(process.env[name]);
});

return {
'process.env': env,
};
}

export const getConfigDir = () => process.env.SBCONFIG_CONFIG_DIR || './.storybook';
Loading

0 comments on commit 40c652d

Please sign in to comment.