UNPKG

tsdk

Version:

Type-safe API development and code share tool for TypeScript projects.

213 lines (211 loc) 12.5 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 __rest = (this && this.__rest) || function (s, e) { var t = {}; for (var p in s) if (Object.prototype.hasOwnProperty.call(s, p) && e.indexOf(p) < 0) t[p] = s[p]; if (s != null && typeof Object.getOwnPropertySymbols === "function") for (var i = 0, p = Object.getOwnPropertySymbols(s); i < p.length; i++) { if (e.indexOf(p[i]) < 0 && Object.prototype.propertyIsEnumerable.call(s, p[i])) t[p[i]] = s[p[i]]; } return t; }; var __importDefault = (this && this.__importDefault) || function (mod) { return (mod && mod.__esModule) ? mod : { "default": mod }; }; Object.defineProperty(exports, "__esModule", { value: true }); exports.webpackBuild = exports.tsdkConfigFilePath = void 0; const child_process_1 = require("child_process"); const fs_extra_1 = __importDefault(require("fs-extra")); const path_1 = __importDefault(require("path")); const typescript_1 = __importDefault(require("typescript")); const webpack_1 = __importDefault(require("webpack")); const webpack_node_externals_1 = __importDefault(require("webpack-node-externals")); const get_pkg_manager_1 = require("./get-pkg-manager"); exports.tsdkConfigFilePath = path_1.default.join(process.cwd(), 'tsdk.config.js'); const defaultMainName = 'default'; const distProjects = 'dist-projects'; // npx tsdk --nest build // npx tsdk --nest build [name] [name] // npx tsdk --nest build all function run() { return __awaiter(this, void 0, void 0, function* () { const idx = process.argv.findIndex((i) => i === '--names'); const command = process.argv[idx - 1]; const _names = process.argv.filter((item, index) => index > idx); const { projects } = yield getNestProjectsConfig(); const names = _names.find((i) => i === 'all') ? Object.keys(projects) : _names; if (names.length === 0) { names.push(defaultMainName); } const cwd = process.cwd(); if (command === 'build') { const tsconfig = typescript_1.default.readConfigFile(path_1.default.resolve(cwd, 'tsconfig.json'), typescript_1.default.sys.readFile).config; const outDir = path_1.default.normalize(tsconfig.compilerOptions.outDir); const include = tsconfig.include || []; const sourceMap = tsconfig.compilerOptions.sourceMap; // remove dist folder before build yield Promise.all([ fs_extra_1.default.remove(path_1.default.resolve(cwd, distProjects)), fs_extra_1.default.remove(path_1.default.resolve(cwd, outDir)), ]); console.log(`\n[${command}]: ${names.join(', ')}`); yield copyProdPackageJSON(path_1.default.resolve(cwd, distProjects), undefined, 'default-root'); const npmCMDs = (0, get_pkg_manager_1.getNpmCommand)(cwd); yield Promise.all(names.map((name) => { if (!projects[name]) { const msg = `\`${name}\` not exists in \`nest-cli.json\``; console.warn(msg); throw new Error(msg); } return new Promise((resolve, reject) => { setTimeout(() => __awaiter(this, void 0, void 0, function* () { console.log(`\n[${command} ${name}] Run: \`${npmCMDs.runCmd} nest ${command} ${name}\`\n`); try { (0, child_process_1.execSync)(`${npmCMDs.runCmd} nest ${command} ${name}`, { stdio: 'inherit' }); console.log(`[${command} ${name}] Success: \`${npmCMDs.runCmd} nest ${command} ${name}\` and start webpack build`); } catch (e) { console.log(`[${command} ${name}] Run: \`${npmCMDs.runCmd} nest ${command} ${name}\` error: `, e); console.log('\n'); reject(e); return; } const nestProjectConfig = projects[name]; const nodeExternalsParams = nestProjectConfig.nodeExternalsParams; try { const output = Object.assign(Object.assign({}, nestProjectConfig.output), { filename: nestProjectConfig.entryFile.endsWith('.js') ? nestProjectConfig.entryFile : path_1.default.basename(nestProjectConfig.entryFile).replace('.ts', '') + '.js', path: path_1.default.resolve(cwd, distProjects, `dist-${name}`) }); if (include.length === 0) { nestProjectConfig.entryFile = path_1.default.join(nestProjectConfig.sourceRoot, path_1.default.basename(nestProjectConfig.entryFile)); } let entry = path_1.default.resolve(cwd, outDir, nestProjectConfig.entryFile.replace('.ts', '.js')); const entryExists = yield fs_extra_1.default.pathExists(entry.indexOf('.js') > -1 ? entry : entry + '.js'); if (!entryExists) { const errorMsg = `[${command} ${name}] Entry not found: \`${entry}\``; const tmpEntry = entry.indexOf('src') > -1 ? path_1.default.normalize(path_1.default .resolve(cwd, outDir, nestProjectConfig.entryFile.replace('.ts', '.js')) .replace('src', '')) : path_1.default.resolve(cwd, outDir, 'src', nestProjectConfig.entryFile.replace('.ts', '.js')); const tmpEntryExists = yield fs_extra_1.default.pathExists(tmpEntry.indexOf('.js') > -1 ? tmpEntry : tmpEntry + '.js'); if (tmpEntryExists) { entry = tmpEntry; console.log(`\n${errorMsg}, use another entry: \`${entry}\``); } else { throw new Error(`${errorMsg}`); } } yield webpackBuild(Object.assign(Object.assign({ name, entry, mode: nestProjectConfig.mode || 'production', target: nestProjectConfig.target || 'node' }, (nestProjectConfig.externals ? { externals: nestProjectConfig.externals } : {})), { nodeExternalsParams, devtool: sourceMap ? 'source-map' : nestProjectConfig.devtool, // nestProjectConfig.devtool, 'source-map' output })); console.log(`\n[${command} ${name}] Success webpack build, output: ./${path_1.default.join(distProjects, `dist-${name}`, output.filename)}`); yield copyProdPackageJSON(path_1.default.join(cwd, distProjects, `dist-${name}`), JSON.stringify(Object.assign(Object.assign({}, pkgContent), { name: pkgContent.name + '-' + name, scripts: { start: 'cross-env NODE_ENV=production node ./main', } }), null, 2), name); resolve(nestProjectConfig); } catch (e) { console.log(`[${command} ${name}] Webpack build error: `, e); reject(e); } }), 0); }); })); } }); } run().catch((e) => { console.log(e); }); function getNestProjectsConfig() { return __awaiter(this, void 0, void 0, function* () { const cwd = process.cwd(); const nestjsFilepath = path_1.default.resolve(cwd, require(exports.tsdkConfigFilePath).monorepoRoot || './', 'node_modules/@nestjs/cli/package.json'); const nestjsFilepathExists = yield fs_extra_1.default.pathExists(nestjsFilepath); if (!nestjsFilepathExists) { // check again without `monorepoRoot` const nestjsFilepath = path_1.default.resolve(cwd, 'node_modules/@nestjs/cli/package.json'); const nestjsFilepathExists = yield fs_extra_1.default.pathExists(nestjsFilepath); if (!nestjsFilepathExists) throw new Error(`install \`@nestjs/cli\` first`); } const nestConfigFilepath = path_1.default.resolve(cwd, './nest-cli.json'); const exists = yield fs_extra_1.default.pathExists(nestConfigFilepath); if (!exists) { // throw new Error(`nest-cli.json doesn't exists: ${nestConfigFilepath}`); } const content = yield fs_extra_1.default.readFile(nestConfigFilepath, 'utf8'); const nestConfig = exists ? JSON.parse(content) : {}; const defaultMainConfig = Object.assign({ type: 'application', root: './', sourceRoot: 'src', entryFile: 'main', compilerOptions: Object.assign({ webpack: false, tsConfigPath: 'tsconfig.json' }, nestConfig.compilerOptions) }, nestConfig); return { projects: Object.assign(Object.assign({}, nestConfig.projects), { [defaultMainName]: defaultMainConfig }), }; }); } /** * in order to ignore built-in modules like path, fs, etc. * add `externalsPresets: { node: true },`, default is ignore all built-in modules. * * in order to ignore all modules in node_modules folder, default is ignore all node_modules. * if you dont want ignore modules in node_modules, you can add `externals: []` * * @Example: webpackBuild({ name: 'nestjs-todo', entry: './dist/modules/nestjs-todo/main.js', mode: 'production', devtool: "source-map", externals: undefined, // build all node_modules into one file target: 'node', output: { path: path.resolve(process.cwd(), 'dist-nestjs-todo'), filename: 'main.js', }, }) */ function webpackBuild(_a) { var { nodeExternalsParams } = _a, webpackConfig = __rest(_a, ["nodeExternalsParams"]); return new Promise((resolve, reject) => { (0, webpack_1.default)(Object.assign({ externalsPresets: { node: true }, externals: [(0, webpack_node_externals_1.default)(nodeExternalsParams)] }, webpackConfig), (err, stats) => { if (err || (stats === null || stats === void 0 ? void 0 : stats.hasErrors())) { const error = (stats === null || stats === void 0 ? void 0 : stats.compilation.errors) ? stats === null || stats === void 0 ? void 0 : stats.compilation.errors : err; console.log(`${webpackConfig.name} build error: `, error); reject(error); } else { resolve('done'); } }); }); } exports.webpackBuild = webpackBuild; let pkgContent = {}; function copyProdPackageJSON(dir, content, name) { return __awaiter(this, void 0, void 0, function* () { if (!Object.keys(pkgContent).length) { const fileContent = yield fs_extra_1.default.readFile(path_1.default.resolve(process.cwd(), 'package.json'), 'utf8'); const pkgJson = JSON.parse(fileContent); ['devDependencies', 'license', 'author', 'keywords', 'files'].forEach((k) => { delete pkgJson[k]; }); pkgContent = Object.assign({}, pkgJson); } if (dir) { yield fs_extra_1.default.ensureDir(dir); yield fs_extra_1.default.writeFile(path_1.default.resolve(dir, 'package.json'), content || JSON.stringify(Object.assign(Object.assign({}, pkgContent), { name: pkgContent.name + '-' + name, scripts: {} }), null, 2)); } }); }