改写scripts脚本支持多应用(MPA)开发
(use create-react-app@2.1.8
)
- 在不
eject
的情况下,安装react-app-rewired
,customize-cra
,仍旧可以使用react-app-rewired
编译你的应用为SPA- 也可以通过
eject
直接改写webpack.config
和scripts脚本- 可通过少量的改动合并为一个应用
安装react-app-rewired
,customize-cra
:
npx add react-app-rewired customize-cra
根目录下新增config-overrides.js
:
const { addBabelPlugin, addLessLoader } = require('customize-cra');
// override config
module.exports = (config) => {
return config;
}
在项目根目录下新增react.json
:
{
"version": 1.0,
"projects": {
"main": {
"name": "main",
"path": ".",
"publicPath": "",
"index": "public/index.html",
"main": "src/index.js"
},
"app1": {
"name": "app1",
"path": "app1",
"publicPath": "app1/",
"index": "public/index.html",
"main": "src/app1/index.js"
}
}
}
新增util/index.js
:
const path = require('path');
const chalk = require('react-dev-utils/chalk');
const { paths } = require('react-app-rewired');
const configFactory = require(paths.scriptVersion + '/config/webpack.config');
const createDevServerConfig = require(paths.scriptVersion + '/config/webpackDevServer.config');
const override = require('../config-overrides');
let packageJson = require(path.join(paths.appPath,'react.json'));
let apps = packageJson.projects;
const argvs = process.argv.slice(2);
let currentApp = null;
// 通过参数--app指定应用
argvs.some(arg => {
if (arg.startsWith('--app=')) {
const currentStr = arg.split('=')[1];
if (!apps[currentStr]) {
console.log(chalk.yellow(`${currentStr} is not in apps`));
process.exit(1);
} else {
currentApp = {currentStr:apps[currentStr]};
return true;
}
}
return false;
});
const bpObj = currentApp?currentApp:apps;
const buildApps = [];
for(let key in bpObj){
const config =configFactory(process.env.NODE_ENV);
override(config);
setAppConfig(config,bpObj[key]);
bpObj[key]['config']=config;
buildApps.push(bpObj[key]);
}
function setAppConfig(config, app) {
config.entry[config.entry.length - 1] = path.join(paths.appPath, app.main);
if(app.path){
config.output.path = path.join(paths.appBuild, app.path);
}
// build时设置publicPath
if(app.publicPath&&process.env.NODE_ENV!=="development"){
config.output.publicPath = `${app.publicPath}/`;
}
}
module.exports = {
buildApps,
createDevServerConfig,
paths
};
复制react-scripts
下的scripts脚本到根目录下并修改start.js
,build.js
。
checkBrowsers(buildPath, isInteractive)
写在function
内(buildApp
),以方便调用进行编译
以build为例:
const async = require('async');
// src有多少个应用,使用util/index.js下的paths代替原先的paths(删除旧的require)
let { buildApps,paths } = require('../util');
let i = -1, len = buildApps.length;
// 使用async.waterfall依次打包react.json下的应用
async.waterfall(buildApps.map(currentApp => {
return (callback) => {
i++;
const config = currentApp['config'];
let buildPath = path.join(paths.appBuild,currentApp.path);
buildApp(currentApp, buildPath, config).then(() => {
i == (len - 1) ? '' : callback();
});
}
}), (err, result) => {
console.log(err);
});
修改package.json
内的scripts:
"scripts": {
"start": "node scripts/start.js",
"app1":"node scripts/start.js --app=app1",
"build": "node scripts/build.js",
"test": "node scripts/test.js"
},
打包的目录如图所示。
运行以下命令浏览应用:
> cd build
> serve
github地址:https://github.com/upcyoung/muti-project.git
原创文章,转载请保留或注明出处