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

feat(lune): add optional farm build to lune #33

Open
wants to merge 4 commits into
base: main
Choose a base branch
from
Open
Show file tree
Hide file tree
Changes from 3 commits
Commits
File filter

Filter by extension

Filter by extension


Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
17 changes: 9 additions & 8 deletions packages/lune/package.json
Original file line number Diff line number Diff line change
@@ -1,8 +1,8 @@
{
"name": "@uwu/lune",
"version": "1.4.1",
"version": "1.5.0",
"description": "The CLI build tool for shelter",
"bin": "dist/clibundle.cjs",
"bin": "dist/src/index.js",
"main": "dist/src/mod.js",
"module": "dist/src/mod.js",
"author": "uwu.network",
Expand All @@ -14,18 +14,19 @@
},
"type": "module",
"devDependencies": {
"@types/node": "^18.15.3",
"@types/ws": "^8.5.4",
"typescript": "^5.0.2",
"esbuild-plugin-solid": "^0.5.0"
"esbuild-plugin-solid": "^0.5.0",
"typescript": "^5.0.3"
},
"dependencies": {
"solid-js": "1.6.16",
"postcss": "^8.4.21",
"postcss-modules": "^6.0.0",
"@farmfe/core": "^1.3.12",
"chokidar": "^3.5.3",
"esbuild": "^0.17.12",
"esbuild-sass-plugin-ysink": "^2.3.4",
"postcss": "^8.4.21",
"postcss-modules": "^6.0.0",
"solid-js": "1.6.16",
"vite-plugin-solid": "^2.10.1",
"ws": "^8.13.0"
}
}
27 changes: 5 additions & 22 deletions packages/lune/postprocess.mjs
Original file line number Diff line number Diff line change
@@ -1,26 +1,9 @@
// @ts-check

import { readFile, writeFile } from "fs/promises";
import { build } from "esbuild";

await build({
entryPoints: ["dist/src/index.js"],
bundle: true,
outfile: "dist/clibundle.cjs",
external: [
// literally everything except from esbuild-plugin-solid
"chokidar",
"esbuild",
"esbuild-sass-plugin-ysink",
"postcss",
"postcss-modules",
"solid-js",
"ws",
// node things esbuild doesn't know about
"readline/promises",
],
platform: "node",
});
Copy link
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

We need to bundle the solid compiler due to npm's inability to pin deps-of-deps so this change is a no-go

Copy link
Member Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

fix it then lol


for (const f of ["dist/src/index.js", "dist/clibundle.cjs"])
await writeFile(f, "#!/usr/bin/env node\n" + (await readFile(f)).toString());
const builtIndex = "dist/src/index.js";
await writeFile(
builtIndex,
"#!/usr/bin/env node --no-warnings=ExperimentalWarning\n" + (await readFile(builtIndex)).toString(),
);
112 changes: 85 additions & 27 deletions packages/lune/src/builder.ts
Original file line number Diff line number Diff line change
@@ -1,12 +1,13 @@
import type { LuneCfg } from "./config";

import type { LuneCfg } from "./config.js";
import { createHash } from "crypto";
import { readFile, writeFile } from "fs/promises";
import { readFile, writeFile, mkdir } from "fs/promises";
import { resolve } from "path";
import { existsSync } from "fs";
import { build } from "esbuild";
import { solidPlugin } from "esbuild-plugin-solid";
import { solidPlugin as solidEsbuildPlugin } from "esbuild-plugin-solid";
import solidVitePlugin from "vite-plugin-solid";
import { sassPlugin, postcssModules } from "esbuild-sass-plugin-ysink";
import { buildToString as farmBuild } from "./farmbuilder.js";

