Skip to content

Commit

Permalink
fix(packem): major codebase restructuring and improvements
Browse files Browse the repository at this point in the history
- refactor(cli): move CLI-related files to dedicated cli/ directory
- refactor(config): reorganize configuration-related files into config/ directory
  - Move preset and utils from hooks/ to config/
  - Add new config utilities for TypeScript and Packem config loading
- Improve file name handling with path normalization
- feat(types): update type definitions and normalize package.json types
- chore(deps): update package dependencies and configurations
- test: update test files to reflect new directory structure
  • Loading branch information
prisis committed Jan 27, 2025
1 parent 71bf7b2 commit f71710e
Show file tree
Hide file tree
Showing 27 changed files with 369 additions and 223 deletions.
39 changes: 39 additions & 0 deletions packages/packem/README.md
Original file line number Diff line number Diff line change
Expand Up @@ -495,6 +495,45 @@ This will replace all instances of `process.env.NODE_ENV` with `'production'` an
packem build --env.NODE_ENV=production
```
## Programmatic Usage
You can use Packem programmatically in your Node.js applications without the CLI:
```typescript
import { packem } from '@visulima/packem';

// Basic usage
await packem('./src', {
mode: 'build',
environment: 'production'
});

// With custom options
await packem('./src', {
mode: 'build',
environment: 'development',
declaration: true,
minify: true,
sourcemap: true,
logger: {
// Custom logger options
level: 'debug'
}
});
```
The `packem` function accepts the following parameters:
- `rootDirectory` (string): The root directory of your project to bundle
- `options` (PackemOptions): Configuration options that extend the BuildConfig interface
- `mode`: The build mode ('build' | 'watch')
- `environment`: The target environment ('development' | 'production')
- `declaration`: Enable/disable TypeScript declaration file generation
- `minify`: Enable/disable code minification
- `sourcemap`: Enable/disable source map generation
- `logger`: Logger configuration options
For more detailed configuration options, refer to the [Configuration](#configuration) section.
## Validators
### Package.json Validation
Expand Down
3 changes: 2 additions & 1 deletion packages/packem/__tests__/helpers/exec-packem-sync.ts
Original file line number Diff line number Diff line change
Expand Up @@ -15,14 +15,15 @@ const execPackemSync = async (command: "build" | "init", flags: string[] = [], o
}

if (flags.includes("--no-environment")) {
// eslint-disable-next-line no-param-reassign
flags = flags.filter((flag) => flag !== "--no-environment");
}

if (!flags.includes("--validation")) {
flags.push("--no-validation");
}

return await execaNode(join(distributionPath, "cli.mjs"), [command, environmentFlag, ...flags].filter(Boolean) as string[], {
return await execaNode(join(distributionPath, "cli/index.mjs"), [command, environmentFlag, ...flags].filter(Boolean) as string[], {
cleanup: true,
...options,
});
Expand Down
2 changes: 0 additions & 2 deletions packages/packem/__tests__/intigration/jit.test.ts
Original file line number Diff line number Diff line change
Expand Up @@ -68,7 +68,6 @@ describe("packem build --jit", () => {
const jiti = createJiti(__filename, {
"alias": {},
"debug": false,
"interopDefault": true,
"transformOptions": {
"babel": {
Expand Down Expand Up @@ -99,7 +98,6 @@ export { default } from "${temporaryDirectoryPath}/src/index.d.cts";`);
const jiti = createJiti(import.meta.url, {
"alias": {},
"debug": false,
"interopDefault": true,
"transformOptions": {
"babel": {
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -5,7 +5,7 @@ import { join } from "@visulima/path";
import { temporaryDirectory } from "tempy";
import { afterEach, beforeEach, describe, expect, it, vi } from "vitest";

import inferEntries from "../../../../../src/hooks/preset/utils/infer-entries";
import inferEntries from "../../../../../src/config/preset/utils/infer-entries";
import type { BuildContext, InferEntriesResult } from "../../../../../src/types";

const createFiles = (files: string[], directory: string) => {
Expand Down
Original file line number Diff line number Diff line change
@@ -1,7 +1,7 @@
import type { NormalizedPackageJson } from "@visulima/package";
import { describe, expect, it } from "vitest";

import overwriteWithPublishConfig from "../../../src/hooks/preset/utils/overwrite-with-publish-config";
import overwriteWithPublishConfig from "../../../src/config/preset/utils/overwrite-with-publish-config";

describe("overwriteWithPublishConfig", () => {
it("should correctly overwrite package.json properties with publishConfig properties when they exist", () => {
Expand Down
16 changes: 8 additions & 8 deletions packages/packem/package.json
Original file line number Diff line number Diff line change
Expand Up @@ -72,12 +72,12 @@
"exports": {
".": {
"import": {
"types": "./dist/packem/index.d.mts",
"default": "./dist/packem/index.mjs"
"types": "./dist/index.d.mts",
"default": "./dist/index.mjs"
},
"require": {
"types": "./dist/packem/index.d.cts",
"default": "./dist/packem/index.cjs"
"types": "./dist/index.d.cts",
"default": "./dist/index.cjs"
}
},
"./config": {
Expand Down Expand Up @@ -271,7 +271,7 @@
"typesVersions": {
">=5.5": {
".": [
"./dist/packem/index.d.ts"
"./dist/index.d.ts"
],
"config": [
"./dist/config/index.d.ts"
Expand Down Expand Up @@ -330,7 +330,7 @@
}
},
"bin": {
"packem": "./dist/cli.mjs"
"packem": "./dist/cli/index.mjs"
},
"files": [
"dist",
Expand All @@ -340,8 +340,8 @@
"LICENSE.md"
],
"scripts": {
"build": "cross-env INTERNAL_PACKEM_BUILD=1 JITI_INTEROP_DEFAULT=1 jiti ./src/cli.ts build --development",
"build:prod": "cross-env INTERNAL_PACKEM_BUILD=1 JITI_INTEROP_DEFAULT=1 jiti ./src/cli.ts build --production",
"build": "cross-env INTERNAL_PACKEM_BUILD=1 JITI_INTEROP_DEFAULT=1 jiti src/cli/index.ts build --development",
"build:prod": "cross-env INTERNAL_PACKEM_BUILD=1 JITI_INTEROP_DEFAULT=1 jiti src/cli/index.ts build --production",
"clean": "rimraf node_modules dist .eslintcache",
"dev": "pnpm run build",
"lint:attw": "attw --pack",
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -7,7 +7,7 @@ import { readFile, writeFile } from "@visulima/fs";
import { resolve } from "@visulima/path";
import MagicString from "magic-string";

import findPackemFile from "../utils/find-packem-file";
import findPackemFile from "../../config/utils/find-packem-file";
import cssLoaderDependencies from "./utils/css-loader-dependencies";

const typedocPackages = ["typedoc", "typedoc-plugin-markdown", "typedoc-plugin-rename-defaults"];
Expand Down
Original file line number Diff line number Diff line change
@@ -1,10 +1,15 @@
import { exit } from "node:process";
import { cwd, exit } from "node:process";

import type { Cli } from "@visulima/cerebro";
import { resolve } from "@visulima/path";
import { defu } from "defu";
import { createJiti } from "jiti";

import { DEVELOPMENT_ENV, PRODUCTION_ENV } from "../constants";
import packem from "../packem";
import type { Environment, Mode } from "../types";
import { DEVELOPMENT_ENV, PRODUCTION_ENV } from "../../constants";
import packem from "../../packem";
import type { BuildConfig, Environment, Mode } from "../../types";
import loadPackemConfig from "../../config/utils/load-packem-config";
import loadPreset from "../../config/utils/load-preset";

/**
* Creates and registers the build command with the CLI.
Expand Down Expand Up @@ -73,51 +78,71 @@ const createBuildCommand = (cli: Cli): void => {
}
}

const rootPath = resolve(cwd(), options.dir ?? ".");

const jiti = createJiti(rootPath, { debug: options.debug });
const { config: buildConfig, path: buildConfigPath } = await loadPackemConfig(
jiti,
rootPath,
nodeEnvironment as Environment,
mode,
options.config ?? undefined,
);

logger.debug("Using packem config found at", buildConfigPath);

const preset = await loadPreset(buildConfig.preset ?? "auto", jiti);

try {
await packem(options.dir, mode, nodeEnvironment as Environment, logger, {
analyze: options.analyze,
cjsInterop: options.cjsInterop,
clean: options.clean,
configPath: options.config ?? undefined,
debug: options.debug,
dtsOnly: options.dtsOnly,
externals,
killSignal: options.killSignal,
minify: options.minify === undefined ? nodeEnvironment === PRODUCTION_ENV : options.minify,
onSuccess: options.onSuccess,
rollup: {
esbuild: {
target: options.target,
await packem(
rootPath,
mode,
nodeEnvironment as Environment,
logger,
options.debug,
defu<BuildConfig, BuildConfig[]>(buildConfig, preset, {
analyze: options.analyze,
cjsInterop: options.cjsInterop,
clean: options.clean,
dtsOnly: options.dtsOnly,
externals,
killSignal: options.killSignal,
minify: options.minify === undefined ? nodeEnvironment === PRODUCTION_ENV : options.minify,
onSuccess: options.onSuccess,
rollup: {
esbuild: {
target: options.target,
},
license: {
path: options.license,
},
metafile: options.metafile,
replace: {
values: environments,
},
resolveExternals: options.noExternal
? {
builtins: false,
deps: false,
devDeps: false,
optDeps: false,
peerDeps: false,
}
: {},
},
license: {
path: options.license,
},
metafile: options.metafile,
replace: {
values: environments,
},
resolveExternals: options.noExternal
runtime: options.runtime,
sourcemap: options.metafile || options.analyze || options.sourcemap,
validation: options.validation,
...(options.typedoc
? {
builtins: false,
deps: false,
devDeps: false,
optDeps: false,
peerDeps: false,
typedoc: {
format: "html",
},
}
: {},
},
runtime: options.runtime,
sourcemap: options.metafile || options.analyze || options.sourcemap,
tsconfigPath: options.tsconfig ?? undefined,
validation: options.validation,
...(options.typedoc
? {
typedoc: {
format: "html",
},
}
: {}),
});
: {}),
}),
options.tsconfig ?? undefined,
);
} catch (error) {
logger.error(error);

Expand Down Expand Up @@ -274,7 +299,7 @@ const createBuildCommand = (cli: Cli): void => {

throw new Error("Invalid runtime. Use 'node' or 'browser'.");
},
}
},
],
});
};
Expand Down
File renamed without changes.
12 changes: 6 additions & 6 deletions packages/packem/src/cli.ts → packages/packem/src/cli/index.ts
Original file line number Diff line number Diff line change
Expand Up @@ -2,7 +2,7 @@
import Cli from "@visulima/cerebro";
import { SimpleReporter } from "@visulima/pail/reporter";

import { name, version } from "../package.json";
import { name, version } from "../../package.json";
import createAddCommand from "./commands/add";
import createBuildCommand from "./commands/build";
import createInitCommand from "./commands/init";
Expand Down Expand Up @@ -41,7 +41,7 @@ try {
* await cli.run(['build', '--watch']);
* ```
*/
const cli = new Cli("packem", {
const index = new Cli("packem", {
logger: {
reporters: [
new SimpleReporter({
Expand All @@ -59,13 +59,13 @@ const cli = new Cli("packem", {
});

// Register available commands
createInitCommand(cli);
createInitCommand(index);
// eslint-disable-next-line etc/no-internal
createBuildCommand(cli);
createAddCommand(cli);
createBuildCommand(index);
createAddCommand(index);

// Run the CLI without exiting the process
// eslint-disable-next-line no-void
void cli.run({
void index.run({
shouldExitProcess: false,
});
16 changes: 2 additions & 14 deletions packages/packem/src/config/index.ts
Original file line number Diff line number Diff line change
@@ -1,19 +1,7 @@
import type { BuildConfig, BuildPreset, Environment, Mode } from "../types";

/**
* Function type for dynamic build configuration.
* Allows configuration to be generated based on environment and mode.
*
* @param environment - The build environment (development/production)
* @param mode - The build mode (build/watch)
* @returns Build configuration object or Promise resolving to one
*
* @public
*/
export type BuildConfigFunction = (environment: Environment, mode: Mode) => BuildConfig | Promise<BuildConfig>;
import type { BuildConfig, BuildConfigFunction, BuildPreset } from "../types";

// eslint-disable-next-line import/no-unused-modules
export type { BuildConfig, BuildHooks, BuildPreset } from "../types";
export type { BuildConfig, BuildConfigFunction, BuildHooks, BuildPreset } from "../types";

/**
* Defines a build configuration for Packem.
Expand Down
File renamed without changes.
Original file line number Diff line number Diff line change
@@ -1,12 +1,12 @@
import { isAccessibleSync } from "@visulima/fs";
import type { PackageJson } from "@visulima/package";
import type { NormalizedPackageJson } from "@visulima/package";
import { parsePackageJson } from "@visulima/package/package-json";
import { join } from "@visulima/path";

const loadPackageJson = (
rootDirectory: string,
): {
packageJson: PackageJson;
packageJson: NormalizedPackageJson;
packageJsonPath: string;
} => {
const packageJsonPath = join(rootDirectory, "package.json");
Expand Down
24 changes: 24 additions & 0 deletions packages/packem/src/config/utils/load-packem-config.ts
Original file line number Diff line number Diff line change
@@ -0,0 +1,24 @@
import findPackemFile from "./find-packem-file";
import type { BuildConfigFunction, BuildConfig, Environment, Mode } from "../../types";
import type { Jiti } from "jiti";

const loadPackemConfig = async (jiti: Jiti, rootDirectory: string, environment: Environment, mode: Mode, configPath?: string): Promise<{
config: BuildConfig;
path: string;
}> => {
const packemConfigFilePath = await findPackemFile(rootDirectory, configPath);

// eslint-disable-next-line @typescript-eslint/no-unnecessary-condition
let buildConfig = ((await jiti.import(packemConfigFilePath, { default: true, try: true })) || {}) as BuildConfig | BuildConfigFunction;

if (typeof buildConfig === "function") {
buildConfig = await buildConfig(environment, mode);
}

return {
config: buildConfig,
path: packemConfigFilePath,
};
};

export default loadPackemConfig;
Loading

0 comments on commit f71710e

Please sign in to comment.