Merge branch 'dev' of codeup.aliyun.com:61c14a7efa282c88e103c23f/oak-cli into dev

This commit is contained in:
Xu Chang 2024-01-05 12:20:40 +08:00
commit 35f4ffacb9
24 changed files with 748 additions and 130 deletions

View File

@ -17,20 +17,24 @@ let moduleFileExtensions = [
'mp.ts', 'mp.ts',
'ts', 'ts',
]; ];
if (process.env.NODE_ENV !== 'production' && process.env.PROD !== 'true') { if (
moduleFileExtensions = [ process.env.NODE_ENV === 'production' ||
'dev.mp.js', process.env.NODE_ENV === 'staging' ||
'dev.mp.ts', process.env.PROD === 'true'
'dev.js', ) {
'dev.ts',
].concat(moduleFileExtensions);
} else {
moduleFileExtensions = [ moduleFileExtensions = [
'prod.mp.js', 'prod.mp.js',
'prod.mp.ts', 'prod.mp.ts',
'prod.js', 'prod.js',
'prod.ts', 'prod.ts',
].concat(moduleFileExtensions); ].concat(moduleFileExtensions);
} else {
moduleFileExtensions = [
'dev.mp.js',
'dev.mp.ts',
'dev.js',
'dev.ts',
].concat(moduleFileExtensions);
} }
// Resolve file paths in the same order as webpack // Resolve file paths in the same order as webpack

View File

