diff --git a/programs/develop/webpack/plugin-extension/feature-web-resources/__spec__/index.spec.ts b/programs/develop/webpack/plugin-extension/feature-web-resources/__spec__/index.spec.ts new file mode 100644 index 00000000..6c5fc0f7 --- /dev/null +++ b/programs/develop/webpack/plugin-extension/feature-web-resources/__spec__/index.spec.ts @@ -0,0 +1,199 @@ +import { Asset, Compilation } from "webpack"; +import { WebResourcesPlugin } from ".." + +type Manifest = Partial | Partial; + +describe('generateManifestPatches', () => { + const plugin = new WebResourcesPlugin({ + manifestPath: 'manifest.json', + }); + + function runWith(entryImports: Record, partialManifest: Manifest = {}) { + const manifest = { + ...partialManifest, + }; + + const manifestSource = { + source: () => JSON.stringify(manifest) + } as Asset['source']; + const manifestAsset = { + name: 'manifest.json', + source: manifestSource, + } as unknown as Readonly; + + const updateAssetMock = jest.fn(); + + plugin['generateManifestPatches']( + { + getAsset: () => manifestAsset, + assets: { + 'manifest.json': manifestSource, + }, + updateAsset: updateAssetMock, + } as unknown as Compilation, + entryImports + ); + + expect(updateAssetMock).toHaveBeenCalledTimes(1); + const callArgs = updateAssetMock.mock.calls[0]; + expect(callArgs[0]).toEqual('manifest.json'); + return JSON.parse(callArgs[1].source().toString()) as Manifest; + } + + it('should work for manifest v2', () => { + expect( + runWith({ + 'content_scripts/content-0': [ + 'content_scripts/content-0.css', + 'content_scripts/content-0.js.map', + ], + 'content_scripts/content-1': [ + 'content_scripts/content-1.css', + 'content_scripts/content-1.js.map', + ], + }, { + manifest_version: 2, + content_scripts: [ + { + matches: [''], + run_at: 'document_start', + js: [ + 'content_scripts/content-0.js' + ], + css: [] + }, + { + matches: [''], + run_at: 'document_start', + js: [ + 'content_scripts/content-1.js' + ], + css: [] + } + ] + }) + ).toMatchObject({ + web_accessible_resources: [ + 'content_scripts/content-0.css', + 'content_scripts/content-0.js.map', + 'content_scripts/content-1.css', + 'content_scripts/content-1.js.map', + ] + }); + }); + + it('should work for manifest v3', () => { + expect( + runWith({ + 'content_scripts/content-0': [ + 'content_scripts/content-0.css', + 'content_scripts/content-0.js.map', + ], + 'content_scripts/content-1': [ + 'content_scripts/content-1.css', + 'content_scripts/content-1.js.map', + ], + }, { + manifest_version: 3, + content_scripts: [ + { + matches: [''], + run_at: 'document_start', + js: [ + 'content_scripts/content-0.js' + ], + css: [] + }, + { + matches: [''], + run_at: 'document_start', + js: [ + 'content_scripts/content-1.js' + ], + css: [] + } + ] + }) + ).toMatchObject({ + web_accessible_resources: [ + { + matches: [''], + resources: [ + 'content_scripts/content-0.css', + 'content_scripts/content-1.css', + ], + } + ] + }); + }); + + it('should work if there is existing web_accessible_resources', () => { + expect( + runWith({ + 'content_scripts/content-0': [ + 'content_scripts/content-0.css', + 'content_scripts/content-0.js.map', + ], + 'content_scripts/content-1': [ + 'content_scripts/content-1.css', + 'content_scripts/content-1.js.map', + ], + }, { + manifest_version: 3, + content_scripts: [ + { + matches: [''], + run_at: 'document_start', + js: [ + 'content_scripts/content-0.js' + ], + css: [] + }, + { + matches: ['https://example.com/some/path'], + run_at: 'document_start', + js: [ + 'content_scripts/content-1.js' + ], + css: [] + } + ], + web_accessible_resources: [ + { + matches: [''], + resources: [ + 'my-file.css', + ], + } + ] + }) + ).toMatchObject({ + web_accessible_resources: [ + { + matches: [''], + resources: [ + 'my-file.css', + 'content_scripts/content-0.css', + ], + }, + { + matches: ['https://example.com/*'], + resources: [ + 'content_scripts/content-1.css', + ], + } + ] + }); + }); + + it('should not add web_accessible_resources if there is no entries', () => { + expect( + runWith({}, { + manifest_version: 3, + background: { + service_worker: 'background.js', + } + }).web_accessible_resources + ).toBeUndefined(); + }); +}); diff --git a/programs/develop/webpack/plugin-extension/feature-web-resources/index.ts b/programs/develop/webpack/plugin-extension/feature-web-resources/index.ts index 2228bdb3..fbac7a6c 100644 --- a/programs/develop/webpack/plugin-extension/feature-web-resources/index.ts +++ b/programs/develop/webpack/plugin-extension/feature-web-resources/index.ts @@ -56,7 +56,7 @@ export class WebResourcesPlugin { if (existingResource) { resources.forEach((resource) => { - if (!existingResource.resources.includes(resource)) { + if (!existingResource.resources.includes(resource) && !resource.endsWith('.map')) { existingResource.resources.push(resource) } }) @@ -81,13 +81,17 @@ export class WebResourcesPlugin { } if (manifest.manifest_version === 3) { - manifest.web_accessible_resources = - webAccessibleResourcesV3 as Manifest['web_accessible_resources'] + if (webAccessibleResourcesV3.length > 0) { + manifest.web_accessible_resources = + webAccessibleResourcesV3 as Manifest['web_accessible_resources'] + } } else { - // @ts-expect-error - web_accessible_resources is a string[] in V2 - manifest.web_accessible_resources = Array.from( - new Set(webAccessibleResourcesV2) - ) + if (webAccessibleResourcesV2.length > 0) { + // @ts-expect-error - web_accessible_resources is a string[] in V2 + manifest.web_accessible_resources = Array.from( + new Set(webAccessibleResourcesV2) + ) + } } const source = JSON.stringify(manifest, null, 2)