Skip to content

Commit

Permalink
feat: content_scripts css property processing by Vite (#77)
Browse files Browse the repository at this point in the history
* feat: content script CSS parsing

support forwarding content script css files to Vite

* feat: support building content script css in dev mode
  • Loading branch information
samrum authored Jan 17, 2023
1 parent 402c034 commit 84ff1ab
Show file tree
Hide file tree
Showing 7 changed files with 133 additions and 14 deletions.
63 changes: 63 additions & 0 deletions src/devBuilder/devBuilder.ts
Original file line number Diff line number Diff line change
Expand Up @@ -49,6 +49,7 @@ export default abstract class DevBuilder<

await this.writeManifestHtmlFiles(manifestHtmlFiles);
await this.writeManifestContentScriptFiles(manifest);
await this.writeManifestContentCssFiles(manifest);
await this.writeManifestWebAccessibleScriptFiles(
manifest,
this.webAccessibleScriptsFilter
Expand Down Expand Up @@ -171,6 +172,68 @@ export default abstract class DevBuilder<
}
}

protected async writeManifestContentCssFiles(manifest: Manifest) {
if (!manifest.content_scripts) {
return;
}

for (const [
contentScriptIndex,
script,
] of manifest.content_scripts.entries()) {
if (!script.css) {
continue;
}

for (const [cssIndex, fileName] of script.css.entries()) {
const absoluteFileName = getInputFileName(
fileName,
this.viteConfig.root
);

const outputFileName = `${getOutputFileName(fileName)}.css`;

manifest.content_scripts[contentScriptIndex].css![cssIndex] =
outputFileName;

await this.writeManifestContentCssFile(
outputFileName,
absoluteFileName
);

this.viteDevServer!.watcher.on("change", async (path) => {
if (normalizePath(path) !== absoluteFileName) {
return;
}

await this.writeManifestContentCssFile(outputFileName, fileName);
});
}
}
}

protected async writeManifestContentCssFile(
outputFileName: string,
fileName: string
) {
const { default: source } = (await this.viteDevServer!.ssrLoadModule(
fileName
)) as { default: string };

const loaderFile = {
fileName: outputFileName,
source,
};

const outFile = `${this.outDir}/${loaderFile.fileName}`;

const outFileDir = path.dirname(outFile);

await ensureDir(outFileDir);

await writeFile(outFile, loaderFile.source);
}

protected abstract writeManifestWebAccessibleScriptFiles(
manifest: Manifest,
webAccessibleScriptsFilter: ReturnType<typeof createFilter>
Expand Down
29 changes: 22 additions & 7 deletions src/manifestParser/manifestParser.ts
Original file line number Diff line number Diff line change
@@ -1,5 +1,4 @@
import { createFilter } from "vite";
import { readFileSync } from "fs";
import { ResolvedConfig, ViteDevServer } from "vite";
import DevBuilder from "../devBuilder/devBuilder";
import { getInputFileName, getOutputFileName } from "../utils/file";
Expand All @@ -8,7 +7,10 @@ import {
getContentScriptLoaderForOutputChunk,
getWebAccessibleScriptLoaderForOutputChunk,
} from "../utils/loader";
import { getChunkInfoFromBundle } from "../utils/rollup";
import {
getCssAssetInfoFromBundle,
getChunkInfoFromBundle,
} from "../utils/rollup";
import type { ViteWebExtensionOptions } from "../../types";
import { getScriptHtmlLoaderFile } from "../utils/loader";
import { setVirtualModule } from "../utils/virtualModule";
Expand Down Expand Up @@ -136,11 +138,10 @@ export default abstract class ManifestParser<
});

script.css?.forEach((cssFile) => {
result.emitFiles.push({
type: "asset",
fileName: cssFile,
source: readFileSync(cssFile, "utf-8"),
});
const inputFile = getInputFileName(cssFile, this.viteConfig.root);
const outputFile = `${getOutputFileName(cssFile)}css`;

result.inputScripts.push([outputFile, inputFile]);
});
});

Expand All @@ -167,6 +168,20 @@ export default abstract class ManifestParser<
return result;
}

