Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Smarter detection of imported dependency files #288

Merged
merged 11 commits into from
Jul 2, 2024
12 changes: 10 additions & 2 deletions .github/workflows/tests.yml
Original file line number Diff line number Diff line change
Expand Up @@ -46,7 +46,7 @@ jobs:
- uses: oven-sh/setup-bun@v2
name: Install bun
with:
bun-version: "1.1.14"
bun-version: "1.1.17"

- name: Get pnpm store directory
id: pnpm-cache
Expand All @@ -66,13 +66,21 @@ jobs:
${{ runner.os }}-pnpm-store-

- uses: actions/cache@v4
name: Setup Turborepo cache
name: Setup Bati cache
with:
path: ${{ runner.temp }}/bati-cache
key: ${{ runner.os }}-${{ matrix.node }}-bati-cache-${{ github.sha }}
restore-keys: |
${{ runner.os }}-${{ matrix.node }}-bati-cache-

- uses: actions/cache@v4
name: Setup Turborepo cache
with:
path: .turbo
key: ${{ runner.os }}-${{ matrix.node }}-turbo-${{ github.sha }}
restore-keys: |
${{ runner.os }}-${{ matrix.node }}-turbo-

- name: Install global dependencies
if: matrix.os == 'ubuntu-latest'
run: pnpm install --global npm-cli-login
Expand Down
5 changes: 1 addition & 4 deletions .prettierrc
Original file line number Diff line number Diff line change
@@ -1,6 +1,3 @@
{
"printWidth": 120,
"plugins": ["@ianvs/prettier-plugin-sort-imports"],
"importOrderParserPlugins": ["typescript", "jsx"],
"importOrderTypeScriptVersion": "5.0.0"
"printWidth": 120
}
27 changes: 26 additions & 1 deletion boilerplates/README.md
Original file line number Diff line number Diff line change
@@ -1,7 +1,7 @@
### Syntax

Bati uses specific syntaxes to generate its boilerplates.
The global idea is to have templating as code, so that it is easy to write and maintain templates.
The global idea is to have templating as code, making it is easy to write and maintain templates.

<table>
<tr>
Expand Down Expand Up @@ -92,6 +92,31 @@ import "./mycss";

nothing

</td>
</tr>
<tr>
<tr>
<td>

```ts
/*# BATI include-if-imported #*/

const a = 1;
```

</td>
<td>
true if the file is at least imported by any other generated file

```ts
const a = 1;
```

</td>
<td>

nothing

