无法让 webpack require.ensure 分块方法与 react-router 一起使用并生成单独的捆绑文件
Posted
技术标签:
【中文标题】无法让 webpack require.ensure 分块方法与 react-router 一起使用并生成单独的捆绑文件【英文标题】:Can't get webpack require.ensure chunking method to work with react-router and generate separate bundle files 【发布时间】:2016-10-22 23:13:37 【问题描述】:我想使用 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,而且我已经使用了所有可用的大小缩小方法。
感谢您的帮助!
【问题讨论】:
Using webpack and react-router for lazyloading and code-splitting not loading的可能重复 @azrahel,我也遇到了同样的问题,也发布了一个问题***.com/questions/39757297。虽然查看您的 webpack.config 文件,但您没有定义 chunkFilename: "[name].js" 而在 dev config 中您定义了。尝试在生产配置中添加它。如果你已经解决了,请告诉我。 嘿,是的,已经解决了。我真的不记得确切的问题是什么,但我可以向您发送我最近开始的小项目,上面的代码正常工作。 那太棒了。如果它在 github 上,你能发布项目的链接吗? @azrahel 如果您有其他喜欢的方法,请告诉我。 【参考方案1】:由于已经有三个请求访问包含工作解决方案的 repo,所以这里是:) 祝您编码愉快!
https://bitbucket.org/azrahel/crit_calendar/
【讨论】:
以上是关于无法让 webpack require.ensure 分块方法与 react-router 一起使用并生成单独的捆绑文件的主要内容,如果未能解决你的问题,请参考以下文章
无法让多应用 webpack 配置与 react-hot-loader 一起使用
无法让 webpack require.ensure 分块方法与 react-router 一起使用并生成单独的捆绑文件