UNPKG

@omni-door/cli

Version:

A tool set for set up the standard JS project

470 lines (469 loc) 29.7 kB
"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;