@omni-door/cli
Version:
A tool set for set up the standard JS project
470 lines (469 loc) • 29.7 kB
JavaScript
"use strict";
var __awaiter = (this && this.__awaiter) || function (thisArg, _arguments, P, generator) {
function adopt(value) { return value instanceof P ? value : new P(function (resolve) { resolve(value); }); }
return new (P || (P = Promise))(function (resolve, reject) {
function fulfilled(value) { try { step(generator.next(value)); } catch (e) { reject(e); } }
function rejected(value) { try { step(generator["throw"](value)); } catch (e) { reject(e); } }
function step(result) { result.done ? resolve(result.value) : adopt(result.value).then(fulfilled, rejected); }
step((generator = generator.apply(thisArg, _arguments || [])).next());
});
};
var __generator = (this && this.__generator) || function (thisArg, body) {
var _ = { label: 0, sent: function() { if (t[0] & 1) throw t[1]; return t[1]; }, trys: [], ops: [] }, f, y, t, g;
return g = { next: verb(0), "throw": verb(1), "return": verb(2) }, typeof Symbol === "function" && (g[Symbol.iterator] = function() { return this; }), g;
function verb(n) { return function (v) { return step([n, v]); }; }
function step(op) {
if (f) throw new TypeError("Generator is already executing.");
while (_) try {
if (f = 1, y && (t = op[0] & 2 ? y["return"] : op[0] ? y["throw"] || ((t = y["return"]) && t.call(y), 0) : y.next) && !(t = t.call(y, op[1])).done) return t;
if (y = 0, t) op = [op[0] & 2, t.value];
switch (op[0]) {
case 0: case 1: t = op; break;
case 4: _.label++; return { value: op[1], done: false };
case 5: _.label++; y = op[1]; op = [0]; continue;
case 7: op = _.ops.pop(); _.trys.pop(); continue;
default:
if (!(t = _.trys, t = t.length > 0 && t[t.length - 1]) && (op[0] === 6 || op[0] === 2)) { _ = 0; continue; }
if (op[0] === 3 && (!t || (op[1] > t[0] && op[1] < t[3]))) { _.label = op[1]; break; }
if (op[0] === 6 && _.label < t[1]) { _.label = t[1]; t = op; break; }
if (t && _.label < t[2]) { _.label = t[2]; _.ops.push(op); break; }
if (t[2]) _.ops.pop();
_.trys.pop(); continue;
}
op = body.call(thisArg, _);
} catch (e) { op = [6, e]; y = 0; } finally { f = t = 0; }
if (op[0] & 5) throw op[1]; return { value: op[0] ? op[1] : void 0, done: true };
}
};
var __importDefault = (this && this.__importDefault) || function (mod) {
return (mod && mod.__esModule) ? mod : { "default": mod };
};
Object.defineProperty(exports, "__esModule", { value: true });
var fs_1 = __importDefault(require("fs"));
var path_1 = __importDefault(require("path"));
var child_process_1 = require("child_process");
var fs_extra_1 = __importDefault(require("fs-extra"));
var inquirer_1 = __importDefault(require("inquirer"));
var del_1 = __importDefault(require("del"));
var rollup_1 = __importDefault(require("./rollup"));
var webpack_1 = __importDefault(require("./webpack"));
var gulp_1 = __importDefault(require("./gulp"));
var utils_1 = require("@omni-door/utils");
var utils_2 = require("../../utils");
var dependencies_build_1 = __importDefault(require("./dependencies_build"));
var release_1 = __importDefault(require("../release"));
function default_1(config, buildTactic, autoBuild) {
return __awaiter(this, void 0, void 0, function () {
function handleBuildSuc(msg) {
msg = msg || 'Building completed(构建成功)!';
return function (isExit) {
utils_1.logCongrat(msg);
isExit && process.exit(0);
};
}
function handleBuildErr(msg) {
msg = msg || 'Building failed(构建失败)!';
return function (err) {
err && utils_1.logErr(err);
msg && utils_1.logErr(msg);
type !== 'toolkit' && utils_1.spinner.state('fail');
process.exit(1);
};
}
function installDenpendencies(build) {
var _this = this;
return inquirer_1.default.prompt([
{
name: 'install',
type: 'confirm',
message: utils_2.logo() + " Automatic install dependencies(\u81EA\u52A8\u5B89\u88C5\u6240\u9700\u8981\u7684\u4F9D\u8D56)?",
default: true
}
]).then(function (answers) { return __awaiter(_this, void 0, void 0, function () {
var install, dependencies, iTool;
return __generator(this, function (_a) {
switch (_a.label) {
case 0:
install = answers.install;
if (!install) return [3 /*break*/, 2];
return [4 /*yield*/, dependencies_build_1.default({ build: build, project_type: type })];
case 1:
dependencies = _a.sent();
iTool = 'pnpm i --save-dev';
try {
child_process_1.execSync('pnpm -v', { stdio: 'ignore' });
}
catch (e) {
iTool = 'yarn add -D';
try {
child_process_1.execSync('yarn -v', { stdio: 'ignore' });
}
catch (e) {
iTool = 'npm i --save-dev';
}
}
return [2 /*return*/, utils_1.exec([
iTool + " " + dependencies
], function () {
utils_1.logSuc('The dependencies install completed');
utils_1.logSuc('构建依赖安装完毕');
return true;
}, function (err) {
utils_1.logWarn(err);
utils_1.logWarn('The dependencies install occured some accidents');
utils_1.logWarn('依赖安装发生了错误');
return false;
})];
case 2: return [2 /*return*/, false];
}
});
}); });
}
function copyStylesheet(dir, originDir) {
var list = fs_1.default.readdirSync(dir);
list.map(function (v, k) {
var filePath = path_1.default.resolve(dir, v);
var stats = fs_1.default.statSync(filePath);
if (stats.isDirectory()) {
if (!/^.*(test|stories).*$/.test(v)) {
copyStylesheet(filePath, originDir || dir);
}
}
else if (/.(css|scss|sass|less)$/.test(v)) {
var relativePath = path_1.default.relative(originDir || dir, filePath);
var destPath = path_1.default.resolve(outDir, relativePath);
var emsPath = esmDir && path_1.default.resolve(esmDir, relativePath);
fs_extra_1.default.ensureDirSync(path_1.default.resolve(destPath, '..'));
fs_extra_1.default.copySync(filePath, destPath);
if (emsPath) {
fs_extra_1.default.ensureDirSync(path_1.default.resolve(emsPath, '..'));
fs_extra_1.default.copySync(filePath, emsPath);
}
}
});
}
function copyReserves(reserves) {
for (var i = 0, len = reserves.length; i < len; i++) {
var reserveItem = reserves[i];
var srcPath = '';
var relativePath = '';
if (typeof reserveItem === 'string') {
srcPath = reserveItem;
}
else {
srcPath = reserveItem.srcPath;
relativePath = reserveItem.relativePath || '';
}
var stats = void 0;
try {
stats = fs_1.default.statSync(srcPath);
}
catch (error) {
utils_1.logWarn("The path of \"" + srcPath + "\" is invaild");
utils_1.logWarn("\"" + srcPath + "\" \u662F\u4E00\u4E2A\u65E0\u6548\u7684\u8DEF\u5F84");
continue;
}
relativePath = relativePath || path_1.default.relative(srcDir, srcPath);
var destPath = path_1.default.resolve(outDir, relativePath);
var emsPath = esmDir && path_1.default.resolve(esmDir, relativePath);
if (stats.isDirectory()) {
fs_extra_1.default.ensureDirSync(destPath);
emsPath && fs_extra_1.default.ensureDirSync(emsPath);
}
else if (stats.isFile()) {
fs_extra_1.default.ensureDirSync(path_1.default.resolve(destPath, '..'));
emsPath && fs_extra_1.default.ensureDirSync(path_1.default.resolve(emsPath, '..'));
}
else {
utils_1.logWarn("The file or directory path which is \"" + srcPath + "\" cannot be found");
utils_1.logWarn("\"" + srcPath + "\" \u4E0D\u662F\u6709\u6548\u7684\u6587\u4EF6\u6216\u6587\u4EF6\u5939\u8DEF\u5F84");
continue;
}
fs_extra_1.default.copySync(srcPath, destPath);
emsPath && fs_extra_1.default.copySync(srcPath, emsPath);
}
}
var e_1, message, type, template, build, configRelease, plugins, autoRelease, srcDir, outDir, _a, esmDir, hash, tool, _b, reserve, preflight, _c, _d, typescript, _e, test, _f, eslint, _g, prettier, _h, stylelint, CWD, _j, configPath, verify, buildConfig, pkjFieldName, configFileName, configurationPath, realOutDir_1, buildCliArr, buildCliPath, tscPath, is_go_on, nextPath, is_go_on, content_rollup, content_webpack, content_gulp, content_config, buildConfigPath, is_go_on, rollupPath, webpackPath, tscPath, vTscPath, gulpPath, bConfig, err_1, err_2;
return __generator(this, function (_k) {
switch (_k.label) {
case 0:
_k.trys.push([0, 2, , 3]);
// node version pre-check
return [4 /*yield*/, utils_1.nodeVersionCheck('10.13.0')];
case 1:
// node version pre-check
_k.sent();
return [3 /*break*/, 3];
case 2:
e_1 = _k.sent();
utils_1.logWarn(e_1);
return [3 /*break*/, 3];
case 3:
if (!config || JSON.stringify(config) === '{}') {
utils_1.logWarn('Please initialize project first');
utils_1.logWarn('请先初始化项目');
return [2 /*return*/, process.exit(0)];
}
// bind exit signals
utils_2.signal();
message = 'Building(开始构建)';
utils_1.logTime('BUILD(项目构建)');
utils_1.logInfo(message);
type = config.type, template = config.template, build = config.build, configRelease = config.release, plugins = config.plugins;
autoRelease = build.autoRelease, srcDir = build.srcDir, outDir = build.outDir, _a = build.esmDir, esmDir = _a === void 0 ? '' : _a, hash = build.hash, tool = build.tool, _b = build.reserve, reserve = _b === void 0 ? {} : _b, preflight = build.preflight;
_c = preflight || {}, _d = _c.typescript, typescript = _d === void 0 ? false : _d, _e = _c.test, test = _e === void 0 ? false : _e, _f = _c.eslint, eslint = _f === void 0 ? false : _f, _g = _c.prettier, prettier = _g === void 0 ? false : _g, _h = _c.stylelint, stylelint = _h === void 0 ? false : _h;
CWD = process.cwd();
_j = buildTactic || {}, configPath = _j.config, verify = _j.verify, buildConfig = _j.buildConfig, pkjFieldName = _j.pkjFieldName, configFileName = _j.configFileName;
configurationPath = configPath && path_1.default.resolve(CWD, configPath);
if (configurationPath && !fs_1.default.existsSync(configurationPath))
configurationPath = void (0);
if (!outDir || !srcDir) {
handleBuildErr('The "srcDir" or "outDir" were missed in configuration file(配置文件中未定义 "srcDir" 或 "outDir")')();
}
_k.label = 4;
case 4:
_k.trys.push([4, 36, , 37]);
if (!(verify && test)) return [3 /*break*/, 6];
return [4 /*yield*/, utils_1.exec(['npm test'], function () { return utils_1.logSuc('Unit Test!'); }, handleBuildErr('The unit test not pass(单元测试失败)'))];
case 5:
_k.sent();
_k.label = 6;
case 6:
if (!(verify && eslint)) return [3 /*break*/, 8];
return [4 /*yield*/, utils_1.exec(['npm run lint:es'], function () { return utils_1.logSuc('Eslint!'); }, handleBuildErr("The eslint not pass(eslint\u6821\u9A8C\u5931\u8D25) \n try to exec(\u5C1D\u8BD5\u6267\u884C): " + utils_1.underline('npm run lint:es_fix')))];
case 7:
_k.sent();
_k.label = 8;
case 8:
if (!(verify && prettier)) return [3 /*break*/, 10];
return [4 /*yield*/, utils_1.exec(['npm run lint:prettier'], function () { return utils_1.logSuc('Prettier!'); }, handleBuildErr("The prettier not pass(prettier\u6821\u9A8C\u5931\u8D25) \n try to exec(\u5C1D\u8BD5\u6267\u884C): " + utils_1.underline('npm run lint:prettier_fix')))];
case 9:
_k.sent();
_k.label = 10;
case 10:
if (!(verify && stylelint)) return [3 /*break*/, 12];
return [4 /*yield*/, utils_1.exec(['npm run lint:style'], function () { return utils_1.logSuc('Stylelint!'); }, handleBuildErr("The stylelint not pass(stylelint\u6821\u9A8C\u5931\u8D25) \n try to exec(\u5C1D\u8BD5\u6267\u884C): " + utils_1.underline('npm run lint:style_fix')))];
case 11:
_k.sent();
_k.label = 12;
case 12:
realOutDir_1 = '';
buildCliArr = [];
buildCliPath = {
tsc: path_1.default.resolve(CWD, 'node_modules/typescript/bin/tsc'),
tspc: path_1.default.resolve(CWD, 'node_modules/ts-patch/bin/tspc.js'),
vuetsc: path_1.default.resolve(CWD, 'node_modules/vue-tsc/bin/vue-tsc.js'),
rollup: path_1.default.resolve(CWD, 'node_modules/rollup/dist/bin/rollup'),
webpack: path_1.default.resolve(CWD, 'node_modules/webpack-cli/bin/cli.js'),
gulp: path_1.default.resolve(CWD, 'node_modules/gulp/bin/gulp.js'),
next: path_1.default.resolve(CWD, 'node_modules/next/dist/bin/next')
};
if (!(tool === 'tsc')) return [3 /*break*/, 15];
if (!typescript) {
handleBuildErr('The typescript had been forbidden(已禁用 typescript,无法完成构建)')();
}
tscPath = buildCliPath.tsc;
// ts-patch is preferred
if (fs_1.default.existsSync(buildCliPath.tspc))
tscPath = buildCliPath.tspc;
if (!!fs_1.default.existsSync(tscPath)) return [3 /*break*/, 14];
utils_1.logWarn('Please install typescript first');
utils_1.logWarn('请先安装 typescript 相关依赖');
return [4 /*yield*/, installDenpendencies('tsc')];
case 13:
is_go_on = _k.sent();
if (!is_go_on)
return [2 /*return*/, process.exit(0)];
tscPath = buildCliPath.tspc;
_k.label = 14;
case 14:
buildCliArr.push(tscPath + " --outDir " + outDir + " --project " + (configurationPath || path_1.default.resolve(CWD, 'tsconfig.json')) + " --rootDir " + srcDir);
esmDir && buildCliArr.push(tscPath + " --module ESNext --target ES6 --outDir " + esmDir + " --project " + (configurationPath || path_1.default.resolve(CWD, 'tsconfig.json')) + " --rootDir " + srcDir);
realOutDir_1 = outDir;
return [3 /*break*/, 30];
case 15:
if (!(type === 'ssr-react')) return [3 /*break*/, 18];
nextPath = buildCliPath.next;
if (!!fs_1.default.existsSync(nextPath)) return [3 /*break*/, 17];
utils_1.logWarn('Please install webpack first');
utils_1.logWarn('请先安装 webpack 相关依赖');
return [4 /*yield*/, installDenpendencies('next')];
case 16:
is_go_on = _k.sent();
if (!is_go_on)
return [2 /*return*/, process.exit(0)];
_k.label = 17;
case 17:
buildCliArr.push(nextPath + " build");
return [3 /*break*/, 30];
case 18:
content_rollup = !buildConfig && type === 'toolkit' && rollup_1.default({ ts: typescript, multiOutput: true, srcDir: srcDir, outDir: outDir, esmDir: esmDir, configurationPath: configurationPath, pkjFieldName: pkjFieldName, configFileName: configFileName });
content_webpack = !buildConfig && (type === 'spa-react' || type === 'spa-react-pc' || type === 'spa-vue') && webpack_1.default({ ts: typescript, multiOutput: false, srcDir: srcDir, outDir: outDir, configurationPath: configurationPath, pkjFieldName: pkjFieldName, configFileName: configFileName, hash: hash });
content_gulp = !buildConfig && (type === 'component-react' || type === 'component-vue') && gulp_1.default({ srcDir: srcDir, outDir: outDir, esmDir: esmDir, configurationPath: configurationPath, pkjFieldName: pkjFieldName, configFileName: configFileName });
content_config = buildConfig || content_rollup || content_webpack || content_gulp;
if (!content_config) return [3 /*break*/, 30];
buildConfigPath = path_1.default.resolve(__dirname, '../../../', '.omni_cache/build.config.js');
is_go_on = true;
if (!(type === 'toolkit')) return [3 /*break*/, 21];
rollupPath = buildCliPath.rollup;
if (!!fs_1.default.existsSync(rollupPath)) return [3 /*break*/, 20];
utils_1.logWarn('Please install rollup first');
utils_1.logWarn('请先安装 rollup 相关依赖');
return [4 /*yield*/, installDenpendencies('rollup')];
case 19:
is_go_on = _k.sent();
_k.label = 20;
case 20:
buildCliArr.push(rollupPath + " -c " + buildConfigPath);
return [3 /*break*/, 29];
case 21:
if (!(type === 'spa-react' || type === 'spa-react-pc' || type === 'spa-vue')) return [3 /*break*/, 24];
webpackPath = buildCliPath.webpack;
if (!!fs_1.default.existsSync(webpackPath)) return [3 /*break*/, 23];
utils_1.logWarn('Please install webpack first');
utils_1.logWarn('请先安装 webpack 相关依赖');
return [4 /*yield*/, installDenpendencies('webpack')];
case 22:
is_go_on = _k.sent();
_k.label = 23;
case 23:
buildCliArr.push(webpackPath + " --config " + buildConfigPath);
return [3 /*break*/, 29];
case 24:
if (!(type === 'component-react' || type === 'component-vue')) return [3 /*break*/, 29];
tscPath = buildCliPath.tsc;
vTscPath = buildCliPath.vuetsc;
gulpPath = buildCliPath.gulp;
// ts-patch is preferred
if (fs_1.default.existsSync(buildCliPath.tspc))
tscPath = buildCliPath.tspc;
if (!(typescript && (!fs_1.default.existsSync(tscPath) || (type === 'component-vue' && !fs_1.default.existsSync(vTscPath))))) return [3 /*break*/, 26];
utils_1.logWarn('Please install typescript first');
utils_1.logWarn('请先安装 typescript 相关依赖');
return [4 /*yield*/, installDenpendencies('tsc')];
case 25:
is_go_on = _k.sent();
if (is_go_on)
tscPath = buildCliPath.tspc;
_k.label = 26;
case 26:
if (!(is_go_on && !fs_1.default.existsSync(gulpPath))) return [3 /*break*/, 28];
utils_1.logWarn('Please install gulp first');
utils_1.logWarn('请先安装 gulp 相关依赖');
return [4 /*yield*/, installDenpendencies('gulp')];
case 27:
is_go_on = _k.sent();
_k.label = 28;
case 28:
buildCliArr.push(typescript ? tscPath + " --outDir " + outDir + " --project " + (configurationPath || path_1.default.resolve(CWD, 'tsconfig.json')) + " --emitDeclarationOnly --rootDir " + srcDir : '', typescript && esmDir ? tscPath + " --module ESNext --target ES6 --outDir " + esmDir + " --project " + (configurationPath || path_1.default.resolve(CWD, 'tsconfig.json')) + " --emitDeclarationOnly --rootDir " + srcDir : '', typescript && type === 'component-vue' ? vTscPath + " --outDir " + outDir + " --project " + (configurationPath || path_1.default.resolve(CWD, 'tsconfig.json')) + " --emitDeclarationOnly --rootDir " + srcDir : '', typescript && esmDir && type === 'component-vue' ? vTscPath + " --module ESNext --target ES6 --outDir " + esmDir + " --project " + (configurationPath || path_1.default.resolve(CWD, 'tsconfig.json')) + " --emitDeclarationOnly --rootDir " + srcDir : '', gulpPath + " --gulpfile " + buildConfigPath + " --cwd " + CWD);
_k.label = 29;
case 29:
if (!is_go_on)
return [2 /*return*/, process.exit(0)];
utils_1.outputFile({
file_path: buildConfigPath,
file_content: content_config
});
if (type === 'spa-react' || type === 'spa-react-pc' || type === 'spa-vue') {
bConfig = require(buildConfigPath);
realOutDir_1 = (bConfig && bConfig.output && bConfig.output.path) || outDir;
}
_k.label = 30;
case 30:
// loading
if (type !== 'toolkit') {
utils_1.spinner.color('green');
utils_1.spinner.prefix('moon');
utils_1.spinner.state('start', 'Building, please wait patiently(项目构建中)');
}
try {
del_1.default.sync(realOutDir_1 || outDir, {
force: true
});
esmDir && del_1.default.sync(esmDir, {
force: true
});
}
catch (err) {
utils_1.logWarn(err);
}
return [4 /*yield*/, utils_1.exec(buildCliArr, function () {
return __awaiter(this, void 0, void 0, function () {
var style, _a, assets, plugin_handles, _b, _c, _i, name_1, handler, shouldExit;
return __generator(this, function (_d) {
switch (_d.label) {
case 0:
style = reserve.style, _a = reserve.assets, assets = _a === void 0 ? [] : _a;
if (type !== 'component-react' && type !== 'component-vue' && style)
copyStylesheet(srcDir);
copyReserves(assets);
plugin_handles = plugins && plugins.length > 0 && utils_2.getHandlers(plugins, 'build');
if (!plugin_handles) return [3 /*break*/, 4];
_b = [];
for (_c in plugin_handles)
_b.push(_c);
_i = 0;
_d.label = 1;
case 1:
if (!(_i < _b.length)) return [3 /*break*/, 4];
name_1 = _b[_i];
handler = plugin_handles[name_1];
return [4 /*yield*/, handler({
type: type,
template: template,
build: build,
release: configRelease
}, {
verify: verify,
buildConfig: buildConfig
})];
case 2:
_d.sent();
_d.label = 3;
case 3:
_i++;
return [3 /*break*/, 1];
case 4:
if (realOutDir_1 && !fs_1.default.existsSync(realOutDir_1)) {
handleBuildErr("The output file " + realOutDir_1 + " doesn't exist(\u8F93\u51FA\u7684 " + realOutDir_1 + " \u6587\u4EF6\u4E0D\u5B58\u5728\uFF0C\u6784\u5EFA\u5931\u8D25)")();
}
else {
type !== 'toolkit' && utils_1.spinner.state('stop');
utils_1.logTime('BUILD(项目构建)', true);
shouldExit = !(autoRelease || autoBuild);
handleBuildSuc()(shouldExit);
}
return [2 /*return*/];
}
});
});
}, handleBuildErr())];
case 31:
_k.sent();
if (!(!autoBuild && autoRelease)) return [3 /*break*/, 35];
utils_1.logEmph(utils_1.italic('Start auto release'));
utils_1.logEmph(utils_1.italic('开始自动发布'));
_k.label = 32;
case 32:
_k.trys.push([32, 34, , 35]);
return [4 /*yield*/, release_1.default(config, { verify: false }, autoRelease)];
case 33:
_k.sent();
handleBuildSuc('Auto release success(自动发布成功)!')(true);
return [3 /*break*/, 35];
case 34:
err_1 = _k.sent();
handleBuildErr('Auto release failed(自动发布失败)!')();
return [3 /*break*/, 35];
case 35: return [3 /*break*/, 37];
case 36:
err_2 = _k.sent();
utils_1.logErr(err_2);
handleBuildErr('👆 Oops! Building process occured some accidents(糟糕!构建过程发生了点意外)!')();
return [3 /*break*/, 37];
case 37: return [2 /*return*/];
}
});
});
}
exports.default = default_1;