使用 react-router jsx 的 Webpack 代码拆分
Webpack code splitting utilizing react-router jsx
我的路线是用 jsx 映射的。我使用 webpack 来捆绑东西,我想根据路由将输出的 js 文件分成块。
我试过 require.ensure 但 webpack 没有分割任何东西。最后它只生成一个包文件。我不确定我在这里做错了什么。我不想维护路线所在的 2 个地方。理想情况下,webpack 使用我已经定义的路由。
export const renderRoutes = () => (
<Provider store={store}>
<Router history={history}>
<Route path='en' component={AppContainer}>
<Route path='cart' getComponent={(location, cb) => {
require.ensure([], (require) => {
cb(null, require('./Cart/CartContainer'));
});
}}/>
<Route path='checkout'>
<Route path='shipping_address' component={ShippingAddressFormContainer} />
<Route path='delivery_options' component={DeliveryOptionFormContainer} />
<Route path='payment' component={PaymentContainer} />
<Route path='review_order' component={ReviewOrderContainer} />
<Route path='confirmation' component={ConfirmationContainer} />
</Route>
</Route>
</Router>
</Provider>
);
render(
renderRoutes(),
document.getElementById('react-root')
);
grunt 文件配置:
dev: {
entry: [
'./<%= paths.src %>/javascripts/react/containers/Root'
],
output: {
path: path.join(__dirname, '<%= paths.dist %>/javascripts'),
filename: 'bundle.js',
chunkFilename: '[id].chunk.js',
publicPath: '/en/'
},
devtool: 'cheap-module-source-map',
plugins: [
new webpack.optimize.CommonsChunkPlugin('bundle.js'),
new webpack.optimize.OccurrenceOrderPlugin(), // Chunk ids by occurrence count. Ids that are used often get lower (shorter) ids.
new webpack.DefinePlugin({
'process.env': {
'NODE_ENV': JSON.stringify('development')
}
})
],
module: {
preLoaders: [
{
test: /\.json$/,
loader: 'json'
},
],
loaders: [
{
test: /\.js$/,
loaders: ['babel'],
exclude: /node_modules/,
include: __dirname
}
]
}
},
开发任务输出
Asset Size Chunks Chunk Names
bundle.js 2.76 MB 0, 1, 0 [emitted] bundle.js, main
bundle.js.map 3.17 MB 0, 1, 0 [emitted] bundle.js, main
我看了一些教程,但这种情况似乎并不常见。
I talked to OP in chat, he showed me his entire code and I figured it out!
在你的代码中,你有类似的东西:
// ... Some imports here
import CartContainer from './Cart/CartContainer';
// ... More imports here
export const renderRoutes = () => (
<Provider store={store}>
<Router history={history}>
// Some other routes here
<Route path='cart' getComponent={(location, cb) => {
require.ensure([], (require) => {
cb(null, require('./Cart/Container').default);
});
}} />
</Router>
</Provider>
);
现在你可能会看到它,但你是 "tricking" webpack,因为当你 import CartContainer
(在第一行)时,你说的是 "ok, this chunk (the main) has CartContainer
, please, add it to the bundle"。然后,当你使用 require.ensure
时,webpack 已经知道这个依赖被加载了(它去了主块)并且它不需要将它拆分成不同的块。
你只需要删除第一个导入,这样 webpack 就会知道你想要 CartContainer
在一个单独的块中!请注意,由于您使用的是 babel
,因此在需要此额外块时需要添加 .default
。
希望对您有所帮助!
我的路线是用 jsx 映射的。我使用 webpack 来捆绑东西,我想根据路由将输出的 js 文件分成块。
我试过 require.ensure 但 webpack 没有分割任何东西。最后它只生成一个包文件。我不确定我在这里做错了什么。我不想维护路线所在的 2 个地方。理想情况下,webpack 使用我已经定义的路由。
export const renderRoutes = () => (
<Provider store={store}>
<Router history={history}>
<Route path='en' component={AppContainer}>
<Route path='cart' getComponent={(location, cb) => {
require.ensure([], (require) => {
cb(null, require('./Cart/CartContainer'));
});
}}/>
<Route path='checkout'>
<Route path='shipping_address' component={ShippingAddressFormContainer} />
<Route path='delivery_options' component={DeliveryOptionFormContainer} />
<Route path='payment' component={PaymentContainer} />
<Route path='review_order' component={ReviewOrderContainer} />
<Route path='confirmation' component={ConfirmationContainer} />
</Route>
</Route>
</Router>
</Provider>
);
render(
renderRoutes(),
document.getElementById('react-root')
);
grunt 文件配置:
dev: {
entry: [
'./<%= paths.src %>/javascripts/react/containers/Root'
],
output: {
path: path.join(__dirname, '<%= paths.dist %>/javascripts'),
filename: 'bundle.js',
chunkFilename: '[id].chunk.js',
publicPath: '/en/'
},
devtool: 'cheap-module-source-map',
plugins: [
new webpack.optimize.CommonsChunkPlugin('bundle.js'),
new webpack.optimize.OccurrenceOrderPlugin(), // Chunk ids by occurrence count. Ids that are used often get lower (shorter) ids.
new webpack.DefinePlugin({
'process.env': {
'NODE_ENV': JSON.stringify('development')
}
})
],
module: {
preLoaders: [
{
test: /\.json$/,
loader: 'json'
},
],
loaders: [
{
test: /\.js$/,
loaders: ['babel'],
exclude: /node_modules/,
include: __dirname
}
]
}
},
开发任务输出
Asset Size Chunks Chunk Names
bundle.js 2.76 MB 0, 1, 0 [emitted] bundle.js, main
bundle.js.map 3.17 MB 0, 1, 0 [emitted] bundle.js, main
我看了一些教程,但这种情况似乎并不常见。
I talked to OP in chat, he showed me his entire code and I figured it out!
在你的代码中,你有类似的东西:
// ... Some imports here
import CartContainer from './Cart/CartContainer';
// ... More imports here
export const renderRoutes = () => (
<Provider store={store}>
<Router history={history}>
// Some other routes here
<Route path='cart' getComponent={(location, cb) => {
require.ensure([], (require) => {
cb(null, require('./Cart/Container').default);
});
}} />
</Router>
</Provider>
);
现在你可能会看到它,但你是 "tricking" webpack,因为当你 import CartContainer
(在第一行)时,你说的是 "ok, this chunk (the main) has CartContainer
, please, add it to the bundle"。然后,当你使用 require.ensure
时,webpack 已经知道这个依赖被加载了(它去了主块)并且它不需要将它拆分成不同的块。
你只需要删除第一个导入,这样 webpack 就会知道你想要 CartContainer
在一个单独的块中!请注意,由于您使用的是 babel
,因此在需要此额外块时需要添加 .default
。
希望对您有所帮助!