From 52c104f781660e94e6744ca068d327309599f102 Mon Sep 17 00:00:00 2001 From: Miel Truyen Date: Sat, 20 May 2023 21:05:37 +0200 Subject: [PATCH] 0.0.3: Fixed a bug that showed up in watch mode --- README.md | 1 + package.json | 5 +- pnpm-lock.yaml | 11 +++- src/index.ts | 5 +- src/loader.ts | 6 ++ test/watch/fixtures/index.html | 7 ++ test/watch/fixtures/watched-file.js | 3 + test/watch/snapshots/test.js.md | 53 +++++++++++++++ test/watch/snapshots/test.js.snap | Bin 0 -> 776 bytes test/watch/test.js | 97 ++++++++++++++++++++++++++++ 10 files changed, 183 insertions(+), 5 deletions(-) create mode 100644 test/watch/fixtures/index.html create mode 100644 test/watch/fixtures/watched-file.js create mode 100644 test/watch/snapshots/test.js.md create mode 100644 test/watch/snapshots/test.js.snap create mode 100644 test/watch/test.js diff --git a/README.md b/README.md index f779a00..d8e32c4 100644 --- a/README.md +++ b/README.md @@ -105,6 +105,7 @@ This plugin is in an early state. As such not everything that is supported yet, ### Not (yet/properly) supported +- Sourcemaps (inlined script) (dev-note: we're already including magic-string for this, but do not use it yet, neeeds refactoring) - Plugins importing CSS files - CommonJS (cjs) and IIFI output formats. (Is UMD actually ever used?) - Overriding which DOM-nodes and resulting URLS to ignore/include (in a clean way) diff --git a/package.json b/package.json index 8e5fa88..334abb4 100644 --- a/package.json +++ b/package.json @@ -1,6 +1,6 @@ { "name": "rollup-plugin-html-entry2", - "version": "0.0.2", + "version": "0.0.3", "description": "Teaches rollup how to deal with HTML, allows to use HTML-files as entry-points.", "license": "MIT", "repository": { @@ -56,7 +56,8 @@ }, "dependencies": { "@rollup/pluginutils": "^5.0.1", - "parse5": "^7.1.2" + "parse5": "^7.1.2", + "magic-string": "^0.30.0" }, "devDependencies": { "@types/node": "^18.15.11", diff --git a/pnpm-lock.yaml b/pnpm-lock.yaml index 24b5f54..5362db5 100644 --- a/pnpm-lock.yaml +++ b/pnpm-lock.yaml @@ -4,6 +4,9 @@ dependencies: '@rollup/pluginutils': specifier: ^5.0.1 version: 5.0.2(rollup@3.20.3) + magic-string: + specifier: ^0.30.0 + version: 0.30.0 parse5: specifier: ^7.1.2 version: 7.1.2 @@ -475,7 +478,6 @@ packages: /@jridgewell/sourcemap-codec@1.4.15: resolution: {integrity: sha512-eF2rxCRulEKXHTRiDrDy6erMYWqNw4LPdQ8UQA4huuxaQsVeRPFl2oM8oDGxMFhJUWZf9McpLtJasDDZb/Bpeg==} - dev: true /@jridgewell/trace-mapping@0.3.18: resolution: {integrity: sha512-w+niJYzMHdd7USdiH2U6869nqhD2nbfZXND5Yp93qIbEmnDNk7PD48o+YchRVpzMU7M6jVCbenTR7PA1FLQ9pA==} @@ -2139,6 +2141,13 @@ packages: yallist: 4.0.0 dev: true + /magic-string@0.30.0: + resolution: {integrity: sha512-LA+31JYDJLs82r2ScLrlz1GjSgu66ZV518eyWT+S8VhyQn/JL0u9MeBOvQMGYiPk1DBiSN9DDMOcXvigJZaViQ==} + engines: {node: '>=12'} + dependencies: + '@jridgewell/sourcemap-codec': 1.4.15 + dev: false + /make-dir@3.1.0: resolution: {integrity: sha512-g3FeP20LNwhALb/6Cz6Dd4F2ngze0jz7tbzrD2wAV+o9FeNHe4rL+yK2md0J/fiSf1sa1ADhXqi5+oVwOM/eGw==} engines: {node: '>=8'} diff --git a/src/index.ts b/src/index.ts index 09d2973..8885d0e 100644 --- a/src/index.ts +++ b/src/index.ts @@ -106,7 +106,8 @@ export default function html(opts: RollupHtmlOptions = {}): Plugin { } } }, - load: { + load: { // TODO, not in the mood to fix this. Load-result is getting cached and that gives us issues. Seperate load/transform behavior and adapt to use magic string for transformations? + // Something to figure out: its counter intuitive that rollup expects the load-callback to already return JS. It implies we already do transformations and can't really use rollup to further transform any of it. (i.e handlebars > intermediate-html > html would not be possible?) async handler(id: string) { if(virtualSources.has(id)) return virtualSources.get(id); if(!filter(id)) return; @@ -121,7 +122,7 @@ export default function html(opts: RollupHtmlOptions = {}): Plugin { }) : contents; // Parse document and store it (TODO: check for watch mode, we should check if it needs reparsing or not) - const document = htmlModule.document = htmlModule.document ?? parseHtml(htmlSrc); + const document = htmlModule.document = parseHtml(htmlSrc); // Figure out which references to load from this HTML by iterating all nodes (looking for src or href attributes) let htmlImports: HtmlImport[] = htmlModule.imports = []; diff --git a/src/loader.ts b/src/loader.ts index 5d4b75e..5075b61 100644 --- a/src/loader.ts +++ b/src/loader.ts @@ -49,6 +49,8 @@ export function makeInlineId(sourceId: string, node: DefaultTreeAdapterMap['chil export function makeLoader(mappings: NodeMapping[] = defaultMapping){ const fn : LoadNodeCallback = async function ({node, sourceId}, load){ for(const mapping of mappings){ + + // Test the mapping for a match if (mapping.tagName && mapping.tagName !== node.tagName) continue; // No match, skip if (mapping.match){ if(typeof(mapping.match) === 'function'){ @@ -67,7 +69,10 @@ export function makeLoader(mappings: NodeMapping[] = defaultMapping){ } } } + + // If we've gotten this far its a valid mapping. (either inline or a src/href attribute) if((mapping).attr){ + // Mapped on attribute, resolve its src or href (or whatever was returned) const attr = node.attrs.find(attr=>attr.name === (mapping).attr); if(!attr) continue ;// No match, skip const placeholder = await load({ @@ -76,6 +81,7 @@ export function makeLoader(mappings: NodeMapping[] = defaultMapping){ }); attr.value = placeholder; }else if((mapping).body){ + // Mapped as body, use the contents of the DOM element const body = serializeHtml(node); // unlike what you' might expect, this doesn't serialize the + + diff --git a/test/watch/fixtures/watched-file.js b/test/watch/fixtures/watched-file.js new file mode 100644 index 0000000..3616030 --- /dev/null +++ b/test/watch/fixtures/watched-file.js @@ -0,0 +1,3 @@ + + export const a = 1; // DO NOT CHANGE ME HERE, but in ../test.js + \ No newline at end of file diff --git a/test/watch/snapshots/test.js.md b/test/watch/snapshots/test.js.md new file mode 100644 index 0000000..1ae170e --- /dev/null +++ b/test/watch/snapshots/test.js.md @@ -0,0 +1,53 @@ +# Snapshot report for `test/watch/test.js` + +The actual snapshot is saved in `test.js.snap`. + +Generated by [AVA](https://avajs.dev). + +## watch + +> Snapshot 1 + + [ + { + code: `const a = 2; // If i show up as a changed file, then the watch test has gone wrong!␊ + ␊ + export { a };␊ + //# sourceMappingURL=watched-file-8c4729c5.js.map␊ + `, + fileName: 'watched-file-8c4729c5.js', + map: SourceMap { + file: 'watched-file-8c4729c5.js', + mappings: 'AACgB,MAAC,CAAC,GAAG,EAAE;;;;', + names: [], + sources: [ + '../watched-file.js', + ], + sourcesContent: [ + `␊ + export const a = 2; // If i show up as a changed file, then the watch test has gone wrong!␊ + `, + ], + version: 3, + }, + source: undefined, + }, + { + code: undefined, + fileName: 'watched-file-8c4729c5.js.map', + map: undefined, + source: '{"version":3,"file":"watched-file-8c4729c5.js","sources":["../watched-file.js"],"sourcesContent":["\\n export const a = 2; // If i show up as a changed file, then the watch test has gone wrong!\\n "],"names":[],"mappings":"AACgB,MAAC,CAAC,GAAG,EAAE;;;;"}', + }, + { + code: undefined, + fileName: 'index.html', + map: undefined, + source: `␊ + ␊ + ␊ + ␊ + ␊ + ␊ + `, + }, + ] diff --git a/test/watch/snapshots/test.js.snap b/test/watch/snapshots/test.js.snap new file mode 100644 index 0000000000000000000000000000000000000000..949ee1abeb321ac130d7bd1aeff08df458332586 GIT binary patch literal 776 zcmV+j1NZzvRzVVka0%S{?!+DlO*f#!@Mwq)Cw}RfR;U1meK! z;Mm*PC0SechPJ9I)E|I2ap6|ZNE{FsPW%L}969g<5JCvJFzY03;yys2uJrBB?#?$m zp4nM%F4mi&`zYCX$wVNUj4eCD^@D^vQR0Up+1T_vM>u!2PdQQ`vOy8@6F627*ANSc zN>AkosrX)siZrQyMezsX6%g_n@e{gcwT1c; za|I|{;_&crN;#zvGK!c)v=Psg45hGx@;XPzTf_&%FT}}whEg1)3=zl^D4~vWLVk!k z0(m#|Sa+g4CvM0SK^ENZAa8eaL4r>-e4YG44TZO!e?A|Gz~Nr z4B0;FHA0SSamX9zbe*k4VJzqxve&0{%Q{b!upPT>-ie}sH}2fJQA_E}8eXi<2PaM&*KONZUrm*y||6G&=mmsN6ToWvgFN?myg8mHzM6v@cKQ7%k}-imlECz?os&GmWd}JPziJ?B;BH&YZRF*(q$s`hVv| z54gux%D!kd|1k^jq$=6dRi8QDv@U~Hwff|G=&g3dbegzv5DA*ZZf);GQL!4an$Zfq zHfD6XYIRs0GrC^2Qlof`JXn@|;S1j8?+8;RWC^i>c!7AQc1!=z?Ots`Zb$WN*$7IH z{-TTqW7|txZ((%bA< { + const origContent = ` + export const a = 1; // DO NOT CHANGE ME HERE, but in ../test.js + `; + const changeContent = ` + export const a = 2; // If i show up as a changed file, then the watch test has gone wrong! + ` + + const path = resolve(__dirname, 'fixtures/watched-file.js'); + await writeFile(path, origContent, {encoding: 'utf-8'}); + + const watcher = rollup.watch({ + input: 'index.html', + output, + plugins: [ + html({ + }), + ], + watch: { + skipWrite: true, + } + }); + + const steps = [ + async (bundle)=>{ + await writeFile(path, changeContent, {encoding: 'utf-8'}); + // Just wait on the watch mode to pick up on the changes + }, + async (bundle)=>{ + const code = await getCode(bundle, output, true); + debugPrintOutput('watch',code); + + // Reset the source file + await writeFile(path, origContent, {encoding: 'utf-8'}); + + // Assert the output is what we exapect; + t.snapshot(code); + + watcher + }, + ]; + + await new Promise((resolve, reject)=>{ + watcher.on('event', async (event) => { + const {result} = event; + switch (event.code) { + case "START": + t.log(`WATCH STARTED`); + break; + case "BUNDLE_START": + t.log(`REBUILDING...`); + + break; + case "BUNDLE_END": + t.log(`Rebuilt...`); + const cb = steps.shift(); + + const generated = await result.generate(output); + const cbResult = await cb(result); + if(steps.length===0){ + watcher.close(); + resolve(); + } + + break; + case "ERROR": + reject(event.error); + break; + } + if (result) { + result.close(); + } + }); + }); +});