</td>
</tr>
<tr>
Expand Down
2 changes: 1 addition & 1 deletion boilerplates/auth0/tsconfig.json
Original file line number Diff line number Diff line change
Expand Up @@ -3,6 +3,6 @@
"../tsconfig.base.json"
],
"compilerOptions": {
"types": ["@types/node", "@batijs/core/types", "@batijs/core/module"]
"types": ["@types/node", "@batijs/core/types"]
}
}
2 changes: 1 addition & 1 deletion boilerplates/authjs/tsconfig.json
Original file line number Diff line number Diff line change
Expand Up @@ -3,6 +3,6 @@
"../tsconfig.base.json"
],
"compilerOptions": {
"types": ["@types/node", "@batijs/core/types", "@batijs/core/module"]
"types": ["@types/node", "@batijs/core/types"]
}
}
2 changes: 1 addition & 1 deletion boilerplates/edgedb/tsconfig.json
Original file line number Diff line number Diff line change
@@ -1,6 +1,6 @@
{
"extends": ["../tsconfig.base.json"],
"compilerOptions": {
"types": ["@types/node", "@batijs/core/types", "@batijs/core/module"]
"types": ["@types/node", "@batijs/core/types"]
}
}
2 changes: 1 addition & 1 deletion boilerplates/express/tsconfig.json
Original file line number Diff line number Diff line change
@@ -1,6 +1,6 @@
{
"extends": ["../tsconfig.base.json"],
"compilerOptions": {
"types": ["@types/node", "@batijs/core/types", "@batijs/core/module"]
"types": ["@types/node", "@batijs/core/types"]
}
}
2 changes: 1 addition & 1 deletion boilerplates/fastify/tsconfig.json
Original file line number Diff line number Diff line change
@@ -1,7 +1,7 @@
{
"extends": ["../tsconfig.base.json"],
"compilerOptions": {
"types": ["@types/node", "@batijs/core/types", "@batijs/core/module"],
"types": ["@types/node", "@batijs/core/types"],
"lib": ["DOM"]
}
}
2 changes: 1 addition & 1 deletion boilerplates/prisma/tsconfig.json
Original file line number Diff line number Diff line change
@@ -1,6 +1,6 @@
{
"extends": ["../tsconfig.base.json"],
"compilerOptions": {
"types": ["@types/node", "@batijs/core/types", "@batijs/core/module"]
"types": ["@types/node", "@batijs/core/types"]
}
}
2 changes: 1 addition & 1 deletion boilerplates/react-firebase-auth/tsconfig.json
Original file line number Diff line number Diff line change
Expand Up @@ -3,7 +3,7 @@
"../tsconfig.base.json"
],
"compilerOptions": {
"types": ["vite/client", "@types/node", "@batijs/core/types", "@batijs/core/module"],
"types": ["vite/client", "@types/node", "@batijs/core/types"],
"jsx": "preserve",
"jsxImportSource": "react",
"lib": ["DOM", "DOM.Iterable", "ES2022"]
Expand Down
1 change: 1 addition & 0 deletions boilerplates/shared-server/files/server/vike-handler.ts
Original file line number Diff line number Diff line change
@@ -1,3 +1,4 @@
/*# BATI include-if-imported #*/
/// <reference lib="webworker" />
import { renderPage } from "vike/server";

Expand Down
2 changes: 1 addition & 1 deletion boilerplates/solid-firebase-auth/tsconfig.json
Original file line number Diff line number Diff line change
Expand Up @@ -3,7 +3,7 @@
"compilerOptions": {
"module": "ESNext",
"moduleResolution": "Bundler",
"types": ["vite/client", "@types/node", "@batijs/core/types", "@batijs/core/module"],
"types": ["vite/client", "@types/node", "@batijs/core/types"],
"jsx": "preserve",
"jsxImportSource": "solid-js",
"lib": ["DOM", "DOM.Iterable", "ESNext"]
Expand Down
2 changes: 1 addition & 1 deletion boilerplates/telefunc/tsconfig.json
Original file line number Diff line number Diff line change
@@ -1,6 +1,6 @@
{
"compilerOptions": {
"types": ["@types/node", "@batijs/core/types", "@batijs/core/module"]
"types": ["@types/node", "@batijs/core/types"]
},
"extends": ["../tsconfig.base.json"]
}
2 changes: 1 addition & 1 deletion boilerplates/ts-rest/tsconfig.json
Original file line number Diff line number Diff line change
Expand Up @@ -3,7 +3,7 @@
"skipLibCheck": true,
"module": "ESNext",
"moduleResolution": "Bundler",
"types": ["@batijs/core/types", "@batijs/core/module"]
"types": ["@batijs/core/types"]
},
"exclude": ["*/dist/**/*", "*/node_modules/**/*"]
}
2 changes: 1 addition & 1 deletion boilerplates/tsconfig.base.json
Original file line number Diff line number Diff line change
Expand Up @@ -3,7 +3,7 @@
"compilerOptions": {
"module": "ESNext",
"moduleResolution": "Bundler",
"types": ["@batijs/core/types", "@batijs/core/module"]
"types": ["@batijs/core/types"]
},
"exclude": ["*/dist/**/*", "*/node_modules/**/*"]
}
22 changes: 20 additions & 2 deletions package.json
Original file line number Diff line number Diff line change
Expand Up @@ -24,7 +24,6 @@
"license": "MIT",
"devDependencies": {
"@eslint/js": "^9.6.0",
"@ianvs/prettier-plugin-sort-imports": "^4.3.0",
"@types/eslint__js": "^8.42.3",
"bumpp": "^9.4.1",
"citty": "^0.1.6",
Expand All @@ -46,5 +45,24 @@
"node": ">=18",
"pnpm": ">=9"
},
"packageManager": "[email protected]"
"packageManager": "[email protected]",
"pnpm": {
"overrides": {
"array-includes": "npm:@nolyfill/array-includes@^1",
"array.prototype.findlast": "npm:@nolyfill/array.prototype.findlast@^1",
"array.prototype.flat": "npm:@nolyfill/array.prototype.flat@^1",
"array.prototype.flatmap": "npm:@nolyfill/array.prototype.flatmap@^1",
"array.prototype.toreversed": "npm:@nolyfill/array.prototype.toreversed@^1",
"array.prototype.tosorted": "npm:@nolyfill/array.prototype.tosorted@^1",
"es-iterator-helpers": "npm:@nolyfill/es-iterator-helpers@^1",
"is-core-module": "npm:@nolyfill/is-core-module@^1",
"object.assign": "npm:@nolyfill/object.assign@^1",
"object.entries": "npm:@nolyfill/object.entries@^1",
"object.fromentries": "npm:@nolyfill/object.fromentries@^1",
"object.hasown": "npm:@nolyfill/object.hasown@^1",
"object.values": "npm:@nolyfill/object.values@^1",
"side-channel": "npm:@nolyfill/side-channel@^1",
"string.prototype.matchall": "npm:@nolyfill/string.prototype.matchall@^1"
}
}
}
73 changes: 70 additions & 3 deletions packages/build/src/index.ts
Original file line number Diff line number Diff line change
Expand Up @@ -68,16 +68,69 @@ async function importTransformer(p: string) {
return f.default as Transformer;
}