protected parseOutputContentCss(
cssFileName: string,
bundle: OutputBundle
): { cssFileName: string } {
const cssAssetInfo = getCssAssetInfoFromBundle(bundle, cssFileName);
if (!cssAssetInfo) {
throw new Error(`Failed to find CSS asset info for ${cssFileName}`);
}

return {
cssFileName: cssAssetInfo.fileName,
};
}

protected parseOutputContentScript(
scriptFileName: string,
result: ParseResult<Manifest>,
Expand Down
9 changes: 9 additions & 0 deletions src/manifestParser/manifestV2.ts
Original file line number Diff line number Diff line change
Expand Up @@ -86,6 +86,15 @@ export default class ManifestV2 extends ManifestParser<Manifest> {
webAccessibleResources
);
});

script.css?.forEach((cssFileName, index) => {
const parsedContentCss = this.parseOutputContentCss(
cssFileName,
bundle
);

script.css![index] = parsedContentCss.cssFileName;
});
});

if (webAccessibleResources.size > 0) {
Expand Down
9 changes: 9 additions & 0 deletions src/manifestParser/manifestV3.ts
Original file line number Diff line number Diff line change
Expand Up @@ -144,6 +144,15 @@ export default class ManifestV3 extends ManifestParser<Manifest> {
webAccessibleResources.add(resource);
}
});

script.css?.forEach((cssFileName, index) => {
const parsedContentCss = this.parseOutputContentCss(
cssFileName,
bundle
);

script.css![index] = parsedContentCss.cssFileName;
});
});

if (webAccessibleResources.size > 0) {
Expand Down
25 changes: 24 additions & 1 deletion src/utils/rollup.ts
Original file line number Diff line number Diff line change
@@ -1,4 +1,9 @@
import type { InputOptions, OutputBundle, OutputChunk } from "rollup";
import type {
InputOptions,
OutputAsset,
OutputBundle,
OutputChunk,
} from "rollup";
import { getNormalizedFileName } from "./file";

export function addInputScriptsToOptionsInput(
Expand Down Expand Up @@ -57,3 +62,21 @@ export function getChunkInfoFromBundle(
);
}) as OutputChunk | undefined;
}

export function getCssAssetInfoFromBundle(
bundle: OutputBundle,
assetFileName: string
): OutputAsset | undefined {
const normalizedFileName = getNormalizedFileName(assetFileName).replace(
/\.[^/.]+$/,
".css"
);

return Object.values(bundle).find((chunk) => {
if (chunk.type === "chunk") {
return;
}

return normalizedFileName.endsWith(chunk.name ?? chunk.fileName);
}) as OutputAsset | undefined;
}
6 changes: 3 additions & 3 deletions test/manifest/__snapshots__/contentCss.v2.test.ts.snap
Original file line number Diff line number Diff line change
Expand Up @@ -34,8 +34,8 @@ exports[`contentCss - Manifest V2 1`] = `
},
},
{
"fileName": "test/manifest/resources/contentCss/content.css",
"name": undefined,
"fileName": "assets/content.css",
"name": "content.css",
"source": ".css {
}
",
Expand All @@ -54,7 +54,7 @@ exports[`contentCss - Manifest V2 1`] = `
\\"assets/test/manifest/resources/contentCss/content.js\\"
],
\\"css\\": [
\\"test/manifest/resources/contentCss/content.css\\"
\\"assets/content.css\\"
],
\\"matches\\": [
\\"https://*/*\\",
Expand Down
6 changes: 3 additions & 3 deletions test/manifest/__snapshots__/contentCss.v3.test.ts.snap
Original file line number Diff line number Diff line change
Expand Up @@ -34,8 +34,8 @@ exports[`contentCss - Manifest V3 1`] = `
},
},
{
"fileName": "test/manifest/resources/contentCss/content.css",
"name": undefined,
"fileName": "assets/content.css",
"name": "content.css",
"source": ".css {
}
",
Expand All @@ -54,7 +54,7 @@ exports[`contentCss - Manifest V3 1`] = `
\\"assets/test/manifest/resources/contentCss/content.js\\"
],
\\"css\\": [
\\"test/manifest/resources/contentCss/content.css\\"
\\"assets/content.css\\"
],
\\"matches\\": [
\\"https://*/*\\",
Expand Down

0 comments on commit 84ff1ab

Please sign in to comment.