@ -1,13 +1,48 @@
const { resolve } = require('path'); const { resolve } = require('path');
const watchFolders = process.env.NODE_ENV === 'production' ? ['../src', '../node_modules'] : [ const watchFolders = [
'../src', '../node_modules', '../../oak-domain', '../../oak-common-aspect', '../../oak-external-sdk', '../src', '../node_modules', '../../oak-domain', '../../oak-common-aspect', '../../oak-external-sdk',
'../../oak-frontend-base', '../../oak-general-business', '../../oak-memory-tree-store' '../../oak-frontend-base', '../../oak-general-business', '../../oak-memory-tree-store'
]; ];
const sourceExts = (process.env.NODE_ENV === 'production' || process.env.PROD === 'true') ? const sourceExts =
['prod.ts', 'ts', 'tsx', 'prod.js', 'js', 'jsx', 'less', 'json', 'svg'] : process.env.NODE_ENV === 'production' ||
['dev.ts', 'ts', 'tsx', 'dev.js', 'js', 'jsx', 'less', 'json', 'svg']; process.env.NODE_ENV === 'staging' ||
process.env.PROD === 'true'
? [
'prod.native.js',
'prod.native.ts',
'prod.native.jsx',
'prod.native.tsx',
'prod.js',
'prod.ts',
'prod.jsx',
'prod.tsx',
'js',
'ts',
'jsx',
'tsx',
'less',
'json',
'svg',
]
: [
'dev.native.js',
'dev.native.ts',
'dev.native.jsx',
'dev.native.tsx',
'dev.js',
'dev.ts',
'dev.jsx',
'dev.tsx',
'js',
'ts',
'jsx',
'tsx',
'less',
'json',
'svg',
];
const NullModules = ['fs', 'url']; const NullModules = ['fs', 'url'];
/** /**

View File

@ -40,24 +40,32 @@ let moduleFileExtensions = [
'pc.jsx', 'pc.jsx',
'jsx', 'jsx',
]; ];
if (process.env.NODE_ENV !== 'production' && process.env.PROD !== 'true') { if (
moduleFileExtensions = [ process.env.NODE_ENV === 'production' ||
'dev.web.js', process.env.NODE_ENV === 'staging' ||
'dev.web.ts', process.env.PROD === 'true'
'dev.web.tsx', ) {
'dev.js',
'dev.ts',
'dev.tsx',
].concat(moduleFileExtensions);
} else {
moduleFileExtensions = [ moduleFileExtensions = [
'prod.web.js', 'prod.web.js',
'prod.web.ts', 'prod.web.ts',
'prod.web.jsx',
'prod.web.tsx', 'prod.web.tsx',
'prod.js', 'prod.js',
'prod.ts', 'prod.ts',
'prod.jsx',
'prod.tsx', 'prod.tsx',
].concat(moduleFileExtensions); ].concat(moduleFileExtensions);
} else {
moduleFileExtensions = [
'dev.web.js',
'dev.web.ts',
'dev.web.jsx',
'dev.web.tsx',
'dev.js',
'dev.ts',
'dev.jsx',
'dev.tsx',
].concat(moduleFileExtensions);
} }
// Resolve file paths in the same order as webpack // Resolve file paths in the same order as webpack

View File

@ -8,32 +8,43 @@ const makeLocale_1 = tslib_1.__importDefault(require("./makeLocale"));
const makeRouter_1 = tslib_1.__importDefault(require("./makeRouter")); const makeRouter_1 = tslib_1.__importDefault(require("./makeRouter"));
const fs_1 = require("fs"); const fs_1 = require("fs");
async function build(cmd) { async function build(cmd) {
const mode = (cmd.mode || 'development');
const target = cmd.target;
if (!cmd.target) { if (!cmd.target) {
(0, tip_style_1.Error)(`${(0, tip_style_1.error)(`Please add --target web or --target mp(wechatMp) or --target rn(native) to run the project in Web/WechatMp/ReactNative environment`)}`); (0, tip_style_1.Error)(`${(0, tip_style_1.error)(`Please add --target web or --target mp(wechatMp) or --target rn(native) to run the project in Web/WechatMp/ReactNative environment`)}`);
return; return;
} }
let subdir = cmd.subDir; let subdir = cmd.subDir;
if (!subdir) { if (!subdir) {
subdir = ['mp', 'wechatMp'].includes(cmd.target) ? 'wechatMp' : (['native', 'rn'].includes(cmd.target) ? 'native' : 'web'); subdir = ['mp', 'wechatMp'].includes(target)
? 'wechatMp'
: ['native', 'rn'].includes(target)
? 'native'
: 'web';
} }
// 先makeLocale // 先makeLocale
(0, makeLocale_1.default)('', cmd.mode === 'development'); (0, makeLocale_1.default)('', mode === 'development');
// 再尝试makeRouter // 再尝试makeRouter
(0, makeRouter_1.default)({ subdir }, cmd.mode === 'development'); (0, makeRouter_1.default)({ subdir }, mode === 'development');
//ts类型检查 waring 还是error, //ts类型检查 waring 还是error,
//主要web受影响error级别的话 控制台和网页都报错warning级别的话 控制台报错 //主要web受影响error级别的话 控制台和网页都报错warning级别的话 控制台报错
// development/staging/production // development/staging/production
const TSC_COMPILE_ON_ERROR = cmd.check !== 'error'; const errorLevel = cmd.check !== 'error';
(0, tip_style_1.Success)(`${(0, tip_style_1.success)(`build ${cmd.target} environment:${cmd.mode} ${['development'].includes(cmd.mode) ? `server:${!!cmd.prod}` : ''} ${['mp', 'wechatMp'].includes(cmd.target) && (0, tip_style_1.Success)(`${(0, tip_style_1.success)(`build ${target} environment:${mode} ${['development'].includes(mode) ? `server:${!!cmd.prod}` : ''} ${['mp', 'wechatMp'].includes(target) &&
['development'].includes(cmd.mode) ['development'].includes(mode)
? `split:${!!cmd.split}` ? `split:${!!cmd.split}`
: ''}`)}`); : ''}`)}`);
if (['mp', 'wechatMp'].includes(cmd.target)) { if (['mp', 'wechatMp'].includes(target)) {
const mpFileMap = {
production: 'build-mp.js',
staging: 'build-staging-mp.js',
development: 'start-mp.js',
};
const result = cross_spawn_1.default.sync(`cross-env`, [ const result = cross_spawn_1.default.sync(`cross-env`, [
`NODE_ENV=${cmd.mode}`, `NODE_ENV=${mode}`,
`NODE_TARGET=${cmd.target}`, `NODE_TARGET=${target}`,
`SUB_DIR_NAME=${subdir}`, `SUB_DIR_NAME=${subdir}`,
`TSC_COMPILE_ON_ERROR=${TSC_COMPILE_ON_ERROR}`, `TSC_COMPILE_ON_ERROR=${errorLevel}`,
`COMPILE_ANALYZE=${!!cmd.analyze}`, `COMPILE_ANALYZE=${!!cmd.analyze}`,
`GENERATE_SOURCEMAP=${!!cmd.sourcemap}`, `GENERATE_SOURCEMAP=${!!cmd.sourcemap}`,
`PROD=${!!cmd.prod}`, `PROD=${!!cmd.prod}`,
@ -41,9 +52,7 @@ async function build(cmd) {
!!cmd.memoryLimit && `MEMORY_LIMIT=${cmd.memoryLimit}`, !!cmd.memoryLimit && `MEMORY_LIMIT=${cmd.memoryLimit}`,
`node`, `node`,
cmd.memoryLimit && `--max_old_space_size=${cmd.memoryLimit}`, cmd.memoryLimit && `--max_old_space_size=${cmd.memoryLimit}`,
require.resolve(`../scripts/${cmd.mode === 'production' (0, path_1.resolve)(__dirname, `../scripts/${mpFileMap[mode]}`),
? 'build-mp.js'
: 'start-mp.js'}`),
].filter(Boolean), { ].filter(Boolean), {
stdio: 'inherit', stdio: 'inherit',
shell: true, shell: true,
@ -55,21 +64,24 @@ async function build(cmd) {
(0, tip_style_1.Error)(`${(0, tip_style_1.error)(`执行失败`)}`); (0, tip_style_1.Error)(`${(0, tip_style_1.error)(`执行失败`)}`);
} }
} }
else if (cmd.target === 'web') { else if (target === 'web') {
const webFileMap = {
production: 'build-web.js',
staging: 'build-staging-web.js',
development: 'start-web.js',
};
const result = cross_spawn_1.default.sync(`cross-env`, [ const result = cross_spawn_1.default.sync(`cross-env`, [
`NODE_ENV=${cmd.mode}`, `NODE_ENV=${mode}`,
`NODE_TARGET=${cmd.target}`, `NODE_TARGET=${target}`,
`SUB_DIR_NAME=${subdir}`, `SUB_DIR_NAME=${subdir}`,
`TSC_COMPILE_ON_ERROR=${TSC_COMPILE_ON_ERROR}`, `TSC_COMPILE_ON_ERROR=${errorLevel}`,
`COMPILE_ANALYZE=${!!cmd.analyze}`, `COMPILE_ANALYZE=${!!cmd.analyze}`,
`GENERATE_SOURCEMAP=${!!cmd.sourcemap}`, `GENERATE_SOURCEMAP=${!!cmd.sourcemap}`,
`PROD=${!!cmd.prod}`, `PROD=${!!cmd.prod}`,
!!cmd.memoryLimit && `MEMORY_LIMIT=${cmd.memoryLimit}`, !!cmd.memoryLimit && `MEMORY_LIMIT=${cmd.memoryLimit}`,
`node`, `node`,
cmd.memoryLimit && `--max_old_space_size=${cmd.memoryLimit}`, cmd.memoryLimit && `--max_old_space_size=${cmd.memoryLimit}`,
require.resolve(`../scripts/${cmd.mode === 'production' (0, path_1.resolve)(__dirname, `../scripts/${webFileMap[mode]}`),
? 'build-web.js'
: 'start-web.js'}`),
].filter(Boolean), { ].filter(Boolean), {
stdio: 'inherit', stdio: 'inherit',
shell: true, shell: true,
@ -81,33 +93,52 @@ async function build(cmd) {
(0, tip_style_1.Error)(`${(0, tip_style_1.error)(`执行失败`)}`); (0, tip_style_1.Error)(`${(0, tip_style_1.error)(`执行失败`)}`);
} }
} }
else if (['native', 'rn'].includes(cmd.target)) { else if (['native', 'rn'].includes(target)) {
const prjDir = process.cwd(); const prjDir = process.cwd();
const cwd = (0, path_1.resolve)(prjDir, subdir); const cwd = (0, path_1.resolve)(prjDir, subdir);
(0, fs_1.copyFileSync)((0, path_1.resolve)(prjDir, 'package.json'), (0, path_1.resolve)(cwd, 'package.json')); (0, fs_1.copyFileSync)((0, path_1.resolve)(prjDir, 'package.json'), (0, path_1.resolve)(cwd, 'package.json'));
// rn不支持注入NODE_ENVIRONMENT这样的环境变量cross-env没有用 // rn不支持注入NODE_ENVIRONMENT这样的环境变量cross-env没有用
/* const result = spawn.sync( const platform = cmd.platform;
'react-native', let result;
[ if (mode === 'production') {
'start', //cd native/android && cross-env NODE_ENV=production ./gradlew assembleRelease
], result = cross_spawn_1.default.sync(`cd android`, [
{ '&& cross-env',
`NODE_ENV=${mode}`,
'OAK_PLATFORM=native',
'./gradlew assembleRelease',
].filter(Boolean), {
cwd, cwd,
stdio: 'inherit', stdio: 'inherit',
shell: true, shell: true,
} });
); */ }
const result = cross_spawn_1.default.sync(`cross-env`, [ else if (mode === 'staging') {
`NODE_ENV=${cmd.mode}`, //cd native/android && cross-env NODE_ENV=production ./gradlew assembleStaging
'OAK_PLATFORM=native', result = cross_spawn_1.default.sync(`cd android`, [
`PROD=${!!cmd.prod}`, '&& cross-env',
'react-native', `NODE_ENV=${mode}`,
'start', 'OAK_PLATFORM=native',
].filter(Boolean), { './gradlew assembleStaging',
cwd, ].filter(Boolean), {
stdio: 'inherit', cwd,
shell: true, stdio: 'inherit',
}); shell: true,
});
}
else {
result = cross_spawn_1.default.sync(`cross-env`, [
`NODE_ENV=${mode}`,
'OAK_PLATFORM=native',
`PROD=${!!cmd.prod}`,
'react-native',
'start',
].filter(Boolean), {
cwd,
stdio: 'inherit',
shell: true,
});
}
if (result.status === 0) { if (result.status === 0) {
(0, tip_style_1.Success)(`${(0, tip_style_1.success)(`执行完成`)}`); (0, tip_style_1.Success)(`${(0, tip_style_1.success)(`执行完成`)}`);
} }