function importToPotentialTargets(imp: string) {
let subject = imp;
const ext = path.posix.extname(imp);
const targets: string[] = [];

if (ext.match(/^\.[jt]sx?$/)) {
subject = subject.replace(/^\.[jt]sx?$/, "");
}

if (!ext || subject !== imp) {
targets.push(...[".js", ".jsx", ".ts", ".tsx", ".cjs", ".mjs"].map((e) => `${subject}${e}`));
} else {
targets.push(imp);
}

return targets;
}

export default async function main(options: { source: string | string[]; dist: string }, meta: VikeMeta) {
const sources = Array.isArray(options.source) ? options.source : [options.source];
const targets = new Set<string>();
const allImports = new Set<string>();
const includeIfImported = new Map<string, () => Promise<void>>();

const priorityQ = queue();
const transformAndWriteQ = queue();

function updateAllImports(target: string, imports?: Set<string>) {
if (!imports) return;

for (const imp of imports.values()) {
const importTarget = path.posix.resolve(path.posix.dirname(target), imp);
const importTargets = importToPotentialTargets(importTarget);

for (const imp2 of importTargets) {
allImports.add(imp2);
}
}
}

async function triggerPendingTargets(target: string, imports?: Set<string>) {
if (!imports) return;

for (const imp of imports.values()) {
const importTarget = path.posix.resolve(path.posix.dirname(target), imp);
const importTargets = importToPotentialTargets(importTarget);
// console.log("triggerPendingTargets(targets)", importTarget, importTargets);

for (const imp2 of importTargets) {
if (includeIfImported.has(imp2)) {
const fn = includeIfImported.get(imp2)!;
includeIfImported.delete(imp2);
await fn();
break;
}
}
}
}

for (const source of sources) {
for await (const p of walk(source)) {
const target = toDist(p, source, options.dist);
const targetAbsolute = path.resolve(target);
const parsed = path.parse(p);
if (parsed.name.match(reIgnoreFile)) {
continue;
Expand Down Expand Up @@ -106,18 +159,19 @@ Please report this issue to https://github.com/batijs/bati`,

if (fileContent !== null) {
await safeWriteFile(target, fileContent);
targets.add(target);
}
});
} else {
priorityQ.add(async () => {
const code = await readFile(p, { encoding: "utf-8" });
const filepath = path.relative(source, p);

let fileContent = await transformAndFormat(code, meta, {
const result = await transformAndFormat(code, meta, {
filepath,
});

let fileContent = result.code;

if (p.endsWith(".d.ts") && targets.has(target)) {
// Merging .d.ts files here
fileContent = await mergeDts({
Expand All @@ -129,7 +183,13 @@ Please report this issue to https://github.com/batijs/bati`,
}

if (fileContent) {
await safeWriteFile(target, fileContent.trimStart());
updateAllImports(targetAbsolute, result.context?.imports);
if (!result.context?.flags.has("include-if-imported") || allImports.has(targetAbsolute)) {
await safeWriteFile(target, fileContent.trimStart());
await triggerPendingTargets(targetAbsolute, result.context?.imports);
} else {
includeIfImported.set(targetAbsolute, () => safeWriteFile(target, fileContent.trimStart()));
}
targets.add(target);
}
});
Expand All @@ -139,4 +199,11 @@ Please report this issue to https://github.com/batijs/bati`,

await priorityQ.run();
await transformAndWriteQ.run();

// Ensure all pending files are copied if necessary
for (const target of includeIfImported.keys()) {
if (allImports.has(target)) {
await includeIfImported.get(target)!();
}
}
}
4 changes: 3 additions & 1 deletion packages/build/src/merge-dts.ts
Original file line number Diff line number Diff line change
Expand Up @@ -50,7 +50,9 @@ export async function mergeDts({
}
}

return transformAndFormat(currentAst.generate().code, meta, {
const res = await transformAndFormat(currentAst.generate().code, meta, {
filepath,
});

return res.code;
}
2 changes: 1 addition & 1 deletion packages/build/tsconfig.json
Original file line number Diff line number Diff line change
@@ -1,6 +1,6 @@
{
"extends": ["../tsconfig.base.json"],
"compilerOptions": {
"types": ["@types/node", "@batijs/core/types", "@batijs/core/module"]
"types": ["@types/node", "@batijs/core/types"]
}
}
1 change: 1 addition & 0 deletions packages/cli/package.json
Original file line number Diff line number Diff line change
Expand Up @@ -27,6 +27,7 @@
"sift": "^17.1.3",
"tsup": "^8.1.0",
"typescript": "^5.5.2",
"unplugin-purge-polyfills": "^0.0.4",
"vite": "^5.3.2",
"which-pm-runs": "^1.1.0"
},
Expand Down
3 changes: 2 additions & 1 deletion packages/cli/tsup.config.ts
Original file line number Diff line number Diff line change
@@ -1,13 +1,14 @@
import { defineConfig } from "tsup";
import esbuildBundleAllPlugin from "./esbuild-bundle-all.js";
import { purgePolyfills } from "unplugin-purge-polyfills";

export default defineConfig({
entry: ["index.ts"],
format: ["esm"],
outDir: "./dist",
clean: true,
bundle: true,
esbuildPlugins: [esbuildBundleAllPlugin],
esbuildPlugins: [esbuildBundleAllPlugin, purgePolyfills.esbuild({})],
platform: "node",
banner: {
js: "#!/usr/bin/env node",
Expand Down
3 changes: 2 additions & 1 deletion packages/compile/package.json
Original file line number Diff line number Diff line change
Expand Up @@ -15,7 +15,8 @@
"license": "MIT",
"devDependencies": {
"@types/node": "^18.19.14",
"typescript": "^5.5.2"
"typescript": "^5.5.2",
"unplugin-purge-polyfills": "^0.0.4"
},
"dependencies": {
"esbuild": "^0.22.0",
Expand Down
2 changes: 2 additions & 0 deletions packages/compile/tsup.config.ts
Original file line number Diff line number Diff line change
@@ -1,9 +1,11 @@
import { defineConfig } from "tsup";
import { purgePolyfills } from "unplugin-purge-polyfills";

export default defineConfig({
entry: ["index.ts"],
clean: true,
format: "esm",
dts: true,
outDir: "./dist",
esbuildPlugins: [purgePolyfills.esbuild({})],
});
1 change: 0 additions & 1 deletion packages/core/module.d.ts

This file was deleted.

Loading
Loading