From 89e8523013e470f909dd8667db5beefb7d7510d7 Mon Sep 17 00:00:00 2001 From: dmail Date: Fri, 30 May 2025 17:08:07 +0200 Subject: [PATCH 1/2] allow to ouput importmap into js file --- src/cli.mjs | 5 +- src/step_write_into_files/write_into_files.js | 45 ++++++++- .../0_basic/0_basic.md | 92 +++++++++++++++++++ .../write_inside_js.test.mjs.md | 10 ++ .../fixtures/0_basic/index.html | 12 +++ .../write_inside_js/fixtures/0_basic/main.js | 1 + .../fixtures/0_basic/node_modules/foo/foo.js | 1 + .../0_basic/node_modules/foo/package.json | 5 + .../fixtures/0_basic/package.json | 7 ++ .../write_inside_js/write_inside_js.test.mjs | 22 +++++ 10 files changed, 196 insertions(+), 4 deletions(-) create mode 100644 tests/write_inside_js/_write_inside_js.test.mjs/0_basic/0_basic.md create mode 100644 tests/write_inside_js/_write_inside_js.test.mjs/write_inside_js.test.mjs.md create mode 100644 tests/write_inside_js/fixtures/0_basic/index.html create mode 100644 tests/write_inside_js/fixtures/0_basic/main.js create mode 100644 tests/write_inside_js/fixtures/0_basic/node_modules/foo/foo.js create mode 100644 tests/write_inside_js/fixtures/0_basic/node_modules/foo/package.json create mode 100644 tests/write_inside_js/fixtures/0_basic/package.json create mode 100644 tests/write_inside_js/write_inside_js.test.mjs diff --git a/src/cli.mjs b/src/cli.mjs index cc58b04a..5f2189be 100755 --- a/src/cli.mjs +++ b/src/cli.mjs @@ -39,9 +39,10 @@ if (positionals.length > 1) { if ( !outfile.endsWith(".html") && !outfile.endsWith(".importmap") && - !outfile.endsWith(".json") + !outfile.endsWith(".json") && + !outfile.endsWith(".js") ) { - console.error("Error: outfile must end with .html, .importmap or .json"); + console.error("Error: outfile must end with .html, .importmap, .json or .js"); process.exit(1); } diff --git a/src/step_write_into_files/write_into_files.js b/src/step_write_into_files/write_into_files.js index be08facf..de9b8c29 100644 --- a/src/step_write_into_files/write_into_files.js +++ b/src/step_write_into_files/write_into_files.js @@ -22,13 +22,19 @@ export const writeIntoFiles = ( const importmapAsJson = JSON.stringify(importmap, null, " "); if (fileUrl.endsWith(".html")) { writeIntoHtmlFile(fileUrl, importmapAsJson, { logger }); + } else if (fileUrl.endsWith(".js")) { + writeInfoJsFile(fileUrl, importmapAsJson, { logger }); } else { - writeFileSync(fileUrl, importmapAsJson); - logger.info(`-> ${urlToFileSystemPath(fileUrl)}`); + writeIntoJsonFile(fileUrl, importmapAsJson, { logger }); } } }; +const writeIntoJsonFile = (jsonFileUrl, importmapAsJson, { logger }) => { + writeFileSync(jsonFileUrl, importmapAsJson); + logger.info(`-> ${urlToFileSystemPath(jsonFileUrl)}`); +}; + const writeIntoHtmlFile = (htmlFileUrl, importmapAsJson, { logger }) => { const htmlAst = parseHtml({ html: readFileSync(htmlFileUrl, { as: "string" }), @@ -80,3 +86,38 @@ const writeIntoHtmlFile = (htmlFileUrl, importmapAsJson, { logger }) => { const html = stringifyHtmlAst(htmlAst); writeFileSync(new URL(htmlFileUrl), html); }; + +const writeInfoJsFile = (jsFileUrl, importmapAsJson, { logger }) => { + const jsFileContent = ` +const currentScript = document.currentScript; +if (!currentScript) { + throw new Error( + "document.currentScript is not available, cannot inject importmap" + ); +} +const baseUrl = new URL(".", currentScript.src).href; +const importmap = ${importmapAsJson}; +const topLevelMappings = importmap.imports; +const scopedMappings = importmap.scopes; +const makeMappingsAbsolute = () => { + for (const key of Object.keys(mappings)) { + mappings[key] = baseUrl + mappings[key]; + } +} +if (topLevelMappings) { + makeMappingsAbsolute(topLevelMappings); +} +if (scopedMappings) { + for (const scope of Object.keys(scopedMappings)) { + const mappings = scopedMappings[scope]; + makeMappingsAbsolute(mappings); + } +} +const importmapScript = document.createElement("script"); +importmapScript.type = "importmap"; +importmapScript.textContent = importmap; +currentScript.after(importmapScript); +`; + writeFileSync(jsFileUrl, jsFileContent); + logger.info(`-> ${urlToFileSystemPath(jsFileUrl)}`); +}; diff --git a/tests/write_inside_js/_write_inside_js.test.mjs/0_basic/0_basic.md b/tests/write_inside_js/_write_inside_js.test.mjs/0_basic/0_basic.md new file mode 100644 index 00000000..45b33501 --- /dev/null +++ b/tests/write_inside_js/_write_inside_js.test.mjs/0_basic/0_basic.md @@ -0,0 +1,92 @@ +# [0_basic](../../write_inside_js.test.mjs#L21) + +```js +run("0_basic") +``` + +# 1/2 write 6 files into "./git_ignored/" + +## node_modules/foo/foo.js +```js +console.log('foo'); +``` + +## node_modules/foo/package.json +```json +{ + "name": "foo", + "main": "./foo.js", + "private": true +} +``` + +## index.html +```html + + + + Title + + + + + + + + +``` + +## main.js +```js +import "foo"; + +``` + +## package.json +```json +{ + "name": "root", + "private": true, + "dependencies": { + "foo": "*" + } +} +``` + +## index.js + +``` + +const currentScript = document.currentScript; +if (!currentScript) { + throw new Error( + "document.currentScript is not available, cannot inject importmap" + ); +} +const baseUrl = new URL(".", currentScript.src).href; +const importmap = { + "imports": { + "root/": "./", + "foo/": "./node_modules/foo/", + "root": "./index", + "foo": "./node_modules/foo/foo.js" + }, + "scopes": {} +}; +const topLevelMappings = importmap.imports; +const scopedMappings = importmap.scopes; +const makeMappingsAbsolute = () => { +``` +see [git_ignored/index.js](git_ignored/index.js) for more + +# 2/2 resolve + +```js +undefined +``` + +--- + + + Generated by @jsenv/snapshot + diff --git a/tests/write_inside_js/_write_inside_js.test.mjs/write_inside_js.test.mjs.md b/tests/write_inside_js/_write_inside_js.test.mjs/write_inside_js.test.mjs.md new file mode 100644 index 00000000..3389c98b --- /dev/null +++ b/tests/write_inside_js/_write_inside_js.test.mjs/write_inside_js.test.mjs.md @@ -0,0 +1,10 @@ +# [write_inside_js.test.mjs](../write_inside_js.test.mjs) + + +- [0_basic](0_basic/0_basic.md) + +--- + + + Generated by @jsenv/snapshot + diff --git a/tests/write_inside_js/fixtures/0_basic/index.html b/tests/write_inside_js/fixtures/0_basic/index.html new file mode 100644 index 00000000..964be259 --- /dev/null +++ b/tests/write_inside_js/fixtures/0_basic/index.html @@ -0,0 +1,12 @@ + + + + Title + + + + + + + + diff --git a/tests/write_inside_js/fixtures/0_basic/main.js b/tests/write_inside_js/fixtures/0_basic/main.js new file mode 100644 index 00000000..c0748305 --- /dev/null +++ b/tests/write_inside_js/fixtures/0_basic/main.js @@ -0,0 +1 @@ +import "foo"; diff --git a/tests/write_inside_js/fixtures/0_basic/node_modules/foo/foo.js b/tests/write_inside_js/fixtures/0_basic/node_modules/foo/foo.js new file mode 100644 index 00000000..3c800d3a --- /dev/null +++ b/tests/write_inside_js/fixtures/0_basic/node_modules/foo/foo.js @@ -0,0 +1 @@ +console.log('foo'); \ No newline at end of file diff --git a/tests/write_inside_js/fixtures/0_basic/node_modules/foo/package.json b/tests/write_inside_js/fixtures/0_basic/node_modules/foo/package.json new file mode 100644 index 00000000..d48f02b9 --- /dev/null +++ b/tests/write_inside_js/fixtures/0_basic/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/write_inside_js/fixtures/0_basic/package.json b/tests/write_inside_js/fixtures/0_basic/package.json new file mode 100644 index 00000000..3453665e --- /dev/null +++ b/tests/write_inside_js/fixtures/0_basic/package.json @@ -0,0 +1,7 @@ +{ + "name": "root", + "private": true, + "dependencies": { + "foo": "*" + } +} diff --git a/tests/write_inside_js/write_inside_js.test.mjs b/tests/write_inside_js/write_inside_js.test.mjs new file mode 100644 index 00000000..479b7899 --- /dev/null +++ b/tests/write_inside_js/write_inside_js.test.mjs @@ -0,0 +1,22 @@ +import { replaceFileStructureSync } from "@jsenv/filesystem"; +import { writeImportmaps } from "@jsenv/importmap-node-module"; +import { snapshotWriteImportmaps } from "@jsenv/importmap-node-module/tests/snapshot_write_importmaps.js"; + +const run = async (scenario, options) => { + replaceFileStructureSync({ + from: new URL(`./fixtures/${scenario}/`, import.meta.url), + to: new URL("./git_ignored/", import.meta.url), + }); + await writeImportmaps({ + logLevel: "warn", + directoryUrl: new URL("./git_ignored/", import.meta.url), + importmaps: { + "index.js": {}, + }, + ...options, + }); +}; + +await snapshotWriteImportmaps(import.meta.url, ({ test }) => { + test("0_basic", () => run("0_basic")); +}); From 24c3826d938d78102f787710c0cb67a5b2e399a4 Mon Sep 17 00:00:00 2001 From: dmail Date: Fri, 30 May 2025 17:08:32 +0200 Subject: [PATCH 2/2] update version --- package.json | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/package.json b/package.json index 5602427a..360ad27f 100644 --- a/package.json +++ b/package.json @@ -1,6 +1,6 @@ { "name": "@jsenv/importmap-node-module", - "version": "7.1.1", + "version": "7.2.0", "description": "Generate importmap for node_modules", "license": "MIT", "repository": {