1
lib/clean.d.ts vendored Normal file
View File

@ -0,0 +1 @@
export default function run(options: any): Promise<void>;

51
lib/clean.js Normal file
View File

@ -0,0 +1,51 @@
"use strict";
Object.defineProperty(exports, "__esModule", { value: true });
const tslib_1 = require("tslib");
const tip_style_1 = require("./tip-style");
const cross_spawn_1 = tslib_1.__importDefault(require("cross-spawn"));
const path_1 = require("path");
const fs_1 = require("fs");
async function run(options) {
const prjDir = process.cwd();
const cwd = (0, path_1.resolve)(process.cwd(), options.subDir || 'native');
const mode = options.mode || 'development'; //development/staging/production
if (options.platform === 'ios') {
(0, fs_1.copyFileSync)((0, path_1.resolve)(prjDir, 'package.json'), (0, path_1.resolve)(cwd, 'package.json'));
(0, tip_style_1.Success)(`${(0, tip_style_1.primary)('run react-native run-ios')}`);
const result = cross_spawn_1.default.sync('react-native', ['run-ios'], {
cwd,
stdio: 'inherit',
shell: true,
});
if (result.status === 0) {
(0, tip_style_1.Success)(`${(0, tip_style_1.success)(`react-native run-ios success`)}`);
}
else {
Error(`${(0, tip_style_1.error)('react-native run-ios fail')}`);
process.exit(-1);
}
}
else if (options.platform === 'android') {
(0, tip_style_1.Success)(`${(0, tip_style_1.primary)('run react-native run-android')}`);
(0, fs_1.copyFileSync)((0, path_1.resolve)(prjDir, 'package.json'), (0, path_1.resolve)(cwd, 'package.json'));
const result = cross_spawn_1.default.sync('cd android', [
'&& ./gradlew clean',
].filter(Boolean), {
cwd,
stdio: 'inherit',
shell: true,
});
if (result.status === 0) {
(0, tip_style_1.Success)(`${(0, tip_style_1.success)(`react-native run-android success`)}`);
}
else {
Error(`${(0, tip_style_1.error)('react-native run-android fail')}`);
process.exit(-1);
}
}
else {
Error((0, tip_style_1.error)(`unrecoganized platfrom: ${options.platform}`));
process.exit(-1);
}
}
exports.default = run;

View File

