diff --git a/packages/js/src/utils/copy-assets-handler.spec.ts b/packages/js/src/utils/copy-assets-handler.spec.ts index a2c443c1483ca..b1f0e0d00b624 100644 --- a/packages/js/src/utils/copy-assets-handler.spec.ts +++ b/packages/js/src/utils/copy-assets-handler.spec.ts @@ -42,6 +42,7 @@ describe('AssetInputOutputHandler', () => { output: 'docs', ignore: ['ignore.md', '**/nested-ignore.md'], }, + 'LICENSE', ], }); }); @@ -49,6 +50,8 @@ describe('AssetInputOutputHandler', () => { test('watchAndProcessOnAssetChange', async () => { const dispose = await sut.watchAndProcessOnAssetChange(); + fse.writeFileSync(path.join(rootDir, 'LICENSE'), 'license'); + await wait(100); fse.writeFileSync(path.join(projectDir, 'README.md'), 'readme'); await wait(100); // give watch time to react fse.writeFileSync(path.join(projectDir, 'docs/test1.md'), 'test'); @@ -72,6 +75,15 @@ describe('AssetInputOutputHandler', () => { await wait(100); expect(callback.mock.calls).toEqual([ + [ + [ + { + type: 'create', + src: path.join(rootDir, 'LICENSE'), + dest: path.join(rootDir, 'dist/mylib/LICENSE'), + }, + ], + ], [ [ { @@ -130,6 +142,7 @@ describe('AssetInputOutputHandler', () => { }); test('processAllAssetsOnce', async () => { + fse.writeFileSync(path.join(rootDir, 'LICENSE'), 'license'); fse.writeFileSync(path.join(projectDir, 'README.md'), 'readme'); fse.writeFileSync(path.join(projectDir, 'docs/test1.md'), 'test'); fse.writeFileSync(path.join(projectDir, 'docs/test2.md'), 'test'); @@ -144,6 +157,15 @@ describe('AssetInputOutputHandler', () => { await sut.processAllAssetsOnce(); expect(callback.mock.calls).toEqual([ + [ + [ + { + type: 'create', + src: path.join(rootDir, 'LICENSE'), + dest: path.join(rootDir, 'dist/mylib/LICENSE'), + }, + ], + ], [ [ { diff --git a/packages/js/src/utils/copy-assets-handler.ts b/packages/js/src/utils/copy-assets-handler.ts index 3d9c7ba141ca6..304cdd486a494 100644 --- a/packages/js/src/utils/copy-assets-handler.ts +++ b/packages/js/src/utils/copy-assets-handler.ts @@ -120,14 +120,12 @@ export class CopyAssetsHandler { !ag.ignore?.some((ig) => minimatch(src, ig)) && !this.ignore.ignores(src) ) { + const relPath = path.relative(ag.input, src); + const dest = relPath.startsWith('..') ? src : relPath; acc.push({ type: 'create', src: path.join(this.rootDir, src), - dest: path.join( - this.rootDir, - ag.output, - path.relative(ag.input, src) - ), + dest: path.join(this.rootDir, ag.output, dest), }); } return acc; @@ -140,7 +138,7 @@ export class CopyAssetsHandler { async watchAndProcessOnAssetChange(): Promise<() => Promise> { const watcher = await import('@parcel/watcher'); const subscription = await watcher.subscribe( - this.projectDir, + this.rootDir, (err, events) => { if (err) { logger.error(`Watch error: ${err?.message ?? 'Unknown'}`); @@ -163,14 +161,12 @@ export class CopyAssetsHandler { !ag.ignore?.some((ig) => minimatch(pathFromRoot, ig)) && !this.ignore.ignores(pathFromRoot) ) { + const relPath = path.relative(ag.input, pathFromRoot); + const destPath = relPath.startsWith('..') ? pathFromRoot : relPath; fileEvents.push({ type: event.type, src: path.join(this.rootDir, pathFromRoot), - dest: path.join( - this.rootDir, - ag.output, - path.relative(ag.input, pathFromRoot) - ), + dest: path.join(this.rootDir, ag.output, destPath), }); // Match first entry and skip the rest for this file. break;