diff --git a/.github/workflows/validate.yml b/.github/workflows/validate.yml index 45a569f6..ebb618c1 100644 --- a/.github/workflows/validate.yml +++ b/.github/workflows/validate.yml @@ -18,7 +18,7 @@ jobs: steps: - uses: actions/checkout@v4 - uses: ./.github/actions/setup - - run: pnpm -r --sequential build + - run: pnpm buildc all build-demo: runs-on: ubuntu-22.04 steps: diff --git a/package.json b/package.json index 28343056..4f208344 100644 --- a/package.json +++ b/package.json @@ -15,10 +15,10 @@ "docs:gen": "typedoc --options docs/typedoc.json", "docs:dev": "pnpm -s docs:gen && vitepress dev docs", "docs:build": "pnpm -s docs:gen && vitepress build docs", - "docs:preview": "pnpm -s docs:gen && vitepress preview docs", - "build-deps": "pnpm tsx scripts/build-deps.ts" + "docs:preview": "pnpm -s docs:gen && vitepress preview docs" }, "devDependencies": { + "@aklinker1/buildc": "^1.0.5", "@aklinker1/check": "^1.3.1", "@types/fs-extra": "^11.0.4", "@vitest/coverage-v8": "^1.6.0", diff --git a/packages/module-react/package.json b/packages/module-react/package.json index fc11b6a4..3cc0e8a1 100644 --- a/packages/module-react/package.json +++ b/packages/module-react/package.json @@ -21,9 +21,8 @@ "dist" ], "scripts": { - "build": "pnpm -s build-deps && unbuild", - "check": "pnpm -s build-deps && check", - "build-deps": "pnpm -ws build-deps @wxt-dev/module-react" + "build": "buildc -- unbuild", + "check": "buildc --deps-only -- check" }, "peerDependencies": { "wxt": ">=0.18.5" diff --git a/packages/module-solid/package.json b/packages/module-solid/package.json index a65d3f6d..4118ec3a 100644 --- a/packages/module-solid/package.json +++ b/packages/module-solid/package.json @@ -21,9 +21,8 @@ "dist" ], "scripts": { - "build": "pnpm -s build-deps && unbuild", - "check": "pnpm -s build-deps && check", - "build-deps": "pnpm -ws build-deps @wxt-dev/module-solid" + "build": "buildc -- unbuild", + "check": "buildc --deps-only -- check" }, "peerDependencies": { "wxt": ">=0.18.5" diff --git a/packages/module-svelte/package.json b/packages/module-svelte/package.json index 3671df11..61c02f48 100644 --- a/packages/module-svelte/package.json +++ b/packages/module-svelte/package.json @@ -21,9 +21,8 @@ "dist" ], "scripts": { - "build": "pnpm -s build-deps && unbuild", - "check": "pnpm -s build-deps && check", - "build-deps": "pnpm -ws build-deps @wxt-dev/module-svelte" + "build": "buildc -- unbuild", + "check": "buildc --deps-only -- check" }, "peerDependencies": { "wxt": ">=0.18.5" diff --git a/packages/module-vue/package.json b/packages/module-vue/package.json index 58c4c211..b89da4a7 100644 --- a/packages/module-vue/package.json +++ b/packages/module-vue/package.json @@ -21,9 +21,8 @@ "dist" ], "scripts": { - "build": "pnpm -s build-deps && unbuild", - "check": "pnpm -s build-deps && check", - "build-deps": "pnpm -ws build-deps @wxt-dev/module-vue" + "build": "buildc -- unbuild", + "check": "buildc --deps-only -- check" }, "peerDependencies": { "wxt": ">=0.18.5" diff --git a/packages/wxt-demo/package.json b/packages/wxt-demo/package.json index ba7e1e85..34d8e066 100644 --- a/packages/wxt-demo/package.json +++ b/packages/wxt-demo/package.json @@ -4,18 +4,17 @@ "private": true, "type": "module", "scripts": { - "dev": "pnpm -s build-deps && wxt", - "build": "pnpm -s build-deps && wxt build", - "build:all": "pnpm -s build-deps && run-s -s 'build:all:*'", + "dev": "buildc -- wxt", + "build": "buildc --deps-only -- wxt build", + "build:all": "buildc --deps-only -- run-s -s 'build:all:*'", "build:all:chrome-mv3": "wxt build", "build:all:chrome-mv2": "wxt build --mv2", "build:all:firefox-mv3": "wxt build -b firefox --mv3", "build:all:firefox-mv2": "wxt build -b firefox", - "test": "pnpm -s build-deps && vitest", - "zip": "pnpm -s build-deps && wxt zip", - "check": "pnpm -s build-deps && check", - "postinstall": "pnpm -s build-deps && wxt prepare", - "build-deps": "pnpm -sw build-deps wxt-demo" + "test": "buildc --deps-only -- vitest", + "zip": "buildc --deps-only -- wxt zip", + "check": "buildc --deps-only -- check", + "postinstall": "buildc --deps-only -- wxt prepare" }, "dependencies": { "react": "^18.3.1", @@ -27,5 +26,8 @@ "sass": "^1.77.5", "typescript": "^5.4.5", "wxt": "workspace:*" + }, + "buildc": { + "outDir": ".output/chrome-mv3" } } diff --git a/packages/wxt/package.json b/packages/wxt/package.json index 9721f913..58824b96 100644 --- a/packages/wxt/package.json +++ b/packages/wxt/package.json @@ -92,12 +92,12 @@ }, "scripts": { "wxt": "tsx src/cli/index.ts", - "build": "tsx scripts/build.ts", - "check": "run-s -c check:*", + "build": "buildc -- tsx scripts/build.ts", + "check": "buildc --deps-only -- run-s -c check:*", "check:default": "check", "check:tsc-virtual": "tsc --noEmit -p src/virtual", - "test": "vitest", - "test:e2e": "vitest -r e2e", + "test": "buildc --deps-only -- vitest", + "test:e2e": "buildc --deps-only -- vitest -r e2e", "sync-releases": "pnpx changelogen@latest gh release" }, "dependencies": { diff --git a/pnpm-lock.yaml b/pnpm-lock.yaml index 0dbd58bc..b32f6349 100644 --- a/pnpm-lock.yaml +++ b/pnpm-lock.yaml @@ -8,6 +8,9 @@ importers: .: devDependencies: + '@aklinker1/buildc': + specifier: ^1.0.5 + version: 1.0.5(typescript@5.4.5) '@aklinker1/check': specifier: ^1.3.1 version: 1.3.1(typescript@5.4.5) @@ -374,6 +377,23 @@ importers: packages: + /@aklinker1/buildc@1.0.5(typescript@5.4.5): + resolution: {integrity: sha512-xM9tA6VpkHh2qTCVBwuXUGdBpgxtnj35zrDT0hMBWBLAoAvNXjQrGf4DaFN+gnBsd32TtFPDg1IfcW2ZcUF0ZQ==} + hasBin: true + peerDependencies: + typescript: ^5.0.0 + dependencies: + cac: 6.7.14 + consola: 3.2.3 + dependency-graph: 1.0.0 + fast-glob: 3.3.2 + fs-extra: 11.2.0 + ohash: 1.1.3 + pathe: 1.1.2 + typescript: 5.4.5 + yaml: 2.4.5 + dev: true + /@aklinker1/check@1.3.1(typescript@5.4.5): resolution: {integrity: sha512-EALKJzoojytjC6cYLIjRjC+nNpVdqSWYjJm8FTUtWneemKDs+Q46PaMyEx2EYTRbj4fO0OXj9igABwbpp/vV4g==} hasBin: true diff --git a/scripts/build-deps.ts b/scripts/build-deps.ts deleted file mode 100644 index dc90222f..00000000 --- a/scripts/build-deps.ts +++ /dev/null @@ -1,133 +0,0 @@ -// -// Build all workspace packages, or only dependencies of a specific package. -// Kind of a simple version of nx/turborepo, but we can keep using PNPM to run -// all commands. -// -// Usage: -// pnpm tsx scripts/build-deps.ts # Builds all packages in repo -// pnpm tsx scripts/build-deps.ts # Builds only dependencies of -// - -import glob from 'fast-glob'; -import { DepGraph } from 'dependency-graph'; -import fs from 'fs-extra'; -import YAML from 'yaml'; -import { execa } from 'execa'; -import consola from 'consola'; -import { hashFile, hash } from 'hasha'; -import { resolve } from 'node:path'; - -// Quick hack to prevent recursive calls to this script. If it's being called -// from another instance of this script, the parent instance is already -// preforming this build, so it can be skipped. -if (process.env.BUILD_DEPS) process.exit(0); -process.env.BUILD_DEPS = 'true'; - -// Parse args -const packageToBuild = process.argv[2]; -if (packageToBuild == null) { - consola.info('Building all packages...'); -} else { - consola.info(`Building dependencies of \`${packageToBuild}\``); -} - -// Build graph -const workspace: { packages: string[] } = YAML.parse( - await fs.readFile('pnpm-workspace.yaml', 'utf8'), -); -const packageDirs = await glob(workspace.packages, { onlyDirectories: true }); - -const graph = new DepGraph>(); -// Add all packages to chart -for (const packageDir of packageDirs) { - try { - const packageJson = await fs.readJson(`${packageDir}/package.json`); - graph.addNode(packageJson.name, { ...packageJson, dir: packageDir }); - } catch { - // Package missing package.json, ignore it - } -} -// Add dependencies between packages -graph.entryNodes().forEach((packageName) => { - const packageJson = graph.getNodeData(packageName); - [ - ...Object.entries(packageJson.dependencies ?? {}), - ...Object.entries(packageJson.devDependencies ?? {}), - ].forEach(([dep, version]) => { - if (version !== 'workspace:*') return; - graph.addDependency(packageName, dep); - }); -}); -function printGraph(graph: DepGraph) { - consola.debug('Dependency Graph:'); - function printNode(node: string, level = 0) { - consola.debug(`${''.padStart(level * 2, ' ')}- \`${node}\``); - graph.dependenciesOf(node).forEach((dep) => printNode(dep, level + 1)); - } - graph.entryNodes().forEach((entry) => printNode(entry)); -} -printGraph(graph); -if (packageToBuild) { - // Remove nodes not associated with the package to build - graph.entryNodes().forEach((entry) => { - if (entry !== packageToBuild) graph.removeNode(entry); - }); -} - -// Get order -const buildOrder = graph.overallOrder().filter( - // Remove packageToBuild if provided - (packageName) => packageName !== packageToBuild, -); -consola.info('Build order:', buildOrder); - -// Build dependencies of a package -async function hashDir(dir: string): Promise { - const files = await glob('**/*', { - ignore: [ - '**/dist/**', - '**/node_modules/**', - '**/__tests__/**', - '**/e2e/**', - 'CHANGELOG.md', - 'typedoc.json', - 'vitest.*.ts', - ], - cwd: dir, - }); - const hashes = await Promise.all( - files.sort().map(async (file) => { - const hash = await hashFile(resolve(dir, file), { algorithm: 'md5' }); - return `${hash}-${file}`; - }), - ); - consola.debug(hashes.join('\n')); - return await hash(hashes.join('\n'), { algorithm: 'md5' }); -} -async function buildPackage(packageName: string): Promise { - const packageJson = graph.getNodeData(packageName); - const hash = await hashDir(packageJson.dir); - consola.debug('Directory hash:', hash); - const cacheDir = resolve('.cache', packageJson.dir, hash); - const outputDir = resolve(packageJson.dir, 'dist'); - if (await fs.pathExists(cacheDir)) { - await fs.ensureDir(outputDir); - await fs.copy(cacheDir, outputDir); - consola.success(`\`${packageName}\` cached`); - } else { - await execa('pnpm', ['--filter', packageName, 'build'], { - stdio: 'inherit', - }); - await fs.ensureDir(cacheDir); - await fs.copy(outputDir, cacheDir); - } -} - -try { - for (const packageName of buildOrder) { - await buildPackage(packageName); - } -} catch (err) { - consola.error(err); - process.exit(1); -}