將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 看效果