Skip to content

Commit

Permalink
feat: Add import option
Browse files Browse the repository at this point in the history
  • Loading branch information
tommy351 committed Jun 8, 2024
1 parent 94e94f2 commit 1c4c852
Show file tree
Hide file tree
Showing 35 changed files with 701 additions and 533 deletions.
5 changes: 5 additions & 0 deletions .changeset/friendly-walls-shave.md
Original file line number Diff line number Diff line change
@@ -0,0 +1,5 @@
---
"@kosko/require": minor
---

Remove `ESM_IMPORT_DISABLED` environment variable.
5 changes: 5 additions & 0 deletions .changeset/funny-chefs-smile.md
Original file line number Diff line number Diff line change
@@ -0,0 +1,5 @@
---
"@kosko/require": minor
---

Handle `ERR_VM_DYNAMIC_IMPORT_CALLBACK_MISSING_FLAG` errors.
5 changes: 5 additions & 0 deletions .changeset/red-forks-cheer.md
Original file line number Diff line number Diff line change
@@ -0,0 +1,5 @@
---
"@kosko/require": minor
---

Use import attributes when importing JSON files.
5 changes: 5 additions & 0 deletions .changeset/serious-clouds-march.md
Original file line number Diff line number Diff line change
@@ -0,0 +1,5 @@
---
"@kosko/cli": minor
---

Add `--import` option to `generate` and `validate` command.
5 changes: 5 additions & 0 deletions .changeset/slimy-clocks-trade.md
Original file line number Diff line number Diff line change
@@ -0,0 +1,5 @@
---
"@kosko/config": minor
---

