无法获得 webpack require.ensure 分块方法来使用 react-router 并生成单独的包文件
Can't get webpack require.ensure chunking method to work with react-router and generate separate bundle files
我想使用 webpack 分块方法为我的路由配置中的单独路由生成单独的包。
实现它的一种方法是使用 require.ensure 为块定义拆分点并根据浏览器需求异步加载模块。
这是我得到的:
webpack.config.js(根据执行的 npm 脚本与 dev/prod webpack 配置合并):
var autoprefixer = require('autoprefixer');
var html = require('html-webpack-plugin');
var path = require('path');
var webpack = require('webpack');
var node_modules_dir = path.resolve('./node_modules')
var HappyPack = require('happypack');
module.exports = {
context: path.resolve('./src'),
entry: {
app: ['./scripts/index.js', './styles/index.scss'],
vendor: ['react', 'react-dom', 'react-redux', 'redux','immutable'],
},
module: {
loaders: [
{
test: /\.(jpg|png|gif|json)$/,
loader: 'file',
query: {
name: 'assets/[hash].[ext]',
},
},
{
test: /\.svg$/,
loader: 'happypack/loader?id=svg'
},
],
},
output: {
filename: '[name].js',
path: path.resolve('./build'),
},
plugins: [
new webpack.optimize.OccurrenceOrderPlugin(),
// new webpack.optimize.LimitChunkCountPlugin({maxChunks: 5}),
// new webpack.optimize.MinChunkSizePlugin({minChunkSize: 10000}),
new html({
minify: {
collapseWhitespace: true,
},
template: './index.html',
title: process.env.npm_package_config_title,
}),
new webpack.optimize.CommonsChunkPlugin('vendor','vendor.bundle.js'),
new HappyPack({
id: 'svg',
threads: 5,
loaders: [
'svg-inline'
]
})
],
postcss: function() {
return [
autoprefixer,
];
},
resolve: {
alias: {
assets: path.resolve('./src/assets'),
lib: path.resolve('./src/lib'),
modules: path.resolve('./src/scripts/modules'),
scripts: path.resolve('./src/scripts'),
styles: path.resolve('./src/styles'),
toolbox: path.resolve('./node_modules/react-toolbox'),
vendors: path.resolve('./src/vendors'),
'react-redux': node_modules_dir + '/react-redux/dist/react-redux.min.js',
'redux': node_modules_dir + '/redux/dist/redux.min.js',
'immutable': node_modules_dir +'/immutable/dist/immutable.min.js'
},
extensions: [
'',
'.js',
'.jsx',
'.css',
'.scss',
],
},
toolbox: {
theme: path.resolve('./toolbox/index.scss'),
},
};
webpack.config.dev.js(dev webpack配置[与上面合并]):
var merge = require('webpack-merge');
var webpack = require('webpack');
var path = require('path');
var config = require('./config');
var HappyPack = require('happypack');
var ExtractTextPlugin = require("extract-text-webpack-plugin");
module.exports = merge(config, {
// devtool: 'eval',
devServer: {
contentBase: 'build',
historyApiFallback: true,
hot: true,
host: '0.0.0.0',
inline: true,
port: parseInt(process.env.npm_package_config_port),
},
module: {
loaders: [
{
test: /\.jsx?$/,
exclude: /node_modules/,
loader: 'happypack/loader?id=jsx'
},
{
test: /\.s?css$/,
loader: 'happypack/loader?id=css'
},
],
},
output: {
chunkFilename: "[name].js",
publicPath: 'http://localhost:' + process.env.npm_package_config_port + process.env.npm_package_config_public_path,
pathInfo: true,
},
plugins: [
new webpack.PrefetchPlugin('react'),
new webpack.PrefetchPlugin('react-toolbox'),
new webpack.PrefetchPlugin('react-redux'),
new webpack.PrefetchPlugin('redux'),
new webpack.PrefetchPlugin('immutable'),
new webpack.PrefetchPlugin('./scripts/routes.jsx'),
new webpack.PrefetchPlugin('./scripts/components/smart/index.jsx'),
new webpack.PrefetchPlugin('./scripts/components/views/login/index.jsx'),
new webpack.PrefetchPlugin('./scripts/components/views/companies_list/index.jsx'),
new webpack.PrefetchPlugin('./scripts/components/views/shortlists/index.jsx'),
new webpack.PrefetchPlugin('./scripts/components/views/testing_shortlist/index.jsx'),
new webpack.PrefetchPlugin('./scripts/components/views/tools/components/index.jsx'),
new webpack.PrefetchPlugin('./scripts/components/views/tools/horizontal_chart/index.jsx'),
new webpack.PrefetchPlugin('./scripts/components/views/tools/smarts/index.jsx'),
new webpack.PrefetchPlugin('./scripts/components/views/tools/view_content/index.jsx'),
new webpack.PrefetchPlugin('./scripts/components/views/tools/views/index.jsx'),
new webpack.PrefetchPlugin('./scripts/components/views/tools.old/refactorized_tools/components/index.jsx'),
new webpack.PrefetchPlugin('./scripts/components/views/tools.old/refactorized_tools/composed/index.jsx'),
new webpack.PrefetchPlugin('./scripts/components/views/tools.old/refactorized_tools/view_content/index.jsx'),
new webpack.PrefetchPlugin('./scripts/components/views/tools.old/refactorized_tools/views/index.jsx'),
new webpack.PrefetchPlugin('./scripts/components/views/tools.old/tools/cities_list_with_filters/index.jsx'),
new webpack.PrefetchPlugin('./scripts/components/views/tools.old/tools/city_path_start/index.jsx'),
new webpack.PrefetchPlugin('./scripts/components/views/tools.old/tools/company_path_start/index.jsx'),
new webpack.PrefetchPlugin('./scripts/components/views/tools.old/tools/compare_cities_datapoints/index.jsx'),
new webpack.PrefetchPlugin('./scripts/components/views/tools.old/tools/compare_companies_datapoints/index.jsx'),
new webpack.PrefetchPlugin('./scripts/components/views/tools.old/tools/compare_result/index.jsx'),
new webpack.PrefetchPlugin('./scripts/components/views/tools.old/tools/scan_your_brand/index.jsx'),
new webpack.PrefetchPlugin('./scripts/components/views/tools.old/tools/subcomponents/index.jsx'),
new webpack.PrefetchPlugin('./lib/ui/multi_select/RTAutocomplete/index.js'),
new webpack.PrefetchPlugin('./scripts/components/views/tools/view_content/charts/style/charts.scss'),
new webpack.PrefetchPlugin('./scripts/components/views/tools/view_content/filters_box/style/city.scss'),
new webpack.PrefetchPlugin('./scripts/components/views/tools/view_content/filters_box/style/company.scss'),
new webpack.PrefetchPlugin('./scripts/components/views/tools/view_content/map_with_bottom_stats/style.scss'),
new webpack.PrefetchPlugin('./scripts/components/views/tools/view_content/city_boxes/style/city_boxes.scss'),
new webpack.PrefetchPlugin('./scripts/components/views/tools/view_content/company_boxes/style/company_boxes.scss'),
new webpack.PrefetchPlugin('./scripts/components/views/tools/view_content/filters_box_with_header_box/style/city.scss'),
new webpack.PrefetchPlugin('./scripts/components/views/tools/view_content/filters_box_with_header_box/style/company.scss'),
new webpack.PrefetchPlugin('./scripts/components/views/tools/view_content/selected_entities/style/selected_entities.scss'),
new webpack.PrefetchPlugin('./scripts/components/views/tools/view_content/human_resources_table_box/style/_human_resources_table_box.scss'),
// new webpack.PrefetchPlugin(''),
new ExtractTextPlugin("[hash].css"),
new webpack.DefinePlugin({
'process.env.NODE_ENV': JSON.stringify('development'),
'process.env.LANDING_ONLY': JSON.stringify(false),
}),
new webpack.HotModuleReplacementPlugin(),
new HappyPack({
id: 'jsx',
threads: 5,
loaders: ['babel?presets[]=react-hmre']
}),
new HappyPack({
id: 'css',
threads: 5,
loaders: [
'style',
'css?sourceMap,modules,localIdentName=[local]__[hash:base64:5]',
'postcss',
'resolve-url',
'sass?sourceMap',
'toolbox'
]
})
],
});
routes.jsx:
[some module imports here]
export default (
<Route component={ PermisionProvider } >
<Route component={ AppProvider } >
<Route component={ SnackbarProvider } >
<Redirect from={ paths.root } to={ localStorage.get('user') ? paths.login : paths.landingPageCities } />
{ /* Landing */ }
<Route onEnter={ _hasPermission.bind(null, 'landingPage') }>
<Route component={ LandingLayout }>
<Route
path={ paths.landingPageCities }
getComponent={(location, callback) => {
require.ensure(['modules/landing_page/smarts/SmartLandingCities'], function (require) {
callback(null, require('modules/landing_page/smarts/SmartLandingCities').default);
}, 'SmartLandingCities');
}}
/>
<Route
path={ paths.landingPageCompanies }
getComponent={(location, callback) => {
require.ensure(['modules/landing_page/smarts/SmartLandingCompanies'], function (require) {
callback(null, require('modules/landing_page/smarts/SmartLandingCompanies').default);
}, 'SmartLandingCompanies');
}}
/>
<Route
path={ paths.aboutUsPage }
getComponent={(location, callback) => {
require.ensure(['modules/landing_page/views/AboutUsPage'], function (require) {
callback(null, require('modules/landing_page/views/AboutUsPage').default);
}, 'AboutUsPage');
}}
/>
</Route>
</Route>
{ /* Login */ }
<Route onEnter={ _hasPermission.bind(null, 'login') }>
我看了很多博文和教程,这里似乎都到位了。然而,webpack 没有为我使用 require.ensure:
的两条路线生成单独的包
- SmartLandingCities
- SmartLandingCompanies
- 关于我们页面
我已经非常绝望了,因为应用程序包的大小为 2mb,我已经使用了所有可用的大小缩小方法。
感谢您的帮助!
因为已经有三个访问包含有效解决方案的 repo 的请求,这里是:)
祝你编码愉快!
我想使用 webpack 分块方法为我的路由配置中的单独路由生成单独的包。 实现它的一种方法是使用 require.ensure 为块定义拆分点并根据浏览器需求异步加载模块。
这是我得到的:
webpack.config.js(根据执行的 npm 脚本与 dev/prod webpack 配置合并):
var autoprefixer = require('autoprefixer');
var html = require('html-webpack-plugin');
var path = require('path');
var webpack = require('webpack');
var node_modules_dir = path.resolve('./node_modules')
var HappyPack = require('happypack');
module.exports = {
context: path.resolve('./src'),
entry: {
app: ['./scripts/index.js', './styles/index.scss'],
vendor: ['react', 'react-dom', 'react-redux', 'redux','immutable'],
},
module: {
loaders: [
{
test: /\.(jpg|png|gif|json)$/,
loader: 'file',
query: {
name: 'assets/[hash].[ext]',
},
},
{
test: /\.svg$/,
loader: 'happypack/loader?id=svg'
},
],
},
output: {
filename: '[name].js',
path: path.resolve('./build'),
},
plugins: [
new webpack.optimize.OccurrenceOrderPlugin(),
// new webpack.optimize.LimitChunkCountPlugin({maxChunks: 5}),
// new webpack.optimize.MinChunkSizePlugin({minChunkSize: 10000}),
new html({
minify: {
collapseWhitespace: true,
},
template: './index.html',
title: process.env.npm_package_config_title,
}),
new webpack.optimize.CommonsChunkPlugin('vendor','vendor.bundle.js'),
new HappyPack({
id: 'svg',
threads: 5,
loaders: [
'svg-inline'
]
})
],
postcss: function() {
return [
autoprefixer,
];
},
resolve: {
alias: {
assets: path.resolve('./src/assets'),
lib: path.resolve('./src/lib'),
modules: path.resolve('./src/scripts/modules'),
scripts: path.resolve('./src/scripts'),
styles: path.resolve('./src/styles'),
toolbox: path.resolve('./node_modules/react-toolbox'),
vendors: path.resolve('./src/vendors'),
'react-redux': node_modules_dir + '/react-redux/dist/react-redux.min.js',
'redux': node_modules_dir + '/redux/dist/redux.min.js',
'immutable': node_modules_dir +'/immutable/dist/immutable.min.js'
},
extensions: [
'',
'.js',
'.jsx',
'.css',
'.scss',
],
},
toolbox: {
theme: path.resolve('./toolbox/index.scss'),
},
};
webpack.config.dev.js(dev webpack配置[与上面合并]):
var merge = require('webpack-merge');
var webpack = require('webpack');
var path = require('path');
var config = require('./config');
var HappyPack = require('happypack');
var ExtractTextPlugin = require("extract-text-webpack-plugin");
module.exports = merge(config, {
// devtool: 'eval',
devServer: {
contentBase: 'build',
historyApiFallback: true,
hot: true,
host: '0.0.0.0',
inline: true,
port: parseInt(process.env.npm_package_config_port),
},
module: {
loaders: [
{
test: /\.jsx?$/,
exclude: /node_modules/,
loader: 'happypack/loader?id=jsx'
},
{
test: /\.s?css$/,
loader: 'happypack/loader?id=css'
},
],
},
output: {
chunkFilename: "[name].js",
publicPath: 'http://localhost:' + process.env.npm_package_config_port + process.env.npm_package_config_public_path,
pathInfo: true,
},
plugins: [
new webpack.PrefetchPlugin('react'),
new webpack.PrefetchPlugin('react-toolbox'),
new webpack.PrefetchPlugin('react-redux'),
new webpack.PrefetchPlugin('redux'),
new webpack.PrefetchPlugin('immutable'),
new webpack.PrefetchPlugin('./scripts/routes.jsx'),
new webpack.PrefetchPlugin('./scripts/components/smart/index.jsx'),
new webpack.PrefetchPlugin('./scripts/components/views/login/index.jsx'),
new webpack.PrefetchPlugin('./scripts/components/views/companies_list/index.jsx'),
new webpack.PrefetchPlugin('./scripts/components/views/shortlists/index.jsx'),
new webpack.PrefetchPlugin('./scripts/components/views/testing_shortlist/index.jsx'),
new webpack.PrefetchPlugin('./scripts/components/views/tools/components/index.jsx'),
new webpack.PrefetchPlugin('./scripts/components/views/tools/horizontal_chart/index.jsx'),
new webpack.PrefetchPlugin('./scripts/components/views/tools/smarts/index.jsx'),
new webpack.PrefetchPlugin('./scripts/components/views/tools/view_content/index.jsx'),
new webpack.PrefetchPlugin('./scripts/components/views/tools/views/index.jsx'),
new webpack.PrefetchPlugin('./scripts/components/views/tools.old/refactorized_tools/components/index.jsx'),
new webpack.PrefetchPlugin('./scripts/components/views/tools.old/refactorized_tools/composed/index.jsx'),
new webpack.PrefetchPlugin('./scripts/components/views/tools.old/refactorized_tools/view_content/index.jsx'),
new webpack.PrefetchPlugin('./scripts/components/views/tools.old/refactorized_tools/views/index.jsx'),
new webpack.PrefetchPlugin('./scripts/components/views/tools.old/tools/cities_list_with_filters/index.jsx'),
new webpack.PrefetchPlugin('./scripts/components/views/tools.old/tools/city_path_start/index.jsx'),
new webpack.PrefetchPlugin('./scripts/components/views/tools.old/tools/company_path_start/index.jsx'),
new webpack.PrefetchPlugin('./scripts/components/views/tools.old/tools/compare_cities_datapoints/index.jsx'),
new webpack.PrefetchPlugin('./scripts/components/views/tools.old/tools/compare_companies_datapoints/index.jsx'),
new webpack.PrefetchPlugin('./scripts/components/views/tools.old/tools/compare_result/index.jsx'),
new webpack.PrefetchPlugin('./scripts/components/views/tools.old/tools/scan_your_brand/index.jsx'),
new webpack.PrefetchPlugin('./scripts/components/views/tools.old/tools/subcomponents/index.jsx'),
new webpack.PrefetchPlugin('./lib/ui/multi_select/RTAutocomplete/index.js'),
new webpack.PrefetchPlugin('./scripts/components/views/tools/view_content/charts/style/charts.scss'),
new webpack.PrefetchPlugin('./scripts/components/views/tools/view_content/filters_box/style/city.scss'),
new webpack.PrefetchPlugin('./scripts/components/views/tools/view_content/filters_box/style/company.scss'),
new webpack.PrefetchPlugin('./scripts/components/views/tools/view_content/map_with_bottom_stats/style.scss'),
new webpack.PrefetchPlugin('./scripts/components/views/tools/view_content/city_boxes/style/city_boxes.scss'),
new webpack.PrefetchPlugin('./scripts/components/views/tools/view_content/company_boxes/style/company_boxes.scss'),
new webpack.PrefetchPlugin('./scripts/components/views/tools/view_content/filters_box_with_header_box/style/city.scss'),
new webpack.PrefetchPlugin('./scripts/components/views/tools/view_content/filters_box_with_header_box/style/company.scss'),
new webpack.PrefetchPlugin('./scripts/components/views/tools/view_content/selected_entities/style/selected_entities.scss'),
new webpack.PrefetchPlugin('./scripts/components/views/tools/view_content/human_resources_table_box/style/_human_resources_table_box.scss'),
// new webpack.PrefetchPlugin(''),
new ExtractTextPlugin("[hash].css"),
new webpack.DefinePlugin({
'process.env.NODE_ENV': JSON.stringify('development'),
'process.env.LANDING_ONLY': JSON.stringify(false),
}),
new webpack.HotModuleReplacementPlugin(),
new HappyPack({
id: 'jsx',
threads: 5,
loaders: ['babel?presets[]=react-hmre']
}),
new HappyPack({
id: 'css',
threads: 5,
loaders: [
'style',
'css?sourceMap,modules,localIdentName=[local]__[hash:base64:5]',
'postcss',
'resolve-url',
'sass?sourceMap',
'toolbox'
]
})
],
});
routes.jsx:
[some module imports here]
export default (
<Route component={ PermisionProvider } >
<Route component={ AppProvider } >
<Route component={ SnackbarProvider } >
<Redirect from={ paths.root } to={ localStorage.get('user') ? paths.login : paths.landingPageCities } />
{ /* Landing */ }
<Route onEnter={ _hasPermission.bind(null, 'landingPage') }>
<Route component={ LandingLayout }>
<Route
path={ paths.landingPageCities }
getComponent={(location, callback) => {
require.ensure(['modules/landing_page/smarts/SmartLandingCities'], function (require) {
callback(null, require('modules/landing_page/smarts/SmartLandingCities').default);
}, 'SmartLandingCities');
}}
/>
<Route
path={ paths.landingPageCompanies }
getComponent={(location, callback) => {
require.ensure(['modules/landing_page/smarts/SmartLandingCompanies'], function (require) {
callback(null, require('modules/landing_page/smarts/SmartLandingCompanies').default);
}, 'SmartLandingCompanies');
}}
/>
<Route
path={ paths.aboutUsPage }
getComponent={(location, callback) => {
require.ensure(['modules/landing_page/views/AboutUsPage'], function (require) {
callback(null, require('modules/landing_page/views/AboutUsPage').default);
}, 'AboutUsPage');
}}
/>
</Route>
</Route>
{ /* Login */ }
<Route onEnter={ _hasPermission.bind(null, 'login') }>
我看了很多博文和教程,这里似乎都到位了。然而,webpack 没有为我使用 require.ensure:
的两条路线生成单独的包- SmartLandingCities
- SmartLandingCompanies
- 关于我们页面
我已经非常绝望了,因为应用程序包的大小为 2mb,我已经使用了所有可用的大小缩小方法。
感谢您的帮助!
因为已经有三个访问包含有效解决方案的 repo 的请求,这里是:) 祝你编码愉快!