Skip to content

Navigation Menu

Sign in
Appearance settings

Search code, repositories, users, issues, pull requests...

Provide feedback

We read every piece of feedback, and take your input very seriously.

Saved searches

Use saved searches to filter your results more quickly

Sign up
Appearance settings

Commit 4fd4bdc

Browse files
committed
feat: allow dynamic imports to be enabled/disabled
1 parent 67399dc commit 4fd4bdc

File tree

9 files changed

+123
-77
lines changed

9 files changed

+123
-77
lines changed

‎config/index.js

Lines changed: 3 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -1,6 +1,9 @@
11
const { mapValues, keyBy } = require('lodash');
22

33
module.exports = {
4+
// Enable or disable dynamic imports (code splitting)
5+
enableDynamicImports: false,
6+
47
// The env vars to expose on the client side. If you add them here, they will
58
// be available on the client as process.env[VAR_NAME], same as they would be
69
// in node.js.

‎server/index.js

Lines changed: 29 additions & 25 deletions
Original file line numberDiff line numberDiff line change
@@ -75,38 +75,42 @@ const startServer = () => {
7575
if (!module.parent) {
7676
let server;
7777

78-
// Ensure react-loadable stats file exists before starting the server
79-
const statsPath = path.join(__dirname, '..', 'react-loadable.json');
80-
const watcher = chokidar.watch(statsPath, { persistent: true });
78+
if (!config.enableDynamicImports) {
79+
startServer();
80+
} else {
81+
// Ensure react-loadable stats file exists before starting the server
82+
const statsPath = path.join(__dirname, '..', 'react-loadable.json');
83+
const watcher = chokidar.watch(statsPath, { persistent: true });
8184

82-
console.info(`Checking/waiting for ${statsPath}...`);
85+
console.info(`Checking/waiting for ${statsPath}...`);
8386

84-
watcher.on('all', (event, path) => {
85-
if (event === 'add') {
86-
if (env === 'production') {
87-
watcher.close();
88-
}
87+
watcher.on('all', (event, path) => {
88+
if (event === 'add') {
89+
if (env === 'production') {
90+
watcher.close();
91+
}
8992

90-
console.info(`Stats file found at ${path}, starting server...`);
93+
console.info(`Stats file found at ${path}, starting server...`);
9194

92-
startServer().then(s => server = s);
95+
startServer().then(s => server = s);
9396

94-
} else if (event === 'change') {
95-
if (env === 'production') {
96-
watcher.close();
97-
}
97+
} else if (event === 'change') {
98+
if (env === 'production') {
99+
watcher.close();
100+
}
98101

99-
console.info('Stats file changed, restarting server...');
102+
console.info('Stats file changed, restarting server...');
100103

101-
if (server) {
102-
// if the server is already started, restart it.
103-
server.close(() => {
104+
if (server) {
105+
// if the server is already started, restart it.
106+
server.close(() => {
107+
startServer().then(s => server = s);
108+
});
109+
} else {
110+
// otherwise, just start the server.
104111
startServer().then(s => server = s);
105-
});
106-
} else {
107-
// otherwise, just start the server.
108-
startServer().then(s => server = s);
112+
}
109113
}
110-
}
111-
});
114+
});
115+
}
112116
}

‎server/renderer/render.js

Lines changed: 13 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -13,12 +13,22 @@ export default function render(html, initialState = {}, bundles = []) {
1313

1414
const assets = global.ISOTools.assets();
1515
const appJs = assets.javascript.app;
16+
const vendorJs = assets.javascript.vendor;
1617
const helmet = Helmet.renderStatic();
1718
const appCss = assets.styles.app;
19+
const vendorCss = assets.styles.vendor;
1820
const chunkCss = bundles.filter(bundle => bundle.file.match(/.css/));
1921
const chunkJs = bundles.filter(bundle => bundle.file.match(/.js/));
2022

21-
return compile(
22-
{ html, helmet, appCss, appJs, chunkCss, chunkJs, initialState }
23-
);
23+
return compile({
24+
html,
25+
helmet,
26+
appCss,
27+
appJs,
28+
vendorJs,
29+
vendorCss,
30+
chunkCss,
31+
chunkJs,
32+
initialState
33+
});
2434
}

‎server/templates/layouts/application.html

Lines changed: 8 additions & 6 deletions
Original file line numberDiff line numberDiff line change
@@ -5,18 +5,20 @@
55
<meta charset="utf-8" />
66
<meta name="viewport" content="initial-scale=1, maximum-scale=1, user-scalable=no, width=device-width height=device-height" />
77
<link rel="shortcut icon" type="image/x-icon" href="/assets/favicon.png">
8+
<%= vendorCss ? `<link type="text/css" rel="stylesheet" href="${vendorCss}" />` : '' %>
89
<link type="text/css" rel="stylesheet" href="<%= appCss %>" />
9-
<%= chunkCss.map(bundle => {
10-
return ` <link type="text/css" rel="stylesheet" href="${process.env.PUBLIC_ASSET_PATH}${bundle.file}" />`
11-
}).join('\n') %>
10+
<%= chunkCss.map(bundle => {
11+
return `<link type="text/css" rel="stylesheet" href="${process.env.PUBLIC_ASSET_PATH}${bundle.file}" />`
12+
}).join('\n') %>
1213
</head>
1314
<body>
1415
<div id="app"><%= html %></div>
1516
<script>window.__INITIAL_STATE__ = <%= JSON.stringify(initialState) %>;</script>
17+
<%= vendorJs ? `<script src="${vendorJs}"></script>` : '' %>
1618
<script src="<%= appJs %>"></script>
17-
<%= chunkJs.map(bundle => {
18-
return ` <script src="${process.env.PUBLIC_ASSET_PATH}${bundle.file}"></script>`
19-
}).join('\n') %>
19+
<%= chunkJs.map(bundle => {
20+
return `<script src="${process.env.PUBLIC_ASSET_PATH}${bundle.file}"></script>`
21+
}).join('\n') %>
2022
<script>window.main();</script>
2123
</body>
2224
</html>

‎webpack/base.js

Lines changed: 21 additions & 13 deletions
Original file line numberDiff line numberDiff line change
@@ -11,25 +11,38 @@ import { BundleAnalyzerPlugin } from 'webpack-bundle-analyzer';
1111
import { ReactLoadablePlugin } from 'react-loadable/webpack';
1212
import config from '../config';
1313

14-
const ssr = yn(process.env.SSR) || false;
15-
const isoPlugin = new IsoPlugin(config.isomorphicConfig).development(isDev);
16-
const extractTextPlugin = new ExtractTextPlugin({
14+
let ssr = yn(process.env.SSR) || false;
15+
let isoPlugin = new IsoPlugin(config.isomorphicConfig).development(isDev);
16+
let extractTextPlugin = new ExtractTextPlugin({
1717
filename: isDev ? '[name].css' : '[name].[contenthash].css',
1818
allChunks: true,
1919
disable: ssr
2020
});
21-
const plugins = [
21+
22+
let plugins = [
2223
isoPlugin,
23-
new ReactLoadablePlugin({
24-
filename: path.join(__dirname, '..', 'react-loadable.json')
25-
}),
2624
extractTextPlugin,
2725
new webpack.ContextReplacementPlugin(/moment[/\\]locale$/, /en|es/),
2826
new webpack.DefinePlugin({
2927
'process.env': config.clientEnv
3028
})
3129
];
3230

31+
let output = {
32+
path: path.join(__dirname, '..', process.env.PUBLIC_OUTPUT_PATH),
33+
filename: '[name].bundle.js',
34+
publicPath: process.env.PUBLIC_ASSET_PATH || '/'
35+
};
36+
37+
// Enable dynamically imported code-splitting
38+
if (config.enableDynamicImports) {
39+
plugins.unshift(new ReactLoadablePlugin({
40+
filename: path.join(__dirname, '..', 'react-loadable.json')
41+
}));
42+
43+
output.chunkFilename = '[name].bundle.js';
44+
}
45+
3346
if (process.env.ANALYZE) {
3447
plugins.push(new BundleAnalyzerPlugin());
3548
}
@@ -39,12 +52,7 @@ export default {
3952
entry: {
4053
app: ['./client/index']
4154
},
42-
output: {
43-
path: path.join(__dirname, '..', process.env.PUBLIC_OUTPUT_PATH),
44-
filename: '[name].bundle.js',
45-
chunkFilename: '[name].bundle.js',
46-
publicPath: process.env.PUBLIC_ASSET_PATH || '/'
47-
},
55+
output,
4856
resolve: {
4957
extensions: ['.js', '.jsx', '.scss'],
5058
alias: mapValues(config.clientResolvePaths, str =>

‎webpack/development.hot.js

Lines changed: 21 additions & 9 deletions
Original file line numberDiff line numberDiff line change
@@ -2,6 +2,7 @@
22
import WebpackDevServer from 'webpack-dev-server';
33
import webpack from 'webpack';
44
import baseConfig from './base';
5+
import config from '../config';
56

67
const {
78
DEV_SERVER_PORT,
@@ -16,41 +17,52 @@ const entry = [
1617
];
1718

1819
// Additional plugins
19-
const plugins = [
20+
let plugins = [
2021
new webpack.HotModuleReplacementPlugin(),
2122
new webpack.NoEmitOnErrorsPlugin(),
2223
new webpack.NamedModulesPlugin()
2324
];
2425

26+
if (!config.enableDynamicImports) {
27+
plugins.push(new webpack.optimize.CommonsChunkPlugin({
28+
name: 'vendor',
29+
filename: '[name].js',
30+
minChunks: module => /node_modules/.test(module.resource)
31+
}));
32+
}
33+
2534
// Additional loaders
2635
const loaders = [];
2736

28-
const config = Object.assign({}, baseConfig, {
37+
const webpackConfig = {
38+
...baseConfig,
2939
devtool: 'eval',
30-
entry: Object.assign({}, baseConfig.entry, {
40+
entry: {
41+
...baseConfig.entry,
3142
app: [
3243
...entry,
3344
...baseConfig.entry.app
3445
]
35-
}),
46+
},
3647
plugins: [
3748
// don't use the first plugin (isomorphic plugin)
3849
...baseConfig.plugins,
3950
...plugins
4051
],
41-
module: Object.assign({}, baseConfig.module, {
52+
module: {
53+
...baseConfig.module,
4254
rules: [
4355
...baseConfig.module.rules,
4456
...loaders
4557
]
46-
})
47-
});
58+
}
59+
};
4860

4961
console.info('Firing up Webpack dev server...\n');
5062

51-
new WebpackDevServer(webpack(config), {
63+
new WebpackDevServer(webpack(webpackConfig), {
5264
port: DEV_SERVER_PORT,
53-
publicPath: config.output.publicPath,
65+
publicPath: webpackConfig.output.publicPath,
5466
hot: true,
5567
historyApiFallback: true,
5668
noInfo: false,

‎webpack/production.babel.js

Lines changed: 2 additions & 6 deletions
Original file line numberDiff line numberDiff line change
@@ -13,15 +13,11 @@ export default {
1313
...baseConfig,
1414
output: {
1515
...baseConfig.output,
16-
...{
17-
filename: '[name].[hash].js'
18-
}
16+
filename: '[name].[hash].js'
1917
},
2018
plugins,
2119
module: {
2220
...baseConfig.module,
23-
...{
24-
rules: [...baseConfig.module.rules, ...loaders]
25-
}
21+
rules: [...baseConfig.module.rules, ...loaders]
2622
}
2723
};

‎webpack/production.client.babel.js

Lines changed: 24 additions & 13 deletions
Original file line numberDiff line numberDiff line change
@@ -2,8 +2,10 @@ import webpack from 'webpack';
22
import baseConfig from './production.babel';
33
import CompressionPlugin from 'compression-webpack-plugin';
44
import UglifyJSPlugin from 'uglifyjs-webpack-plugin';
5+
import config from '../config';
56

6-
const plugins = [
7+
let plugins = [
8+
...baseConfig.plugins,
79
new webpack.BannerPlugin({
810
banner:
911
'hash:[hash], chunkhash:[chunkhash], name:[name], ' +
@@ -26,25 +28,34 @@ const plugins = [
2628
test: /\.css$|\.js$|\.html$/,
2729
threshold: 10240,
2830
minRatio: 0.8
31+
}),
32+
new webpack.optimize.CommonsChunkPlugin({
33+
name: 'vendor',
34+
filename: '[name].[hash].js',
35+
minChunks: module => /node_modules/.test(module.resource)
2936
})
3037
];
3138

32-
const loaders = [];
39+
let output = {
40+
...baseConfig.output,
41+
filename: '[name].[hash].js'
42+
};
43+
44+
let loaders = [];
45+
46+
if (config.enableDynamicImports) {
47+
// remove commons chunk plugin
48+
plugins = plugins.slice(0, plugins.length - 1);
49+
50+
output.chunkFilename = '[name].[hash].js';
51+
}
3352

3453
export default {
3554
...baseConfig,
36-
output: {
37-
...baseConfig.output,
38-
...{
39-
filename: '[name].[hash].js',
40-
chunkFilename: '[name].[hash].js',
41-
}
42-
},
43-
plugins: [...baseConfig.plugins, ...plugins],
55+
output,
56+
plugins,
4457
module: {
4558
...baseConfig.module,
46-
...{
47-
rules: [...baseConfig.module.rules, ...loaders]
48-
}
59+
rules: [...baseConfig.module.rules, ...loaders]
4960
}
5061
};

‎webpack/production.server.babel.js

Lines changed: 2 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -11,8 +11,8 @@ import { babel } from '../package.json';
1111
const babelOpts = set(babel, 'presets[0][1].targets.uglify', true);
1212

1313
const plugins = [
14-
// we don't need the isomorphic or react-loadable plugins here
15-
...baseConfig.plugins.slice(2),
14+
// we don't need the isomorphic and react-loadable plugins here
15+
...baseConfig.plugins.slice(config.enableDynamicImports ? 2 : 1),
1616
new UglifyJSPlugin({
1717
sourceMap: true
1818
}),

0 commit comments

Comments
(0)

AltStyle によって変換されたページ (->オリジナル) /