import execa from 'execa'; import chalk from 'chalk'; import path from 'path'; import { PACKAGES_PATH, getPluginPackages, CORE_CLIENT, CORE_APP, getCjsPackages, getPresetsPackages, ROOT_PATH, ESM_PACKAGES, } from './constant'; import { buildClient } from './buildClient'; import { buildCjs } from './buildCjs'; import { buildPlugin } from './buildPlugin'; import { buildDeclaration } from './buildDeclaration'; import { PkgLog, getPkgLog, toUnixPath, getPackageJson, getUserConfig, UserConfig, writeToCache, readFromCache } from './utils'; import { getPackages } from './utils/getPackages'; import type { Project } from '@pnpm/workspace.find-packages'; import { tarPlugin } from './tarPlugin' import { buildEsm } from './buildEsm'; const BUILD_ERROR = 'build-error'; export async function build(pkgs: string[]) { const isDev = process.argv.includes('--development'); process.env.NODE_ENV = isDev ? 'development' : 'production'; let packages = await getPackages(pkgs); const cachePkg = readFromCache(BUILD_ERROR); if (process.argv.includes('--retry') && cachePkg?.pkg) { packages = packages.slice(packages.findIndex((item) => item.manifest.name === cachePkg.pkg)); } if (packages.length === 0) { let msg = ''; if (pkgs.length) { msg = `'${pkgs.join(', ')}' did not match any packages` } else { msg = 'No package matched' } console.warn(chalk.yellow(`[@nocobase/build]: ${msg}`)); return; } const pluginPackages = getPluginPackages(packages); const cjsPackages = getCjsPackages(packages); const presetsPackages = getPresetsPackages(packages); // core/* await buildPackages(cjsPackages, 'lib', buildCjs); const clientCore = packages.find((item) => item.dir === CORE_CLIENT); if (clientCore) { await buildPackage(clientCore, 'es', buildClient); } const esmPackages = cjsPackages.filter(pkg => ESM_PACKAGES.includes(pkg.manifest.name)); await buildPackages(esmPackages, 'es', buildEsm); // plugins/*、samples/* await buildPackages(pluginPackages, 'dist', buildPlugin); // presets/* await buildPackages(presetsPackages, 'lib', buildCjs); // core/app const appClient = packages.find((item) => item.dir === CORE_APP); if (appClient) { await runScript(['umi', 'build'], ROOT_PATH, { APP_ROOT: path.join(CORE_APP, 'client'), }); } writeToCache(BUILD_ERROR, {}); } export async function buildPackages( packages: Project[], targetDir: string, doBuildPackage: (cwd: string, userConfig: UserConfig, sourcemap: boolean, log?: PkgLog) => Promise, ) { for await (const pkg of packages) { writeToCache(BUILD_ERROR, { pkg: pkg.manifest.name}) await buildPackage(pkg, targetDir, doBuildPackage); } } export async function buildPackage( pkg: Project, targetDir: string, doBuildPackage: (cwd: string, userConfig: UserConfig, sourcemap: boolean, log?: PkgLog) => Promise, ) { const sourcemap = process.argv.includes('--sourcemap'); const noDeclaration = process.argv.includes('--no-dts'); const hasTar = process.argv.includes('--tar'); const onlyTar = process.argv.includes('--only-tar'); const log = getPkgLog(pkg.manifest.name); const packageJson = getPackageJson(pkg.dir); if (onlyTar) { await tarPlugin(pkg.dir, log); return; } log(`${chalk.bold(toUnixPath(pkg.dir.replace(PACKAGES_PATH, '').slice(1)))} build start`); const userConfig = getUserConfig(pkg.dir); // prebuild if (packageJson?.scripts?.prebuild) { log('prebuild'); await runScript(['prebuild'], pkg.dir); await packageJson.prebuild(pkg.dir); } if (userConfig.beforeBuild) { log('beforeBuild'); await userConfig.beforeBuild(log); } // build source await doBuildPackage(pkg.dir, userConfig, sourcemap, log); // build declaration if (!noDeclaration) { log('build declaration'); await buildDeclaration(pkg.dir, targetDir); } // postbuild if (packageJson?.scripts?.postbuild) { log('postbuild'); await runScript(['postbuild'], pkg.dir); } if (userConfig.afterBuild) { log('afterBuild'); await userConfig.afterBuild(log); } // tar if (hasTar) { await tarPlugin(pkg.dir, log); } } function runScript(args: string[], cwd: string, envs: Record = {}) { return execa('pnpm', args, { cwd, stdio: 'inherit', env: { ...process.env, ...envs, sourcemap: process.argv.includes('--sourcemap') ? 'sourcemap' : undefined, NODE_ENV: process.env.NODE_ENV || 'production', }, }); }