const resolverRoots = {
"solid-js": "solid",
Expand Down Expand Up @@ -52,34 +53,91 @@ export async function buildPlugin(path: string, to: string, cfg: LuneCfg, minify

if (!entryPoint) throw new Error("failed to find entrypoint - check your working directory and config");

await build({
entryPoints: [entryPoint],
outfile,
bundle: true,
minify,
plugins: [
...(cfg.prePlugins ?? []),
solidPlugin(),
(cfg.cssModules
? sassPlugin({
style: "compressed",
sourceMap: false,
transform: postcssModules({
localsConvention: "camelCaseOnly",
inject: cfg.cssModules === "legacy" ? false : "shelter",
} as any),
})
: sassPlugin({ style: "compressed", sourceMap: false, type: "css-text" })) as any, // bad but version conflicts suck
shelterEsbuildResolver(),
...(cfg.postPlugins ?? []),
],
const sharedEsbuildOptions = {
globalName: "__lune_temp_global",
logLevel: "silent", // we handle errors ourself
});
} as const;

if (cfg.useFarm == true) {
const built = await farmBuild({
vitePlugins: [
() => ({
vitePlugin: solidVitePlugin(),
filters: ["\\.tsx$", "\\.jsx$"],
}),
...(cfg.vitePlugins ?? []),
],
plugins: [...(cfg.farmPlugins ?? [])],
compilation: {
partialBundling: {
enforceResources: [
{
name: "index",
test: [".+"],
},
],
},
minify: false, // set to false because esbuild handles this for us.
persistentCache: false,
output: { targetEnv: "library-browser", format: "esm" },
input: { index: entryPoint },
external: [
{ "solid-js/web": "shelter.solidWeb", "solid-js/store": "shelter.solidStore", "solid-js": "shelter.solid" },
],
},
});

try {
await mkdir(to, { recursive: true });
} catch {}

await writeFile(
outfile,
(
await build({
stdin: {
contents: built,
sourcefile: "index.js",
},
format: "iife",
minify,
bundle: true,
write: false,
// I didn't want to have to do this, really. But no matter what I've tried, I can't get Farm to work how I want it to, unfortunately.
// I've noticed that the solid-js Vite plugin adds an import to solid-js/web, which is fine, but it does not get caught by Farm at any point, so I can't mark it as external.
plugins: [shelterEsbuildResolver()],
...sharedEsbuildOptions,
})
).outputFiles[0].text,
);
} else {
await build({
entryPoints: [entryPoint],
outfile,
bundle: true,
minify,
plugins: [
...(cfg.prePlugins ?? []),
solidEsbuildPlugin(),
(cfg.cssModules
? sassPlugin({
style: "compressed",
sourceMap: false,
transform: postcssModules({
localsConvention: "camelCaseOnly",
inject: cfg.cssModules === "legacy" ? false : "shelter",
} as any),
})
: sassPlugin({ style: "compressed", sourceMap: false, type: "css-text" })) as any, // bad but version conflicts suck
shelterEsbuildResolver(),
...(cfg.postPlugins ?? []),
],
...sharedEsbuildOptions,
});
}

const finalDistJs = (await readFile(outfile)).toString().replace(/var __lune_temp_global\s*=\s*/, "");
await writeFile(outfile, finalDistJs);

const manifest = JSON.parse((await readFile(resolve(path, "plugin.json"))).toString());
await writeFile(outmanifest, JSON.stringify({ ...manifest, hash: MD5(finalDistJs) }));
}
2 changes: 1 addition & 1 deletion packages/lune/src/commands/build.ts
Original file line number Diff line number Diff line change
@@ -1,4 +1,4 @@
import type { Command } from ".";
import type { Command } from "./index.js";

import { hrtime } from "process";
import { buildPlugin } from "../builder.js";
Expand Down
2 changes: 1 addition & 1 deletion packages/lune/src/commands/ci.ts
Original file line number Diff line number Diff line change
@@ -1,4 +1,4 @@
import type { Command } from ".";
import type { Command } from "./index.js";

import { hrtime } from "process";
import { resolve } from "path";
Expand Down
2 changes: 1 addition & 1 deletion packages/lune/src/commands/dev.ts
Original file line number Diff line number Diff line change
@@ -1,4 +1,4 @@
import type { Command } from ".";
import type { Command } from "./index.js";

import { createServer } from "http";
import { WebSocketServer } from "ws";
Expand Down
2 changes: 1 addition & 1 deletion packages/lune/src/commands/init.ts
Original file line number Diff line number Diff line change
@@ -1,4 +1,4 @@
import type { Command } from ".";
import type { Command } from "./index.js";
import { createInterface } from "readline/promises";
import { stdin, stdout, cwd } from "process";
import { resolve } from "path";
Expand Down
43 changes: 31 additions & 12 deletions packages/lune/src/config.ts
Original file line number Diff line number Diff line change
@@ -1,26 +1,45 @@
import type { Plugin } from "esbuild";

import type { UserConfig } from "@farmfe/core";
import { existsSync } from "fs";
import { resolve, parse } from "path";
import { pathToFileURL } from "url";

export interface LuneCfg {
/**
* If CSS Modules should be enabled
* @default false
*/
cssModules?: boolean | "legacy";
export type LuneCfg = {
/**
* If the output should be minified
* @default false
*/
minify?: boolean;
} & (
| {
/**
* If Farm should be used instead of esbuild
*/
useFarm?: false;

/** esbuild plugins that run before Lune's transforms */
prePlugins?: Plugin[];
/** esbuild plugins that run after Lune's transforms */
postPlugins?: Plugin[];
}
/**
* If CSS Modules should be enabled
* @default false
*/
cssModules?: boolean | "legacy";
yellowsink marked this conversation as resolved.
Show resolved Hide resolved

/** esbuild plugins that run before Lune's transforms */
prePlugins?: Plugin[];
/** esbuild plugins that run after Lune's transforms */
postPlugins?: Plugin[];
}
| {
/**
* If Farm should be used instead of esbuild
*/
useFarm: true;

/** A list of Vite / Rollup plugins */
vitePlugins?: any[];
/** A list of Farm plugins */
farmPlugins?: UserConfig["plugins"];
}
);

export async function loadCfg(path?: string) {
if (!path || !existsSync(resolve(path))) return null;
Expand Down
17 changes: 17 additions & 0 deletions packages/lune/src/farmbuilder.ts
Original file line number Diff line number Diff line change
@@ -0,0 +1,17 @@
import type { FarmCLIOptions, UserConfig } from "@farmfe/core";
import { createCompiler, resolveConfig } from "@farmfe/core";
import { NoopLogger } from "@farmfe/core";

export async function buildToString(inlineConfig: FarmCLIOptions & UserConfig): Promise<string> {
const logger = new NoopLogger();

const resolvedUserConfig = await resolveConfig(inlineConfig, "production", logger, false);

const compiler = await createCompiler(resolvedUserConfig, logger);
await compiler.compile();

return Object.entries(compiler.resources())
.filter(([n]) => n.endsWith(".js"))
.map(([_, f]) => f.toString())
.join(";");
}
2 changes: 1 addition & 1 deletion packages/lune/src/mod.ts
Original file line number Diff line number Diff line change
@@ -1,4 +1,4 @@
// this is the file imported by packages, not ran by the CLI
import type { LuneCfg } from "./config";
import type { LuneCfg } from "./config.js";

export const defineConfig = (cfg: LuneCfg) => cfg;
5 changes: 3 additions & 2 deletions packages/lune/tsconfig.json
Original file line number Diff line number Diff line change
Expand Up @@ -3,10 +3,11 @@
"compilerOptions": {
"target": "ESNext",
"module": "ESNext",
"moduleResolution": "node",
"moduleResolution": "Node",
"declaration": true,
"outDir": "dist",
"allowSyntheticDefaultImports": true,
"resolveJsonModule": true
"resolveJsonModule": true,
"skipLibCheck": true
yellowsink marked this conversation as resolved.
Show resolved Hide resolved
}
}
Loading