create-react-app 多頁面
阿新 • • 發佈:2021-10-16
原文連線1:https://segmentfault.com/a/1190000019357253
原文連線2:https://www.jianshu.com/p/5bed07073ddd
create-react-app 多頁面
方法1 https://github.com/maoguijun/multi-entry-react-app
1. eject create-react-app
$ npm i yarn -g
$ yarn create react-app my-app
$ yarn eject
$ rm -rf node_modules\
$ yarn
2. 檢視目錄
| .gitignore | package.json | README.md | yarn.lock | +---config #webpack 配置 | | env.js | | paths.js | | webpack.config.js | | webpackDevServer.config.js | | | \---jest | cssTransform.js | fileTransform.js | +---public # 靜態檔案 | favicon.ico | index.html | manifest.json | +---scripts # 指令碼 | build.js | start.js | test.js | \---src # 專案檔案 App.css App.js App.test.js index.css index.js # webpack entry logo.svg serviceWorker.js
3. 修改 /config/
3.1
// /config/paths.js // 新增以下程式碼 + const globby = require('globby'); // 獲取所有入口js + const entriesPath = globby.sync([resolveApp('src') + '/*/index.js']).map(filePath => { let tmp = filePath.split('/'); let name = tmp[tmp.length - 2]; return {path: filePath, name} }); module.exports = { - appIndexJs: resolveModule(resolveApp, 'src/index') ... + entriesPath, }
// /config/webpackDevServer.config.js + const paths = require('./paths'); + const files = paths.entriesPath; + const rewrites = files.map(({name, path}) => { return { from: new RegExp(`^\/${name}`), to: `/${name}.html` }; }); modelue.exports = function (proxy, allowedHost) { return { ... contentBase: paths.appPublic, ... + rewrites, } }
// /config/webpack.config.js
+ const paths = require('./paths');
module.exports = function (webpackEnv) {
// 獲取 entry
+ function getEntries(){
const entries = {};
const files = paths.entriesPath;
// console.log(117, files)
files.forEach(({name, path}) => {
entries[name] = [
isEnvDevelopment && require.resolve('react-dev-utils/webpackHotDevClient'),
path,
].filter(Boolean);
});
return entries;
}
+ const entries = getEntries()
+ const htmlPlugin = Object.keys(entries).map(name => {
return new HtmlWebpackPlugin(Object.assign({}, {
inject: true,
template: paths.appHtml,
chunks: [name, 0], // 只會插入名字中帶 "0" 或者 帶 name 的js 問題
filename: `${name}.html`,
title: `${name} html`,
}, isEnvProduction
? {
minify: {
removeComments: true,
collapseWhitespace: true,
removeRedundantAttributes: true,
useShortDoctype: true,
removeEmptyAttributes: true,
removeStyleLinkTypeAttributes: true,
keepClosingSlash: true,
minifyJS: true,
minifyCSS: true,
minifyURLs: true
}
}
: undefined));
});
}
return {
...
- entry: [
isEnvDevelopment &&
require.resolve('react-dev-utils/webpackHotDevClient'),
paths.appIndexJs,
].filter(Boolean),
+ entry:entries,
output: {
...
- filename: isEnvProduction
? 'static/js/[name].[contenthash:8].js'
: isEnvDevelopment && 'static/js/bundle.js',
+ filename: isEnvProduction
? 'static/js/[name].[contenthash:8].js'
: isEnvDevelopment && 'static/js/[name].bundle.js',
...
}
...
plugins: [
- new HtmlWebpackPlugin(
Object.assign(
{},
{
inject: true,
template: paths.appHtml,
},
isEnvProduction
? {
minify: {
removeComments: true,
collapseWhitespace: true,
removeRedundantAttributes: true,
useShortDoctype: true,
removeEmptyAttributes: true,
removeStyleLinkTypeAttributes: true,
keepClosingSlash: true,
minifyJS: true,
minifyCSS: true,
minifyURLs: true,
},
}
: undefined
)
),
+ ...htmlPlugin,
]
}
// /scripts/start.js
// /scripts/build.js
// /scripts/test.js
+ const path = require("path")
- if (!checkRequiredFiles([paths.appHtml, paths.appIndexJs])) {
process.exit(1);
}
+ paths.entriesPath.forEach(({path, name}) => {
if (!checkRequiredFiles([paths.appHtml, path])) {
process.exit(1);
}
})
4. 修改目錄
| .gitignore #
| package.json
| README.md
| yarn.lock
|
+---config #webpack 相關配置
| | env.js
| | paths.js
| | webpack.config.js
| | webpackDevServer.config.js
| |
| \---jest
| cssTransform.js
| fileTransform.js
|
+---public # 靜態檔案
| favicon.ico
| index.html
| manifest.json
|
+---scripts # 指令碼
| build.js
| start.js
| test.js
|
\---src # 專案檔案
| logo.svg
| serviceWorker.js
| App.css # 刪除
| App.js # 刪除
| App.test.js # 刪除
| index.css # 刪除
| index.js # 刪除
| logo.svg
| serviceWorker.js
|
+ +---h5 # 新增
| | index.js
| |
| +---container
| | \---pcDemo
| | index.css
| | index.js
| |
| +---reducer
| | index.js
| |
| \---store
| index.js
|
+ \---pc # 新增
| index.js
|
+---container
| \---pcDemo
| index.css
| index.js
|
+---reducer
| index.js
|
\---store
index.js
5. 至此,多入口已經修改完畢
6. 對 index.html 做處理
$ yarn add handlebars-loader --save
// /config/webpack.config.js
module.exports = function (webpackEnv) {
...
return {
...
module: {
rules: [
+ {
test: /.hbs$/,
loader: require.resolve('handlebars-loader')
},
]
}
}
}
<!DOCTYPE html>
<html lang="en">
<head>
<meta charset="utf-8" />
<link rel="shortcut icon" href="%PUBLIC_URL%/favicon.ico" />
<meta
name="viewport"
content="width=device-width, initial-scale=1, shrink-to-fit=no"
/>
<meta name="theme-color" content="#000000" />
<link rel="manifest" href="%PUBLIC_URL%/manifest.json" />
- <title>REACT APP</title>
+ <title><%= htmlWebpackPlugin.options.title %></title>
</head>
<body>
<noscript>You need to enable JavaScript to run this app.</noscript>
<div id="root"></div>
</body>
</html>