@ -8,6 +8,7 @@ const build_1 = tslib_1.__importDefault(require("./build"));
const makeDomain_1 = tslib_1.__importDefault(require("./makeDomain")); const makeDomain_1 = tslib_1.__importDefault(require("./makeDomain"));
const makeLocale_1 = tslib_1.__importDefault(require("./makeLocale")); const makeLocale_1 = tslib_1.__importDefault(require("./makeLocale"));
const run_1 = tslib_1.__importDefault(require("./run")); const run_1 = tslib_1.__importDefault(require("./run"));
const clean_1 = tslib_1.__importDefault(require("./clean"));
const config_1 = require("./config"); const config_1 = require("./config");
const tip_style_1 = require("./tip-style"); const tip_style_1 = require("./tip-style");
/** /**
@ -71,6 +72,7 @@ commander_1.default
.option('-m, --mode <mode>', 'mode') .option('-m, --mode <mode>', 'mode')
.option('-d, --subDir <subDirName>', 'subDirName') .option('-d, --subDir <subDirName>', 'subDirName')
.option('-c, --check <level>', 'level') .option('-c, --check <level>', 'level')
.option('-p, --platform <platform>', 'platform')
.description('build project of build on demand') .description('build project of build on demand')
.action(build_1.default); .action(build_1.default);
commander_1.default commander_1.default
@ -89,8 +91,15 @@ commander_1.default
.command('run') .command('run')
.option('-p, --platform <platform>', 'platform') .option('-p, --platform <platform>', 'platform')
.option('-d, --subDir <subDirName>', 'subDirName') .option('-d, --subDir <subDirName>', 'subDirName')
.option('-m, --mode <mode>', 'mode')
.description(`run backend server by ${config_1.CLI_NAME}`) .description(`run backend server by ${config_1.CLI_NAME}`)
.action(run_1.default); .action(run_1.default);
commander_1.default
.command('clean')
.option('-p, --platform <platform>', 'platform')
.option('-d, --subDir <subDirName>', 'subDirName')
.description(`clean rn build by ${config_1.CLI_NAME}`)
.action(clean_1.default);
// output help information on unknown commands // output help information on unknown commands
commander_1.default.arguments('<command>').action((cmd) => { commander_1.default.arguments('<command>').action((cmd) => {
commander_1.default.outputHelp(); commander_1.default.outputHelp();

View File

@ -3,10 +3,11 @@ Object.defineProperty(exports, "__esModule", { value: true });
const tslib_1 = require("tslib"); const tslib_1 = require("tslib");
const tip_style_1 = require("./tip-style"); const tip_style_1 = require("./tip-style");
const cross_spawn_1 = tslib_1.__importDefault(require("cross-spawn")); const cross_spawn_1 = tslib_1.__importDefault(require("cross-spawn"));
const path_1 = require("path");
async function make() { async function make() {
(0, tip_style_1.Success)(`${(0, tip_style_1.success)(`make oak-app-domain`)}`); (0, tip_style_1.Success)(`${(0, tip_style_1.success)(`make oak-app-domain`)}`);
// ts-node scripts/build-app-domain & npm link ./app-domain // ts-node scripts/build-app-domain & npm link ./app-domain
const result = cross_spawn_1.default.sync('ts-node', [require.resolve('../scripts/' + 'make-app-domain.js')], { const result = cross_spawn_1.default.sync('ts-node', [(0, path_1.resolve)(__dirname, '../scripts/make-app-domain.js')], {
stdio: 'inherit', stdio: 'inherit',
shell: true, shell: true,
}); });

View File

@ -3,10 +3,11 @@ Object.defineProperty(exports, "__esModule", { value: true });
const tslib_1 = require("tslib"); const tslib_1 = require("tslib");
const tip_style_1 = require("./tip-style"); const tip_style_1 = require("./tip-style");
const cross_spawn_1 = tslib_1.__importDefault(require("cross-spawn")); const cross_spawn_1 = tslib_1.__importDefault(require("cross-spawn"));
const path_1 = require("path");
async function make(cmd, watch) { async function make(cmd, watch) {
(0, tip_style_1.Success)(`${(0, tip_style_1.success)(`make locales`)}`); (0, tip_style_1.Success)(`${(0, tip_style_1.success)(`make locales`)}`);
// ts-node scripts/build-app-domain & npm link ./app-domain // ts-node scripts/build-app-domain & npm link ./app-domain
const args = [require.resolve('../scripts/' + 'make-locale.js')]; const args = [(0, path_1.resolve)(__dirname, '../scripts/make-locale.js')];
if (watch) { if (watch) {
args.push('true'); args.push('true');
} }

View File

@ -3,10 +3,11 @@ Object.defineProperty(exports, "__esModule", { value: true });
const tslib_1 = require("tslib"); const tslib_1 = require("tslib");
const tip_style_1 = require("./tip-style"); const tip_style_1 = require("./tip-style");
const cross_spawn_1 = tslib_1.__importDefault(require("cross-spawn")); const cross_spawn_1 = tslib_1.__importDefault(require("cross-spawn"));
const path_1 = require("path");
async function make(cmd, watch) { async function make(cmd, watch) {
(0, tip_style_1.Success)(`${(0, tip_style_1.success)(`make router`)}`); (0, tip_style_1.Success)(`${(0, tip_style_1.success)(`make router`)}`);
// node scripts/make-router.js subdir watch // node scripts/make-router.js subdir watch
const args = [require.resolve('../scripts/' + 'make-router.js'), cmd.subdir]; const args = [(0, path_1.resolve)(__dirname, '../scripts/make-router.js'), cmd.subdir];
if (watch) { if (watch) {
args.push('true'); args.push('true');
const result = (0, cross_spawn_1.default)('node', args, { const result = (0, cross_spawn_1.default)('node', args, {

View File

@ -8,6 +8,7 @@ const fs_1 = require("fs");
async function run(options) { async function run(options) {
const prjDir = process.cwd(); const prjDir = process.cwd();
const cwd = (0, path_1.resolve)(process.cwd(), options.subDir || 'native'); const cwd = (0, path_1.resolve)(process.cwd(), options.subDir || 'native');
const mode = options.mode || 'development'; //development/staging/production
if (options.platform === 'ios') { if (options.platform === 'ios') {
(0, fs_1.copyFileSync)((0, path_1.resolve)(prjDir, 'package.json'), (0, path_1.resolve)(cwd, 'package.json')); (0, fs_1.copyFileSync)((0, path_1.resolve)(prjDir, 'package.json'), (0, path_1.resolve)(cwd, 'package.json'));
(0, tip_style_1.Success)(`${(0, tip_style_1.primary)('run react-native run-ios')}`); (0, tip_style_1.Success)(`${(0, tip_style_1.primary)('run react-native run-ios')}`);
@ -27,7 +28,12 @@ async function run(options) {
else if (options.platform === 'android') { else if (options.platform === 'android') {
(0, tip_style_1.Success)(`${(0, tip_style_1.primary)('run react-native run-android')}`); (0, tip_style_1.Success)(`${(0, tip_style_1.primary)('run react-native run-android')}`);
(0, fs_1.copyFileSync)((0, path_1.resolve)(prjDir, 'package.json'), (0, path_1.resolve)(cwd, 'package.json')); (0, fs_1.copyFileSync)((0, path_1.resolve)(prjDir, 'package.json'), (0, path_1.resolve)(cwd, 'package.json'));
const result = cross_spawn_1.default.sync('react-native', ['run-android'], { const result = cross_spawn_1.default.sync('cross-env', [
`NODE_ENV=${mode}`,
'react-native',
'run-android',
mode === 'production' ? '--variant=release' : '',
].filter(Boolean), {
cwd, cwd,
stdio: 'inherit', stdio: 'inherit',
shell: true, shell: true,

View File

@ -53,12 +53,16 @@ function packageJsonContent({ name, version, description, cliName, cliBinName, i
"copy-config-json": "copyfiles -u 1 src/config/*.json lib/", "copy-config-json": "copyfiles -u 1 src/config/*.json lib/",
"start:mp": "${cliBinName} start --target mp --mode development", "start:mp": "${cliBinName} start --target mp --mode development",
"start:mp:prod": "${cliBinName} start --target mp --mode development --prod", "start:mp:prod": "${cliBinName} start --target mp --mode development --prod",
"build:mp:staging": "${cliBinName} build --target mp --mode staging",
"build-analyze:mp:staging": "${cliBinName} build --target mp --mode staging --analyze",
"build:mp": "${cliBinName} build --target mp --mode production", "build:mp": "${cliBinName} build --target mp --mode production",
"build-analyze:mp": "${cliBinName} build --target mp --mode production --analyze", "build-analyze:mp": "${cliBinName} build --target mp --mode production --analyze",
"start:web": "${cliBinName} start --target web --mode development", "start:web": "${cliBinName} start --target web --mode development",
"start:web:prod": "${cliBinName} start --target web --mode development --prod", "start:web:prod": "${cliBinName} start --target web --mode development --prod",
"start:native": "${cliBinName} start --target rn --mode development", "start:native": "${cliBinName} start --target rn --mode development",
"start:native:prod": "${cliBinName} start --target rn --mode development --prod", "start:native:prod": "${cliBinName} start --target rn --mode development --prod",
"build:web:staging": "${cliBinName} build --target web --mode staging",
"build-analyze:web:staging": "${cliBinName} build --target web --mode staging --analyze",
"build:web": "${cliBinName} build --target web --mode production", "build:web": "${cliBinName} build --target web --mode production",
"build-analyze:web": "${cliBinName} build --target web --mode production --analyze", "build-analyze:web": "${cliBinName} build --target web --mode production --analyze",
"build-sourcemap-analyze:web": "${cliBinName} build --target web --mode production --sourcemap --analyze", "build-sourcemap-analyze:web": "${cliBinName} build --target web --mode production --sourcemap --analyze",

View File

@ -0,0 +1,92 @@
'use strict';
const { ProvidePlugin } = require('webpack');
const filterObject = require('filter-obj');
function createAliasFilter({ includeAliases, excludeAliases }) {
if (includeAliases.length > 0) {
return (object) =>
filterObject(object, (key) => includeAliases.includes(key));
}
return (object) =>
filterObject(object, (key) => !excludeAliases.includes(key));
}
module.exports = class NodePolyfillPlugin {
constructor(options = {}) {
this.options = {
excludeAliases: [],
includeAliases: [],
...options,
};
if (
this.options.includeAliases.length > 0 &&
this.options.excludeAliases.length > 0
) {
throw new Error(
'excludeAliases and includeAliases are mutually exclusive'
);
}
}
apply(compiler) {
const filter = createAliasFilter(this.options);
compiler.options.plugins.push(
new ProvidePlugin(
filter({
Buffer: [require.resolve('buffer/'), 'Buffer'],
console: require.resolve('console-browserify'),
process: require.resolve('process/browser'),
})
)
);
compiler.options.resolve.fallback = {
...filter({
assert: require.resolve('assert/'),
buffer: require.resolve('buffer/'),
console: require.resolve('console-browserify'),
constants: require.resolve('constants-browserify'),
crypto: require.resolve('crypto-browserify'),
domain: require.resolve('domain-browser'),
events: require.resolve('events/'),
http: require.resolve('stream-http'),
https: require.resolve('https-browserify'),
os: require.resolve('os-browserify/browser'),
path: require.resolve('path-browserify'),
punycode: require.resolve('punycode/'),
process: require.resolve('process/browser'),
querystring: require.resolve('querystring-es3'),
stream: require.resolve('stream-browserify'),
/* eslint-disable camelcase */
_stream_duplex: require.resolve(
'readable-stream/lib/_stream_duplex'
),
_stream_passthrough: require.resolve(
'readable-stream/lib/_stream_passthrough'
),
_stream_readable: require.resolve(
'readable-stream/lib/_stream_readable'
),
_stream_transform: require.resolve(
'readable-stream/lib/_stream_transform'
),
_stream_writable: require.resolve(
'readable-stream/lib/_stream_writable'
),
string_decoder: require.resolve('string_decoder/'),
/* eslint-enable camelcase */
sys: require.resolve('util/'),
timers: require.resolve('timers-browserify'),
tty: require.resolve('tty-browserify'),
url: require.resolve('url/'),
util: require.resolve('util/'),
vm: require.resolve('vm-browserify'),
zlib: require.resolve('browserify-zlib'),
}),
...compiler.options.resolve.fallback,
};
}
};

