将create-react-app单页面SPA改造成多页面MPA
React推荐的脚手架 create-react-app (以下简称CRA) 默认创建的是单页面(SPA)应用,如果项目需要使用多页面(MPA),则需要对脚手架进行更改
Tips: 以下配置基于 create-react-app@3.4.0 版本
举个栗子,比如我要将原来的index.html扩充出来一个iframe.html页面打包
1、eject 弹出配置
CRA把脚手架相关的配置给隐藏了,需要将配置给弹出
npm run eject
2、更改paths.js
将需要多页面化的html和js入口文件添加到paths中,可参考原有appHtml和appIndexJs即可
module.exports = {
...
appHtml: resolveApp('public/index.html'),
appIndexJs: resolveModule(resolveApp, 'src/index'),
// 多页面添加path部分
iframeHtml: resolveApp('public/iframe.html'),
appIframeJs: resolveModule(resolveApp, 'src/iframe/index'), // 路径可按需指定
...
};
3、更改webpack.config.js
更改entry入口
将原有的单entry入口的数组形式,更改成多chunk入口的对象形式
entry: {
index: [
isEnvDevelopment && require.resolve('react-dev-utils/webpackHotDevClient'),
paths.appIndexJs,
].filter(Boolean),
iframe: [
isEnvDevelopment && require.resolve('react-dev-utils/webpackHotDevClient'),
paths.appIframeJs,
].filter(Boolean),
}
更改output的filename
在开发模式,将打包的bundle.js加上对应包的chunkName
filename: isEnvProduction ? 'static/js/[name].[contenthash:8].js' : isEnvDevelopment && 'static/js/[name].bundle.js',
更改webpack的插件 ==HtmlWebpackPlugin== 选项
plugins: [
// Generates an `index.html` file with the <script> injected.
new HtmlWebpackPlugin(
Object.assign(
{},
{
inject: true,
template: paths.appHtml,
chunks: ['index']
},
...原代码
)
),
new HtmlWebpackPlugin(
Object.assign(
{},
{
inject: true,
template: paths.iframeHtml,
filename: 'iframe.html',
chunks: ['iframe']
},
)
),
// 如果有多个页面,继续添加即可
]
更改ManifestPlugin中entrypointFiles
在generate函数中,改造entrypointFiles,不然在编译时会出现 Cannot read property 'filter' of undefined
这样的错误
参考 https://github.com/timarney/r... 这个issue,里面有讨论
new ManifestPlugin({
fileName: 'asset-manifest.json',
publicPath: paths.publicUrlOrPath,
generate: (seed, files, entrypoints) => {
const manifestFiles = files.reduce((manifest, file) => {
manifest[file.name] = file.path;
return manifest;
}, seed);
// 改造entrypointFiles
const entrypointFiles = {};
Object.keys(entrypoints).forEach(entrypoint => {
entrypointFiles[entrypoint] = entrypoints[entrypoint].filter(fileName => !fileName.endsWith('.map'));
});
return {
files: manifestFiles,
entrypoints: entrypointFiles,
};
}
}),
4、webpackDevServer.config.js中更改historyApiFallback选项
使用rewrites选项
historyApiFallback: {
disableDotRule: true,
// index: paths.publicUrlOrPath,
// 指明哪些路径映射到哪个html
rewrites: [
{ from: /^\/index.html/, to: '/dist/index.html' },
{ from: /^\/iframe.html/, to: '/dist/iframe.html' },
]
},
5、更改
更改完以上配置后,重启项目即可,访问 localhost:3000/index.html 和 localhost:3000/iframe.html 看效果
**粗体** _斜体_ [链接](http://example.com) `代码` - 列表 > 引用
。你还可以使用@
来通知其他用户。