Add `import` option.
3 changes: 2 additions & 1 deletion internal/build-scripts/bin/build-scripts.js
Original file line number Diff line number Diff line change
Expand Up @@ -46,7 +46,7 @@ const typesPath = args.types ? join(cwd, args.types) : fullDistPath;
* @param {{
* suffixes?: readonly string[];
* output: string;
* format: import("rollup").ModuleFormat;
* format: 'cjs' | 'esm';
* importMetaUrlShim?: boolean;
* target: 'browser' | 'node';
* reuse?: string;
Expand Down Expand Up @@ -87,6 +87,7 @@ export const BUILD_PROD = true;
export const BUILD_TARGET = ${JSON.stringify(options.target)};
export const BUILD_FORMAT = ${JSON.stringify(options.format)};
export const TARGET_SUFFIX = ${JSON.stringify(options.output)};
export const ESM_IMPORT_DISABLED = false;
`
}),
replace({
Expand Down
1 change: 1 addition & 0 deletions internal/build-scripts/index.cjs
Original file line number Diff line number Diff line change
Expand Up @@ -5,3 +5,4 @@ exports.BUILD_PROD = false;
exports.BUILD_TARGET = "node";
exports.BUILD_FORMAT = "cjs";
exports.TARGET_SUFFIX = ".js";
exports.ESM_IMPORT_DISABLED = !!process.env.ESM_IMPORT_DISABLED;
2 changes: 1 addition & 1 deletion internal/build-scripts/package.json
Original file line number Diff line number Diff line change
Expand Up @@ -15,7 +15,7 @@
"@rollup/plugin-replace": "^5.0.5",
"@rollup/plugin-swc": "^0.3.0",
"@rollup/plugin-virtual": "^3.0.2",
"@swc/core": "^1.4.8",
"@swc/core": "^1.5.25",
"@swc/helpers": "^0.5.6",
"execa": "^5.1.1",
"globby": "^11.0.2",
Expand Down
5 changes: 2 additions & 3 deletions internal/build-scripts/types.d.ts
Original file line number Diff line number Diff line change
@@ -1,6 +1,5 @@
import type { ModuleFormat } from "rollup";

export const BUILD_PROD: boolean;
export const BUILD_TARGET: "browser" | "node";
export const BUILD_FORMAT: ModuleFormat;
export const BUILD_FORMAT: "cjs" | "esm";
export const TARGET_SUFFIX: string;
export const ESM_IMPORT_DISABLED: boolean;
2 changes: 1 addition & 1 deletion internal/jest-preset/package.json
Original file line number Diff line number Diff line change
Expand Up @@ -7,7 +7,7 @@
},
"dependencies": {
"@kosko/jest-serializer-path": "workspace:^",
"@swc/core": "^1.4.8",
"@swc/core": "^1.5.25",
"@swc/helpers": "^0.5.6",
"@swc/jest": "^0.2.36",
"jest-environment-node": "^29.7.0",
Expand Down
9 changes: 7 additions & 2 deletions package.json
Original file line number Diff line number Diff line change
Expand Up @@ -56,7 +56,7 @@
"jest": "^29.3.1",
"jest-extended": "^4.0.2",
"jest-puppeteer": "^10.0.0",
"kubernetes-models": "^4.1.0",
"kubernetes-models": "^4.3.2",
"lint-staged": "^13.0.3",
"npm-run-all": "^4.1.5",
"prettier": "^3.2.5",
Expand All @@ -78,5 +78,10 @@
"packages/*/package.json"
]
},
"packageManager": "[email protected]"
"packageManager": "[email protected]",
"pnpm": {
"overrides": {
"@kubernetes-models/validate": "0.0.0-20240608085410"
}
}
}
Original file line number Diff line number Diff line change
Expand Up @@ -75,10 +75,12 @@ Options:
--bail Stop immediately when an error occurred. [boolean]
-s, --set Set values on the command line KEY=VAL (can be used multiple
times) [array] [default: []]
-r, --require Require modules. Modules set in config file will also be
-r, --require Require CommonJS modules. Modules set in config file are also
required. [array]
--loader Module loader. Loaders set in config file will also be loaded.
--loader Module loader. Loaders set in config file are also loaded.
[array]
--import Preload ES modules at startup. Modules set in config file are
also imported. [array]
-o, --output Output format
[string] [choices: "yaml", "json"] [default: "yaml"]
--validate Validate components [boolean] [default: true]
Expand Down Expand Up @@ -240,10 +242,12 @@ Options:
--bail Stop immediately when an error occurred. [boolean]
-s, --set Set values on the command line KEY=VAL (can be used multiple
times) [array] [default: []]
-r, --require Require modules. Modules set in config file will also be
-r, --require Require CommonJS modules. Modules set in config file are also
required. [array]
--loader Module loader. Loaders set in config file will also be loaded.
--loader Module loader. Loaders set in config file are also loaded.
[array]
--import Preload ES modules at startup. Modules set in config file are
also imported. [array]
-o, --output Output format
[string] [choices: "yaml", "json"] [default: "yaml"]
--validate Validate components [boolean] [default: true]
Expand Down Expand Up @@ -327,10 +331,12 @@ Options:
--bail Stop immediately when an error occurred. [boolean]
-s, --set Set values on the command line KEY=VAL (can be used multiple
times) [array] [default: []]
-r, --require Require modules. Modules set in config file will also be
-r, --require Require CommonJS modules. Modules set in config file are also
required. [array]
--loader Module loader. Loaders set in config file will also be loaded.
--loader Module loader. Loaders set in config file are also loaded.
[array]
--import Preload ES modules at startup. Modules set in config file are
also imported. [array]
-o, --output Output format
[string] [choices: "yaml", "json"] [default: "yaml"]
--validate Validate components [boolean] [default: true]
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -13,3 +13,17 @@ kind: Pod
metadata:
name: test-pod"
`;

exports[`should use import specified in args 1`] = `
"apiVersion: v1
kind: Pod
metadata:
name: test-pod"
`;

exports[`should use import specified in config 1`] = `
"apiVersion: v1
kind: Pod
metadata:
name: test-pod"
`;
20 changes: 17 additions & 3 deletions packages/cli/integration/generate-ts-mjs/__tests__/index.ts
Original file line number Diff line number Diff line change
Expand Up @@ -13,9 +13,23 @@ test("should load loaders specified in args", async () => {
test("should load loaders specified in config", async () => {
const result = await runNodeCLI(
["generate", "--config", "kosko-loader.toml"],
{
cwd: testDir
}
{ cwd: testDir }
);
expect(result.stdout).toMatchSnapshot();
});

test("should use import specified in args", async () => {
const result = await runNodeCLI(
["generate", "--import", "@swc-node/register/esm-register"],
{ cwd: testDir, stderr: "inherit" }
);
expect(result.stdout).toMatchSnapshot();
});

test("should use import specified in config", async () => {
const result = await runNodeCLI(
["generate", "--config", "kosko-import.toml"],
{ cwd: testDir, stderr: "inherit" }
);
expect(result.stdout).toMatchSnapshot();
});
3 changes: 3 additions & 0 deletions packages/cli/integration/generate-ts-mjs/kosko-import.toml
Original file line number Diff line number Diff line change
@@ -0,0 +1,3 @@
components = ["*"]
import = ["@swc-node/register/esm-register"]
extensions = ["ts"]
7 changes: 5 additions & 2 deletions packages/cli/package.json
Original file line number Diff line number Diff line change
Expand Up @@ -73,16 +73,19 @@
"@kosko/jest-preset": "workspace:^",
"@kosko/plugin": "workspace:^",
"@kosko/test-utils": "workspace:^",
"@swc-node/register": "^1.9.1",
"@swc/core": "^1.5.25",
"@types/bl": "^5.0.2",
"@types/exit": "^0.1.31",
"@types/jsonpath": "^0.2.0",
"@types/yargs": "^17.0.12",
"bl": "^5.0.0",
"execa": "^5.1.1",
"fast-glob": "^3.2.12",
"kubernetes-models": "^4.1.0",
"kubernetes-models": "^4.3.2",
"pkg-dir": "^5.0.0",
"replace-string": "^3.1.0"
"replace-string": "^3.1.0",
"ts-node": "^10.9.2"
},
"jest": {
"preset": "@kosko/jest-preset"
Expand Down
1 change: 1 addition & 0 deletions packages/cli/src/commands/generate/__tests__/command.ts
Original file line number Diff line number Diff line change
@@ -1,3 +1,4 @@
/// <reference types="jest-extended" />
import toml from "@iarna/toml";
import { Config } from "@kosko/config";
import { Environment } from "@kosko/env";
Expand Down
9 changes: 7 additions & 2 deletions packages/cli/src/commands/generate/command.ts
Original file line number Diff line number Diff line change
Expand Up @@ -48,14 +48,19 @@ export function generateBuilder(
type: "string",
array: true,
describe:
"Require modules. Modules set in config file will also be required.",
"Require CommonJS modules. Modules set in config file are also required.",
alias: "r"
})
.option("loader", {
type: "string",
array: true,
describe: "Module loader. Loaders set in config file are also loaded."
})
.option("import", {
type: "string",
array: true,
describe:
"Module loader. Loaders set in config file will also be loaded."
"Preload ES modules at startup. Modules set in config file are also imported."
});
}

Expand Down
9 changes: 8 additions & 1 deletion packages/cli/src/commands/generate/config.ts
Original file line number Diff line number Diff line change
Expand Up @@ -14,13 +14,20 @@ export async function loadConfig(args: BaseGenerateArguments) {
const envs = [base.baseEnvironment, args.env].filter(
(env): env is string => typeof env === "string"
);
const { components, require, loaders, plugins } = getConfig(base, envs);
const {
components,
require,
loaders,
plugins,
import: imp
} = getConfig(base, envs);
const config = {
...base,
plugins,
components: args.components?.length ? args.components : components,
require: [...require, ...(args.require || [])],
loaders: [...loaders, ...(args.loader || [])],
import: [...imp, ...(args.import || [])],
bail: args.bail ?? base.bail
};

Expand Down
17 changes: 12 additions & 5 deletions packages/cli/src/commands/generate/env.ts
Original file line number Diff line number Diff line change
Expand Up @@ -6,10 +6,13 @@ import pkgUp from "pkg-up";
import { dirname, join } from "node:path";
import { readFile } from "node:fs/promises";
import { pathToFileURL } from "node:url";
import { env } from "node:process";
import { excludeFalsyInArray } from "../../utils";
import { resolveModule } from "@kosko/require";
import { BUILD_TARGET } from "@kosko/build-scripts";
import {
BUILD_FORMAT,
BUILD_TARGET,
ESM_IMPORT_DISABLED
} from "@kosko/build-scripts";

const KOSKO_ENV = "@kosko/env";

Expand Down Expand Up @@ -43,15 +46,19 @@ async function importEnvNode(cwd: string): Promise<Environment[]> {

const envs: Environment[] = [];

// eslint-disable-next-line @typescript-eslint/no-var-requires
envs.push(require(envPath));
if (BUILD_FORMAT === "cjs") {
// eslint-disable-next-line @typescript-eslint/no-var-requires
envs.push(require(envPath));
} else {

Check warning on line 52 in packages/cli/src/commands/generate/env.ts

View check run for this annotation

Codecov / codecov/patch

packages/cli/src/commands/generate/env.ts#L52

Added line #L52 was not covered by tests
// TODO: Import CommonJS @kosko/env in ESM environment
}

// Why `@kosko/env` package has to be imported twice? Because the cache on
// CommonJS and ESM are separated, which means we have two isolated
// instances of `Environment`, and each of them must be initialized
// in order to make sure users can access the environment in both CommonJS
// and ESM environment.
if (env.ESM_IMPORT_DISABLED !== "1") {
if (!ESM_IMPORT_DISABLED) {
const envModUrl = await getESMEntry(dirname(envPath));

if (envModUrl) {
Expand Down
1 change: 1 addition & 0 deletions packages/cli/src/commands/generate/types.ts
Original file line number Diff line number Diff line change
Expand Up @@ -11,6 +11,7 @@ export interface BaseGenerateArguments extends GlobalArguments {
loader?: string[];
config?: string;
bail?: boolean;
import?: string[];
}

export interface GenerateArguments extends BaseGenerateArguments {
Expand Down
14 changes: 10 additions & 4 deletions packages/cli/src/commands/generate/worker.ts
Original file line number Diff line number Diff line change
Expand Up @@ -11,7 +11,7 @@ import { fileURLToPath } from "node:url";
import { stdout, execPath, execArgv } from "node:process";
import { createRequire } from "node:module";
import { loadPlugins } from "./plugin";
import { BUILD_TARGET, TARGET_SUFFIX } from "@kosko/build-scripts";
import { BUILD_TARGET } from "@kosko/build-scripts";

export interface WorkerOptions {
printFormat?: PrintFormat;
Expand All @@ -23,7 +23,11 @@ export interface WorkerOptions {
export async function handler(options: WorkerOptions) {
const { printFormat, args, config, ignoreLoaders } = options;

if (BUILD_TARGET === "node" && !ignoreLoaders && config.loaders.length) {
if (
BUILD_TARGET === "node" &&
!ignoreLoaders &&
(config.loaders.length || config.import.length)
) {
await runWithLoaders(options);
return;
}
Expand Down Expand Up @@ -90,8 +94,10 @@ async function runWithLoaders(options: WorkerOptions) {
...execArgv,
// ESM loaders
...options.config.loaders.flatMap((loader) => ["--loader", loader]),
// Entry file
join(fileURLToPath(import.meta.url), "../worker-bin." + TARGET_SUFFIX)
// ESM import
...options.config.import.flatMap((imp) => ["--import", imp]),

Check warning on line 98 in packages/cli/src/commands/generate/worker.ts

View check run for this annotation

Codecov / codecov/patch

packages/cli/src/commands/generate/worker.ts#L98

Added line #L98 was not covered by tests
// Entry file. Always use ESM entry file.
join(fileURLToPath(import.meta.url), "../worker-bin.node.mjs")
],
{
stdio: ["pipe", "inherit", "inherit"],
Expand Down
Loading

0 comments on commit 1c4c852

Please sign in to comment.