View File

@ -1,3 +1,6 @@
process.env.BABEL_ENV = 'production';
process.env.NODE_ENV = 'production';
require('../config/mp/env'); require('../config/mp/env');
const webpack = require('webpack'); const webpack = require('webpack');

View File

@ -0,0 +1,35 @@
process.env.BABEL_ENV = 'production';
process.env.NODE_ENV = 'staging';
require('../config/mp/env');
const webpack = require('webpack');
const chalk = require('chalk');
const fs = require('fs-extra');
const configFactory = require('../config/mp/webpack.config');
const config = configFactory('production');
const paths = require('../config/mp/paths');
const getClientEnvironment = require('../config/mp/env');
const env = getClientEnvironment();
fs.emptyDirSync(paths.appBuild);
webpack(config, (err, stats) => {
if (err) {
console.log(chalk.red(err.stack || err));
if (err.details) {
console.log(chalk.red(err.details));
}
return undefined;
}
if (stats) {
const info = stats.toJson();
if (stats.hasErrors()) {
info.errors.forEach((ele) => console.warn(ele));
}
if (stats.hasWarnings()) {
info.warnings.forEach((ele) => console.warn(ele));
}
}
});

View File

@ -0,0 +1,217 @@
'use strict';
// Do this as the first thing so that any code reading it knows the right env.
process.env.BABEL_ENV = 'production';
process.env.NODE_ENV = 'staging';
// Makes the script crash on unhandled rejections instead of silently
// ignoring them. In the future, promise rejections that are not handled will
// terminate the Node.js process with a non-zero exit code.
process.on('unhandledRejection', err => {
throw err;
});
// Ensure environment variables are read.
require('../config/web/env');
const path = require('path');
const chalk = require('react-dev-utils/chalk');
const fs = require('fs-extra');
const bfj = require('bfj');
const webpack = require('webpack');
const configFactory = require('../config/web/webpack.config');
const paths = require('../config/web/paths');
const checkRequiredFiles = require('react-dev-utils/checkRequiredFiles');
const formatWebpackMessages = require('react-dev-utils/formatWebpackMessages');
const printHostingInstructions = require('react-dev-utils/printHostingInstructions');
const FileSizeReporter = require('react-dev-utils/FileSizeReporter');
const printBuildError = require('react-dev-utils/printBuildError');
const measureFileSizesBeforeBuild =
FileSizeReporter.measureFileSizesBeforeBuild;
const printFileSizesAfterBuild = FileSizeReporter.printFileSizesAfterBuild;
const useYarn = fs.existsSync(paths.yarnLockFile);
// These sizes are pretty large. We'll warn for bundles exceeding them.
const WARN_AFTER_BUNDLE_GZIP_SIZE = 512 * 1024;
const WARN_AFTER_CHUNK_GZIP_SIZE = 1024 * 1024;
const isInteractive = process.stdout.isTTY;
// Warn and crash if required files are missing
if (!checkRequiredFiles([paths.appHtml, paths.appIndexJs])) {
process.exit(1);
}
const argv = process.argv.slice(2);
const writeStatsJson = argv.indexOf('--stats') !== -1;
// Generate configuration
const config = configFactory('production');
// We require that you explicitly set browsers and do not fall back to
// browserslist defaults.
const { checkBrowsers } = require('react-dev-utils/browsersHelper');
checkBrowsers(paths.appPath, isInteractive)
.then(() => {
// First, read the current file sizes in build directory.
// This lets us display how much they changed later.
return measureFileSizesBeforeBuild(paths.appBuild);
})
.then(previousFileSizes => {
// Remove all content but keep the directory so that
// if you're in it, you don't end up in Trash
fs.emptyDirSync(paths.appBuild);
// Merge with the public folder
copyPublicFolder();
// Start the webpack build
return build(previousFileSizes);
})
.then(
({ stats, previousFileSizes, warnings }) => {
if (warnings.length) {
console.log(chalk.yellow('Compiled with warnings.\n'));
console.log(warnings.join('\n\n'));
console.log(
'\nSearch for the ' +
chalk.underline(chalk.yellow('keywords')) +
' to learn more about each warning.'
);
console.log(
'To ignore, add ' +
chalk.cyan('// eslint-disable-next-line') +
' to the line before.\n'
);
} else {
console.log(chalk.green('Compiled successfully.\n'));
}
console.log('File sizes after gzip:\n');
printFileSizesAfterBuild(
stats,
previousFileSizes,
paths.appBuild,
WARN_AFTER_BUNDLE_GZIP_SIZE,
WARN_AFTER_CHUNK_GZIP_SIZE
);
console.log();
const appPackage = require(paths.appPackageJson);
const publicUrl = paths.publicUrlOrPath;
const publicPath = config.output.publicPath;
const buildFolder = path.relative(process.cwd(), paths.appBuild);
printHostingInstructions(
appPackage,
publicUrl,
publicPath,
buildFolder,
useYarn
);
},
err => {
const tscCompileOnError = process.env.TSC_COMPILE_ON_ERROR === 'true';
if (tscCompileOnError) {
console.log(
chalk.yellow(
'Compiled with the following type errors (you may want to check these before deploying your app):\n'
)
);
printBuildError(err);
} else {
console.log(chalk.red('Failed to compile.\n'));
printBuildError(err);
process.exit(1);
}
}
)
.catch(err => {
if (err && err.message) {
console.log(err.message);
}
process.exit(1);
});
// Create the production build and print the deployment instructions.
function build(previousFileSizes) {
console.log('Creating an optimized production build...');
const compiler = webpack(config);
return new Promise((resolve, reject) => {
compiler.run((err, stats) => {
let messages;
if (err) {
if (!err.message) {
return reject(err);
}
let errMessage = err.message;
// Add additional information for postcss errors
if (Object.prototype.hasOwnProperty.call(err, 'postcssNode')) {
errMessage +=
'\nCompileError: Begins at CSS selector ' +
err['postcssNode'].selector;
}
messages = formatWebpackMessages({
errors: [errMessage],
warnings: [],
});
} else {
messages = formatWebpackMessages(
stats.toJson({ all: false, warnings: true, errors: true })
);
}
if (messages.errors.length) {
// Only keep the first error. Others are often indicative
// of the same problem, but confuse the reader with noise.
if (messages.errors.length > 1) {
messages.errors.length = 1;
}
return reject(new Error(messages.errors.join('\n\n')));
}
if (
process.env.CI &&
(typeof process.env.CI !== 'string' ||
process.env.CI.toLowerCase() !== 'false') &&
messages.warnings.length
) {
// Ignore sourcemap warnings in CI builds. See #8227 for more info.
const filteredWarnings = messages.warnings.filter(
w => !/Failed to parse source map/.test(w)
);
if (filteredWarnings.length) {
console.log(
chalk.yellow(
'\nTreating warnings as errors because process.env.CI = true.\n' +
'Most CI servers set it automatically.\n'
)
);
return reject(new Error(filteredWarnings.join('\n\n')));
}
}
const resolveArgs = {
stats,
previousFileSizes,
warnings: messages.warnings,
};
if (writeStatsJson) {
return bfj
.write(paths.appBuild + '/bundle-stats.json', stats.toJson())
.then(() => resolve(resolveArgs))
.catch(error => reject(new Error(error)));
}
return resolve(resolveArgs);
});
});
}
function copyPublicFolder() {
fs.copySync(paths.appPublic, paths.appBuild, {
dereference: true,
filter: (file) => file !== paths.appHtml,
});
}

