改寫scripts腳本支持多應(yīng)用(MPA)開發(fā)
(use create-react-app@2.1.8
)
- 在不
eject
的情況下,安裝react-app-rewired
,customize-cra
,仍舊可以使用react-app-rewired
編譯你的應(yīng)用為SPA- 也可以通過
eject
直接改寫webpack.config
和scripts腳本- 可通過少量的改動合并為一個應(yīng)用
安裝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;
// 通過參數(shù)--app指定應(yīng)用
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時設(shè)置publicPath
if(app.publicPath&&process.env.NODE_ENV!=="development"){
config.output.publicPath = `${app.publicPath}/`;
}
}
module.exports = {
buildApps,
createDevServerConfig,
paths
};
復(fù)制react-scripts
下的scripts腳本到根目錄下并修改start.js
,build.js
。
checkBrowsers(buildPath, isInteractive)
寫在function
內(nèi)(buildApp
)喉酌,以方便調(diào)用進行編譯
以build為例:
const async = require('async');
// src有多少個應(yīng)用,使用util/index.js下的paths代替原先的paths(刪除舊的require)
let { buildApps,paths } = require('../util');
let i = -1, len = buildApps.length;
// 使用async.waterfall依次打包react.json下的應(yīng)用
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
內(nèi)的scripts:
"scripts": {
"start": "node scripts/start.js",
"app1":"node scripts/start.js --app=app1",
"build": "node scripts/build.js",
"test": "node scripts/test.js"
},
打包的目錄如圖所示泵喘。
build.png
運行以下命令瀏覽應(yīng)用:
> cd build
> serve
github地址:https://github.com/upcyoung/muti-project.git
原創(chuàng)文章泪电,轉(zhuǎn)載請保留或注明出處