From 8468e8a0d1591138b32b16c68c293868b4b4f361 Mon Sep 17 00:00:00 2001 From: Klaus Reimer Date: Tue, 3 Jun 2025 23:35:27 +0200 Subject: [PATCH 1/6] Implement support for a JSON configuration file --- README.md | 18 ++++++++++++++++++ src/cli.mjs | 21 +++++++++++++++------ 2 files changed, 33 insertions(+), 6 deletions(-) diff --git a/README.md b/README.md index d32e764..ae670de 100644 --- a/README.md +++ b/README.md @@ -55,6 +55,24 @@ The CLI supports the following options: - `--entrypoint `: Confirm the specified file and its transitive dependencies can be resolved using the generated import map. Auto-enabled when importmap is written into an HTML file. Can be specified multiple times. - `--dev`: Include devDependencies from `package.json`. Also favor `"development"` in [package exports](https://nodejs.org/docs/latest-v16.x/api/packages.html#packages_conditions_definitions). - `--keep-unused`: Keep all mappings, even if they are not currently used by entry file or its transitive dependencies. +- `--config `: Read additional settings from the given JSON configuration file. + +#### Configuration file + +A configuration file in JSON format can be specified with the `--config` CLI option. The following example shows such a JSON file with all supported properties set to their default values: + +```json +{ + "dir": ".", + "dev": false, + "keepUnused": false, + "entryPoints": [], + "manualImportmap": {}, + "packagesManualOverrides": {} +} +``` + +All properties are optional and CLI options like `--dev`, `--entrypoint` and `--keep-unused` will override the values read from the config. The objects `manualImportmap` and `packagesManualOverrides` have the same format as the corresponding objects in the API. ### API diff --git a/src/cli.mjs b/src/cli.mjs index 5f2189b..187e3ce 100755 --- a/src/cli.mjs +++ b/src/cli.mjs @@ -1,5 +1,6 @@ #!/usr/bin/env node +import { readFile } from "node:fs/promises"; import { pathToFileURL } from "node:url"; import { parseArgs } from "node:util"; import { writeImportmaps } from "./main.js"; @@ -21,10 +22,12 @@ const options = { "keep-unused": { type: "boolean", }, + "config": { + type: "string", + }, }; const { values, positionals } = parseArgs({ options, allowPositionals: true }); const outfile = positionals[0]; -values.entrypoint ??= []; if (values.help || positionals.length === 0) { usage(); @@ -46,21 +49,26 @@ if ( process.exit(1); } +const config = values.config ? JSON.parse(await readFile(values.config)) : {}; +const dev = values.dev ?? config.dev; + const currentDirectoryUrl = pathToFileURL(`${process.cwd()}/`); await writeImportmaps({ - directoryUrl: new URL(values.dir || ".", currentDirectoryUrl), + directoryUrl: new URL(values.dir ?? config.dir ?? ".", currentDirectoryUrl), importmaps: { [outfile]: { nodeMappings: { - devDependencies: values.dev, - packageUserConditions: values.dev ? ["development"] : [], + devDependencies: dev, + packageUserConditions: dev ? ["development"] : [], }, importResolution: { - entryPoints: values.entryPoints, + entryPoints: values.entrypoint ?? config.entryPoints ?? [], }, - keepUnusedMappings: values["keep-unused"], + keepUnusedMappings: values["keep-unused"] ?? config.keepUnused, + manualImportmap: config.manualImportmap, }, }, + packagesManualOverrides: config.packagesManualOverrides, }); function usage() { @@ -76,6 +84,7 @@ Options: --entrypoint file.js Confirm the specified file and its transitive dependencies can be resolved using the generated import map. Can be specified multiple times. --dev Include devDependencies from package.json and pick "developement" in package conditions. --keep-unused Remove mappings not used by any entrypoint or their transitive dependencies. Requires --entrypoint. + --config config.json Read additional settings from the given JSON configuration file. For more advanced options, see the API.`); } From 29a7de11cd706a4ac405da4db97f74d89f2b585c Mon Sep 17 00:00:00 2001 From: Klaus Reimer Date: Tue, 3 Jun 2025 23:41:25 +0200 Subject: [PATCH 2/6] Add missing encoding parameter --- src/cli.mjs | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/src/cli.mjs b/src/cli.mjs index 187e3ce..1ace50b 100755 --- a/src/cli.mjs +++ b/src/cli.mjs @@ -49,7 +49,7 @@ if ( process.exit(1); } -const config = values.config ? JSON.parse(await readFile(values.config)) : {}; +const config = values.config ? JSON.parse(await readFile(values.config, "utf-8")) : {}; const dev = values.dev ?? config.dev; const currentDirectoryUrl = pathToFileURL(`${process.cwd()}/`); From ce7a68cd2dd28a0726e02b085a6fa71083f728b9 Mon Sep 17 00:00:00 2001 From: dmail Date: Thu, 5 Jun 2025 15:35:26 +0200 Subject: [PATCH 3/6] prepare cli test --- tests/cli/basic/cli_basic.test.mjs | 19 +++++++++++++++++++ tests/cli/{ => basic}/fixtures/index.html | 0 tests/cli/{ => basic}/fixtures/main.js | 0 .../fixtures/node_modules/foo/foo.js | 0 .../fixtures/node_modules/foo/package.json | 0 tests/cli/{ => basic}/fixtures/package.json | 0 tests/cli/{ => basic}/snapshots/index.html | 0 .../cli_config_file.test.mjs} | 0 tests/cli/config_file/fixtures/index.html | 12 ++++++++++++ tests/cli/config_file/fixtures/main.js | 1 + .../fixtures/node_modules/foo/foo.js | 1 + .../fixtures/node_modules/foo/package.json | 5 +++++ tests/cli/config_file/fixtures/package.json | 7 +++++++ 13 files changed, 45 insertions(+) create mode 100644 tests/cli/basic/cli_basic.test.mjs rename tests/cli/{ => basic}/fixtures/index.html (100%) rename tests/cli/{ => basic}/fixtures/main.js (100%) rename tests/cli/{ => basic}/fixtures/node_modules/foo/foo.js (100%) rename tests/cli/{ => basic}/fixtures/node_modules/foo/package.json (100%) rename tests/cli/{ => basic}/fixtures/package.json (100%) rename tests/cli/{ => basic}/snapshots/index.html (100%) rename tests/cli/{cli.test.mjs => config_file/cli_config_file.test.mjs} (100%) create mode 100644 tests/cli/config_file/fixtures/index.html create mode 100644 tests/cli/config_file/fixtures/main.js create mode 100644 tests/cli/config_file/fixtures/node_modules/foo/foo.js create mode 100644 tests/cli/config_file/fixtures/node_modules/foo/package.json create mode 100644 tests/cli/config_file/fixtures/package.json diff --git a/tests/cli/basic/cli_basic.test.mjs b/tests/cli/basic/cli_basic.test.mjs new file mode 100644 index 0000000..e911da4 --- /dev/null +++ b/tests/cli/basic/cli_basic.test.mjs @@ -0,0 +1,19 @@ +import { copyFileSync, replaceFileStructureSync } from "@jsenv/filesystem"; +import { takeFileSnapshot } from "@jsenv/snapshot"; +import { execSync } from "node:child_process"; + +const indexHtmlFileSnapshot = takeFileSnapshot( + import.meta.resolve("./snapshots/index.html"), +); +replaceFileStructureSync({ + from: import.meta.resolve("./fixtures/"), + to: import.meta.resolve("./git_ignored/"), +}); +execSync("node ../../../../src/cli.mjs ./index.html", { + cwd: new URL(import.meta.resolve("./git_ignored/")), +}); +copyFileSync({ + from: import.meta.resolve("./git_ignored/index.html"), + to: import.meta.resolve("./snapshots/index.html"), +}); +indexHtmlFileSnapshot.compare(); diff --git a/tests/cli/fixtures/index.html b/tests/cli/basic/fixtures/index.html similarity index 100% rename from tests/cli/fixtures/index.html rename to tests/cli/basic/fixtures/index.html diff --git a/tests/cli/fixtures/main.js b/tests/cli/basic/fixtures/main.js similarity index 100% rename from tests/cli/fixtures/main.js rename to tests/cli/basic/fixtures/main.js diff --git a/tests/cli/fixtures/node_modules/foo/foo.js b/tests/cli/basic/fixtures/node_modules/foo/foo.js similarity index 100% rename from tests/cli/fixtures/node_modules/foo/foo.js rename to tests/cli/basic/fixtures/node_modules/foo/foo.js diff --git a/tests/cli/fixtures/node_modules/foo/package.json b/tests/cli/basic/fixtures/node_modules/foo/package.json similarity index 100% rename from tests/cli/fixtures/node_modules/foo/package.json rename to tests/cli/basic/fixtures/node_modules/foo/package.json diff --git a/tests/cli/fixtures/package.json b/tests/cli/basic/fixtures/package.json similarity index 100% rename from tests/cli/fixtures/package.json rename to tests/cli/basic/fixtures/package.json diff --git a/tests/cli/snapshots/index.html b/tests/cli/basic/snapshots/index.html similarity index 100% rename from tests/cli/snapshots/index.html rename to tests/cli/basic/snapshots/index.html diff --git a/tests/cli/cli.test.mjs b/tests/cli/config_file/cli_config_file.test.mjs similarity index 100% rename from tests/cli/cli.test.mjs rename to tests/cli/config_file/cli_config_file.test.mjs diff --git a/tests/cli/config_file/fixtures/index.html b/tests/cli/config_file/fixtures/index.html new file mode 100644 index 0000000..964be25 --- /dev/null +++ b/tests/cli/config_file/fixtures/index.html @@ -0,0 +1,12 @@ + + + + Title + + + + + + + + diff --git a/tests/cli/config_file/fixtures/main.js b/tests/cli/config_file/fixtures/main.js new file mode 100644 index 0000000..c074830 --- /dev/null +++ b/tests/cli/config_file/fixtures/main.js @@ -0,0 +1 @@ +import "foo"; diff --git a/tests/cli/config_file/fixtures/node_modules/foo/foo.js b/tests/cli/config_file/fixtures/node_modules/foo/foo.js new file mode 100644 index 0000000..3c800d3 --- /dev/null +++ b/tests/cli/config_file/fixtures/node_modules/foo/foo.js @@ -0,0 +1 @@ +console.log('foo'); \ No newline at end of file diff --git a/tests/cli/config_file/fixtures/node_modules/foo/package.json b/tests/cli/config_file/fixtures/node_modules/foo/package.json new file mode 100644 index 0000000..d48f02b --- /dev/null +++ b/tests/cli/config_file/fixtures/node_modules/foo/package.json @@ -0,0 +1,5 @@ +{ + "name": "foo", + "main": "./foo.js", + "private": true +} \ No newline at end of file diff --git a/tests/cli/config_file/fixtures/package.json b/tests/cli/config_file/fixtures/package.json new file mode 100644 index 0000000..3453665 --- /dev/null +++ b/tests/cli/config_file/fixtures/package.json @@ -0,0 +1,7 @@ +{ + "name": "root", + "private": true, + "dependencies": { + "foo": "*" + } +} From 357d113b579999d2250475184c1d0dccf6c8be92 Mon Sep 17 00:00:00 2001 From: dmail Date: Thu, 5 Jun 2025 15:38:29 +0200 Subject: [PATCH 4/6] preparing testing axios use case --- tests/cli/config_file/cli_config_file.test.mjs | 9 ++++++--- tests/cli/config_file/fixtures/importmap.config.json | 7 +++++++ tests/cli/config_file/fixtures/main.js | 5 ++++- .../fixtures/node_modules/axios/dist/esm/axios.js | 1 + .../fixtures/node_modules/{foo => axios}/package.json | 2 +- tests/cli/config_file/fixtures/node_modules/foo/foo.js | 1 - 6 files changed, 19 insertions(+), 6 deletions(-) create mode 100644 tests/cli/config_file/fixtures/importmap.config.json create mode 100644 tests/cli/config_file/fixtures/node_modules/axios/dist/esm/axios.js rename tests/cli/config_file/fixtures/node_modules/{foo => axios}/package.json (69%) delete mode 100644 tests/cli/config_file/fixtures/node_modules/foo/foo.js diff --git a/tests/cli/config_file/cli_config_file.test.mjs b/tests/cli/config_file/cli_config_file.test.mjs index 866224c..e32925f 100644 --- a/tests/cli/config_file/cli_config_file.test.mjs +++ b/tests/cli/config_file/cli_config_file.test.mjs @@ -9,9 +9,12 @@ replaceFileStructureSync({ from: import.meta.resolve("./fixtures/"), to: import.meta.resolve("./git_ignored/"), }); -execSync("node ../../../src/cli.mjs ./index.html", { - cwd: new URL(import.meta.resolve("./git_ignored/")), -}); +execSync( + "node ../../../../src/cli.mjs ./index.html --config=importmap.config.json", + { + cwd: new URL(import.meta.resolve("./git_ignored/")), + }, +); copyFileSync({ from: import.meta.resolve("./git_ignored/index.html"), to: import.meta.resolve("./snapshots/index.html"), diff --git a/tests/cli/config_file/fixtures/importmap.config.json b/tests/cli/config_file/fixtures/importmap.config.json new file mode 100644 index 0000000..c0b3881 --- /dev/null +++ b/tests/cli/config_file/fixtures/importmap.config.json @@ -0,0 +1,7 @@ +{ + "packagesManualOverrides": { + "axios": { + "exports": "./dist/esm/axios.js" + } + } +} diff --git a/tests/cli/config_file/fixtures/main.js b/tests/cli/config_file/fixtures/main.js index c074830..6ba0c23 100644 --- a/tests/cli/config_file/fixtures/main.js +++ b/tests/cli/config_file/fixtures/main.js @@ -1 +1,4 @@ -import "foo"; +// eslint-disable-next-line import-x/no-unresolved +import { axios } from "axios"; + +console.log(axios); diff --git a/tests/cli/config_file/fixtures/node_modules/axios/dist/esm/axios.js b/tests/cli/config_file/fixtures/node_modules/axios/dist/esm/axios.js new file mode 100644 index 0000000..dc03e49 --- /dev/null +++ b/tests/cli/config_file/fixtures/node_modules/axios/dist/esm/axios.js @@ -0,0 +1 @@ +export const axios = 'axios'; \ No newline at end of file diff --git a/tests/cli/config_file/fixtures/node_modules/foo/package.json b/tests/cli/config_file/fixtures/node_modules/axios/package.json similarity index 69% rename from tests/cli/config_file/fixtures/node_modules/foo/package.json rename to tests/cli/config_file/fixtures/node_modules/axios/package.json index d48f02b..3a8534b 100644 --- a/tests/cli/config_file/fixtures/node_modules/foo/package.json +++ b/tests/cli/config_file/fixtures/node_modules/axios/package.json @@ -1,5 +1,5 @@ { - "name": "foo", + "name": "axios", "main": "./foo.js", "private": true } \ No newline at end of file diff --git a/tests/cli/config_file/fixtures/node_modules/foo/foo.js b/tests/cli/config_file/fixtures/node_modules/foo/foo.js deleted file mode 100644 index 3c800d3..0000000 --- a/tests/cli/config_file/fixtures/node_modules/foo/foo.js +++ /dev/null @@ -1 +0,0 @@ -console.log('foo'); \ No newline at end of file From 90b3055c0b31ba243eb263d3a4168d0a6438cb87 Mon Sep 17 00:00:00 2001 From: dmail Date: Thu, 5 Jun 2025 15:42:50 +0200 Subject: [PATCH 5/6] execute html to ensure axios mapping is properly done --- .../cli/config_file/cli_config_file.test.mjs | 13 ++++++++++ tests/cli/config_file/fixtures/index.html | 5 ++++ tests/cli/config_file/fixtures/main.js | 4 ++- tests/cli/config_file/fixtures/package.json | 2 +- tests/cli/config_file/snapshots/index.html | 25 +++++++++++++++++++ 5 files changed, 47 insertions(+), 2 deletions(-) create mode 100644 tests/cli/config_file/snapshots/index.html diff --git a/tests/cli/config_file/cli_config_file.test.mjs b/tests/cli/config_file/cli_config_file.test.mjs index e32925f..ae223a8 100644 --- a/tests/cli/config_file/cli_config_file.test.mjs +++ b/tests/cli/config_file/cli_config_file.test.mjs @@ -1,6 +1,9 @@ +import { assert } from "@jsenv/assert"; +import { startBuildServer } from "@jsenv/core"; import { copyFileSync, replaceFileStructureSync } from "@jsenv/filesystem"; import { takeFileSnapshot } from "@jsenv/snapshot"; import { execSync } from "node:child_process"; +import { executeHtml } from "../../execute_html.js"; const indexHtmlFileSnapshot = takeFileSnapshot( import.meta.resolve("./snapshots/index.html"), @@ -20,3 +23,13 @@ copyFileSync({ to: import.meta.resolve("./snapshots/index.html"), }); indexHtmlFileSnapshot.compare(); + +const buildServer = await startBuildServer({ + buildDirectoryUrl: import.meta.resolve("./git_ignored/"), + keepProcessAlive: false, + port: 0, + logLevel: "warn", +}); +const actual = await executeHtml(`${buildServer.origin}/index.html`); +const expect = "axios"; +assert({ actual, expect }); diff --git a/tests/cli/config_file/fixtures/index.html b/tests/cli/config_file/fixtures/index.html index 964be25..071ec4a 100644 --- a/tests/cli/config_file/fixtures/index.html +++ b/tests/cli/config_file/fixtures/index.html @@ -7,6 +7,11 @@ + diff --git a/tests/cli/config_file/fixtures/main.js b/tests/cli/config_file/fixtures/main.js index 6ba0c23..6091e77 100644 --- a/tests/cli/config_file/fixtures/main.js +++ b/tests/cli/config_file/fixtures/main.js @@ -1,4 +1,6 @@ +/* globals window */ + // eslint-disable-next-line import-x/no-unresolved import { axios } from "axios"; -console.log(axios); +window.resolveResultPromise(axios); diff --git a/tests/cli/config_file/fixtures/package.json b/tests/cli/config_file/fixtures/package.json index 3453665..d1e3304 100644 --- a/tests/cli/config_file/fixtures/package.json +++ b/tests/cli/config_file/fixtures/package.json @@ -2,6 +2,6 @@ "name": "root", "private": true, "dependencies": { - "foo": "*" + "axios": "*" } } diff --git a/tests/cli/config_file/snapshots/index.html b/tests/cli/config_file/snapshots/index.html new file mode 100644 index 0000000..48253f2 --- /dev/null +++ b/tests/cli/config_file/snapshots/index.html @@ -0,0 +1,25 @@ + + + + Title + + + + + + + + + + \ No newline at end of file From 70a9d74d9ac2c1c571b44207c12e3ef50247abf9 Mon Sep 17 00:00:00 2001 From: dmail Date: Thu, 5 Jun 2025 15:43:40 +0200 Subject: [PATCH 6/6] 7.3.0 --- package.json | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/package.json b/package.json index 386fed9..da60558 100644 --- a/package.json +++ b/package.json @@ -1,6 +1,6 @@ { "name": "@jsenv/importmap-node-module", - "version": "7.2.2", + "version": "7.3.0", "description": "Generate importmap for node_modules", "license": "MIT", "repository": {