View File

@ -13,7 +13,12 @@ import makeLocale from './makeLocale';
import makeRouter from './makeRouter'; import makeRouter from './makeRouter';
import { copyFileSync } from 'fs'; import { copyFileSync } from 'fs';
type Mode = 'development' | 'staging' | 'production';
type Target = 'mp' | 'wechatMp' | 'web' | 'rn' | 'native';
export default async function build(cmd: any) { export default async function build(cmd: any) {
const mode = (cmd.mode || 'development') as Mode;
const target = cmd.target as Target;
if (!cmd.target) { if (!cmd.target) {
Error( Error(
`${error( `${error(
@ -24,38 +29,45 @@ export default async function build(cmd: any) {
} }
let subdir = cmd.subDir; let subdir = cmd.subDir;
if (!subdir) { if (!subdir) {
subdir = ['mp', 'wechatMp'].includes(cmd.target) ? 'wechatMp' : ( subdir = ['mp', 'wechatMp'].includes(target)
['native', 'rn'].includes(cmd.target) ? 'native' : 'web' ? 'wechatMp'
); : ['native', 'rn'].includes(target)
? 'native'
: 'web';
} }
// 先makeLocale // 先makeLocale
makeLocale('', cmd.mode === 'development'); makeLocale('', mode === 'development');
// 再尝试makeRouter // 再尝试makeRouter
makeRouter({ subdir }, cmd.mode === 'development'); makeRouter({ subdir }, mode === 'development');
//ts类型检查 waring 还是error, //ts类型检查 waring 还是error,
//主要web受影响error级别的话 控制台和网页都报错warning级别的话 控制台报错 //主要web受影响error级别的话 控制台和网页都报错warning级别的话 控制台报错
// development/staging/production // development/staging/production
const TSC_COMPILE_ON_ERROR = cmd.check !== 'error'; const errorLevel = cmd.check !== 'error';
Success( Success(
`${success( `${success(
`build ${cmd.target} environment:${cmd.mode} ${ `build ${target} environment:${mode} ${
['development'].includes(cmd.mode) ? `server:${!!cmd.prod}` : '' ['development'].includes(mode) ? `server:${!!cmd.prod}` : ''
} ${ } ${
['mp', 'wechatMp'].includes(cmd.target) && ['mp', 'wechatMp'].includes(target) &&
['development'].includes(cmd.mode) ['development'].includes(mode)
? `split:${!!cmd.split}` ? `split:${!!cmd.split}`
: '' : ''
}` }`
)}` )}`
); );
if (['mp', 'wechatMp'].includes(cmd.target)) { if (['mp', 'wechatMp'].includes(target)) {
const mpFileMap = {
production: 'build-mp.js',
staging: 'build-staging-mp.js',
development: 'start-mp.js',
};
const result = spawn.sync( const result = spawn.sync(
`cross-env`, `cross-env`,
[ [
`NODE_ENV=${cmd.mode}`, `NODE_ENV=${mode}`,
`NODE_TARGET=${cmd.target}`, `NODE_TARGET=${target}`,
`SUB_DIR_NAME=${subdir}`, `SUB_DIR_NAME=${subdir}`,
`TSC_COMPILE_ON_ERROR=${TSC_COMPILE_ON_ERROR}`, `TSC_COMPILE_ON_ERROR=${errorLevel}`,
`COMPILE_ANALYZE=${!!cmd.analyze}`, `COMPILE_ANALYZE=${!!cmd.analyze}`,
`GENERATE_SOURCEMAP=${!!cmd.sourcemap}`, `GENERATE_SOURCEMAP=${!!cmd.sourcemap}`,
`PROD=${!!cmd.prod}`, `PROD=${!!cmd.prod}`,
@ -63,13 +75,7 @@ export default async function build(cmd: any) {
!!cmd.memoryLimit && `MEMORY_LIMIT=${cmd.memoryLimit}`, !!cmd.memoryLimit && `MEMORY_LIMIT=${cmd.memoryLimit}`,
`node`, `node`,
cmd.memoryLimit && `--max_old_space_size=${cmd.memoryLimit}`, cmd.memoryLimit && `--max_old_space_size=${cmd.memoryLimit}`,
require.resolve( resolve(__dirname, `../scripts/${mpFileMap[mode]}`),
`../scripts/${
cmd.mode === 'production'
? 'build-mp.js'
: 'start-mp.js'
}`
),
].filter(Boolean), ].filter(Boolean),
{ {
stdio: 'inherit', stdio: 'inherit',
@ -81,27 +87,26 @@ export default async function build(cmd: any) {
} else { } else {
Error(`${error(`执行失败`)}`); Error(`${error(`执行失败`)}`);
} }
} else if (cmd.target === 'web') { } else if (target === 'web') {
const webFileMap = {
production: 'build-web.js',
staging: 'build-staging-web.js',
development: 'start-web.js',
};
const result = spawn.sync( const result = spawn.sync(
`cross-env`, `cross-env`,
[ [
`NODE_ENV=${cmd.mode}`, `NODE_ENV=${mode}`,
`NODE_TARGET=${cmd.target}`, `NODE_TARGET=${target}`,
`SUB_DIR_NAME=${subdir}`, `SUB_DIR_NAME=${subdir}`,
`TSC_COMPILE_ON_ERROR=${TSC_COMPILE_ON_ERROR}`, `TSC_COMPILE_ON_ERROR=${errorLevel}`,
`COMPILE_ANALYZE=${!!cmd.analyze}`, `COMPILE_ANALYZE=${!!cmd.analyze}`,
`GENERATE_SOURCEMAP=${!!cmd.sourcemap}`, `GENERATE_SOURCEMAP=${!!cmd.sourcemap}`,
`PROD=${!!cmd.prod}`, `PROD=${!!cmd.prod}`,
!!cmd.memoryLimit && `MEMORY_LIMIT=${cmd.memoryLimit}`, !!cmd.memoryLimit && `MEMORY_LIMIT=${cmd.memoryLimit}`,
`node`, `node`,
cmd.memoryLimit && `--max_old_space_size=${cmd.memoryLimit}`, cmd.memoryLimit && `--max_old_space_size=${cmd.memoryLimit}`,
require.resolve( resolve(__dirname, `../scripts/${webFileMap[mode]}`),
`../scripts/${
cmd.mode === 'production'
? 'build-web.js'
: 'start-web.js'
}`
),
].filter(Boolean), ].filter(Boolean),
{ {
stdio: 'inherit', stdio: 'inherit',
@ -113,7 +118,7 @@ export default async function build(cmd: any) {
} else { } else {
Error(`${error(`执行失败`)}`); Error(`${error(`执行失败`)}`);
} }
} else if (['native', 'rn'].includes(cmd.target)) { } else if (['native', 'rn'].includes(target)) {
const prjDir = process.cwd(); const prjDir = process.cwd();
const cwd = resolve(prjDir, subdir); const cwd = resolve(prjDir, subdir);
copyFileSync( copyFileSync(
@ -121,32 +126,58 @@ export default async function build(cmd: any) {
resolve(cwd, 'package.json') resolve(cwd, 'package.json')
); );
// rn不支持注入NODE_ENVIRONMENT这样的环境变量cross-env没有用 // rn不支持注入NODE_ENVIRONMENT这样的环境变量cross-env没有用
/* const result = spawn.sync( const platform = cmd.platform as 'ios' | 'android';
'react-native', let result;
[ if (mode === 'production') {
'start', //cd native/android && cross-env NODE_ENV=production ./gradlew assembleRelease
], result = spawn.sync(
{ `cd android`,
cwd, [
stdio: 'inherit', '&& cross-env',
shell: true, `NODE_ENV=${mode}`,
} 'OAK_PLATFORM=native',
); */ './gradlew assembleRelease',
const result = spawn.sync( ].filter(Boolean),
`cross-env`, {
[ cwd,
`NODE_ENV=${cmd.mode}`, stdio: 'inherit',
'OAK_PLATFORM=native', shell: true,
`PROD=${!!cmd.prod}`, }
'react-native', );
'start', } else if (mode === 'staging') {
].filter(Boolean), //cd native/android && cross-env NODE_ENV=production ./gradlew assembleStaging
{ result = spawn.sync(
cwd, `cd android`,
stdio: 'inherit', [
shell: true, '&& cross-env',
} `NODE_ENV=${mode}`,
); 'OAK_PLATFORM=native',
'./gradlew assembleStaging',
].filter(Boolean),
{
cwd,
stdio: 'inherit',
shell: true,
}
);
} else {
result = spawn.sync(
`cross-env`,
[
`NODE_ENV=${mode}`,
'OAK_PLATFORM=native',
`PROD=${!!cmd.prod}`,
'react-native',
'start',
].filter(Boolean),
{
cwd,
stdio: 'inherit',
shell: true,
}
);
}
if (result.status === 0) { if (result.status === 0) {
Success(`${success(`执行完成`)}`); Success(`${success(`执行完成`)}`);
} else { } else {

66
src/clean.ts Normal file
View File

@ -0,0 +1,66 @@
import {
Success,
error,
primary,
success,
warn,
Warn,
} from './tip-style';
import spawn from 'cross-spawn';
import { resolve } from 'path';
import { copyFileSync, unlinkSync } from 'fs';
export default async function run(options: any): Promise<void> {
const prjDir = process.cwd();
const cwd = resolve(process.cwd(), options.subDir || 'native');
const mode = options.mode || 'development'; //development/staging/production
if (options.platform === 'ios') {
copyFileSync(resolve(prjDir, 'package.json'), resolve(cwd, 'package.json'));
Success(`${primary('run react-native run-ios')}`);
const result = spawn.sync(
'react-native',
['run-ios'],
{
cwd,
stdio: 'inherit',
shell: true,
}
);
if (result.status === 0) {
Success(`${success(`react-native run-ios success`)}`);
} else {
Error(`${error('react-native run-ios fail')}`);
process.exit(-1);
}
}
else if (options.platform === 'android') {
Success(`${primary('run react-native run-android')}`);
copyFileSync(
resolve(prjDir, 'package.json'),
resolve(cwd, 'package.json')
);
const result = spawn.sync(
'cd android',
[
'&& ./gradlew clean',
].filter(Boolean),
{
cwd,
stdio: 'inherit',
shell: true,
}
);
if (result.status === 0) {
Success(`${success(`react-native run-android success`)}`);
} else {
Error(`${error('react-native run-android fail')}`);
process.exit(-1);
}
}
else {
Error(error(`unrecoganized platfrom: ${options.platform}`));
process.exit(-1);
}
}

View File

@ -5,6 +5,7 @@ import build from './build';
import makeDomain from './makeDomain'; import makeDomain from './makeDomain';
import makeLocale from './makeLocale'; import makeLocale from './makeLocale';
import run from './run'; import run from './run';
import clean from './clean';
import { CLI_VERSION, CLI_NAME } from './config'; import { CLI_VERSION, CLI_NAME } from './config';
import { error, warn } from './tip-style'; import { error, warn } from './tip-style';
@ -77,6 +78,7 @@ program
.option('-m, --mode <mode>', 'mode') .option('-m, --mode <mode>', 'mode')
.option('-d, --subDir <subDirName>', 'subDirName') .option('-d, --subDir <subDirName>', 'subDirName')
.option('-c, --check <level>', 'level') .option('-c, --check <level>', 'level')
.option('-p, --platform <platform>', 'platform')
.description('build project of build on demand') .description('build project of build on demand')
.action(build); .action(build);
program program
@ -95,8 +97,15 @@ program
.command('run') .command('run')
.option('-p, --platform <platform>', 'platform') .option('-p, --platform <platform>', 'platform')
.option('-d, --subDir <subDirName>', 'subDirName') .option('-d, --subDir <subDirName>', 'subDirName')
.option('-m, --mode <mode>', 'mode')
.description(`run backend server by ${CLI_NAME}`) .description(`run backend server by ${CLI_NAME}`)
.action(run); .action(run);
program
.command('clean')
.option('-p, --platform <platform>', 'platform')
.option('-d, --subDir <subDirName>', 'subDirName')
.description(`clean rn build by ${CLI_NAME}`)
.action(clean);
// output help information on unknown commands // output help information on unknown commands
program.arguments('<command>').action((cmd) => { program.arguments('<command>').action((cmd) => {

View File

@ -8,13 +8,14 @@ import {
Warn, Warn,
} from './tip-style'; } from './tip-style';
import spawn from 'cross-spawn'; import spawn from 'cross-spawn';
import { resolve } from 'path';
export default async function make() { export default async function make() {
Success(`${success(`make oak-app-domain`)}`); Success(`${success(`make oak-app-domain`)}`);
// ts-node scripts/build-app-domain & npm link ./app-domain // ts-node scripts/build-app-domain & npm link ./app-domain
const result = spawn.sync( const result = spawn.sync(
'ts-node', 'ts-node',
[require.resolve('../scripts/' + 'make-app-domain.js')], [resolve(__dirname, '../scripts/make-app-domain.js')],
{ {
stdio: 'inherit', stdio: 'inherit',
shell: true, shell: true,

View File

@ -8,11 +8,12 @@ import {
Warn, Warn,
} from './tip-style'; } from './tip-style';
import spawn from 'cross-spawn'; import spawn from 'cross-spawn';
import { resolve } from 'path';
export default async function make(cmd: any, watch?: boolean) { export default async function make(cmd: any, watch?: boolean) {
Success(`${success(`make locales`)}`); Success(`${success(`make locales`)}`);
// ts-node scripts/build-app-domain & npm link ./app-domain // ts-node scripts/build-app-domain & npm link ./app-domain
const args = [require.resolve('../scripts/' + 'make-locale.js')]; const args = [resolve(__dirname, '../scripts/make-locale.js')];
if (watch) { if (watch) {
args.push('true'); args.push('true');
} }

View File

@ -8,11 +8,12 @@ import {
Warn, Warn,
} from './tip-style'; } from './tip-style';
import spawn from 'cross-spawn'; import spawn from 'cross-spawn';
import { resolve } from 'path';
export default async function make(cmd: any, watch?: boolean) { export default async function make(cmd: any, watch?: boolean) {
Success(`${success(`make router`)}`); Success(`${success(`make router`)}`);
// node scripts/make-router.js subdir watch // node scripts/make-router.js subdir watch
const args = [require.resolve('../scripts/' + 'make-router.js'), cmd.subdir]; const args = [resolve(__dirname, '../scripts/make-router.js'), cmd.subdir];
if (watch) { if (watch) {
args.push('true'); args.push('true');
const result = spawn( const result = spawn(

View File

@ -13,6 +13,7 @@ import { copyFileSync, unlinkSync } from 'fs';
export default async function run(options: any): Promise<void> { export default async function run(options: any): Promise<void> {
const prjDir = process.cwd(); const prjDir = process.cwd();
const cwd = resolve(process.cwd(), options.subDir || 'native'); const cwd = resolve(process.cwd(), options.subDir || 'native');
const mode = options.mode || 'development'; //development/staging/production
if (options.platform === 'ios') { if (options.platform === 'ios') {
copyFileSync(resolve(prjDir, 'package.json'), resolve(cwd, 'package.json')); copyFileSync(resolve(prjDir, 'package.json'), resolve(cwd, 'package.json'));
Success(`${primary('run react-native run-ios')}`); Success(`${primary('run react-native run-ios')}`);
@ -37,8 +38,13 @@ export default async function run(options: any): Promise<void> {
Success(`${primary('run react-native run-android')}`); Success(`${primary('run react-native run-android')}`);
copyFileSync(resolve(prjDir, 'package.json'), resolve(cwd, 'package.json')); copyFileSync(resolve(prjDir, 'package.json'), resolve(cwd, 'package.json'));
const result = spawn.sync( const result = spawn.sync(
'react-native', 'cross-env',
['run-android'], [
`NODE_ENV=${mode}`,
'react-native',
'run-android',
mode === 'production' ? '--variant=release' : '',
].filter(Boolean),
{ {
cwd, cwd,
stdio: 'inherit', stdio: 'inherit',

View File

@ -62,12 +62,16 @@ export function packageJsonContent({
"copy-config-json": "copyfiles -u 1 src/config/*.json lib/", "copy-config-json": "copyfiles -u 1 src/config/*.json lib/",
"start:mp": "${cliBinName} start --target mp --mode development", "start:mp": "${cliBinName} start --target mp --mode development",
"start:mp:prod": "${cliBinName} start --target mp --mode development --prod", "start:mp:prod": "${cliBinName} start --target mp --mode development --prod",
"build:mp:staging": "${cliBinName} build --target mp --mode staging",
"build-analyze:mp:staging": "${cliBinName} build --target mp --mode staging --analyze",
"build:mp": "${cliBinName} build --target mp --mode production", "build:mp": "${cliBinName} build --target mp --mode production",
"build-analyze:mp": "${cliBinName} build --target mp --mode production --analyze", "build-analyze:mp": "${cliBinName} build --target mp --mode production --analyze",
"start:web": "${cliBinName} start --target web --mode development", "start:web": "${cliBinName} start --target web --mode development",
"start:web:prod": "${cliBinName} start --target web --mode development --prod", "start:web:prod": "${cliBinName} start --target web --mode development --prod",
"start:native": "${cliBinName} start --target rn --mode development", "start:native": "${cliBinName} start --target rn --mode development",
"start:native:prod": "${cliBinName} start --target rn --mode development --prod", "start:native:prod": "${cliBinName} start --target rn --mode development --prod",
"build:web:staging": "${cliBinName} build --target web --mode staging",
"build-analyze:web:staging": "${cliBinName} build --target web --mode staging --analyze",
"build:web": "${cliBinName} build --target web --mode production", "build:web": "${cliBinName} build --target web --mode production",
"build-analyze:web": "${cliBinName} build --target web --mode production --analyze", "build-analyze:web": "${cliBinName} build --target web --mode production --analyze",
"build-sourcemap-analyze:web": "${cliBinName} build --target web --mode production --sourcemap --analyze", "build-sourcemap-analyze:web": "${cliBinName} build --target web --mode production --sourcemap --analyze",