initial vaguely working commit
This commit is contained in:
commit
6ed07ab982
156
index.mjs
Normal file
156
index.mjs
Normal file
|
@ -0,0 +1,156 @@
|
||||||
|
/* eslint-env node */
|
||||||
|
|
||||||
|
import {readFileSync} from 'node:fs';
|
||||||
|
import {resolve, basename, extname, dirname, relative, join} from 'node:path';
|
||||||
|
|
||||||
|
export function createConfig (manifestPathRelative, options, createConfig) {
|
||||||
|
const manifestPath = resolve(process.cwd(), manifestPathRelative);
|
||||||
|
const manifestDirname = dirname(manifestPath);
|
||||||
|
|
||||||
|
// Load the manifest
|
||||||
|
let manifestContent;
|
||||||
|
try {
|
||||||
|
manifestContent = JSON.parse(readFileSync(manifestPath, {encoding: 'utf-8'}));
|
||||||
|
} catch (error) {
|
||||||
|
throw new Error('Failed to load manifest');
|
||||||
|
}
|
||||||
|
|
||||||
|
const uniqueFileNameSegmentCache = new Map();
|
||||||
|
function uniqueFileNameSegment (filepath, ext = extname(filepath).slice(1)) {
|
||||||
|
// console.log('getting segment for', filepath);
|
||||||
|
const cached = uniqueFileNameSegmentCache.get(filepath);
|
||||||
|
if (cached) {
|
||||||
|
return cached;
|
||||||
|
}
|
||||||
|
const idealName = basename(filepath, extname(filepath));
|
||||||
|
|
||||||
|
const buildName = (str, n) => n ? `${str}_${n}.${ext}` : `${str}.${ext}`;
|
||||||
|
|
||||||
|
let uniquenessNum = 0;
|
||||||
|
const existingNames = [...uniqueFileNameSegmentCache.values()];
|
||||||
|
while (existingNames.some(existingName => existingName.toLowerCase() === buildName(idealName, uniquenessNum).toLowerCase())) {
|
||||||
|
uniquenessNum += 1;
|
||||||
|
}
|
||||||
|
|
||||||
|
const finalName = buildName(idealName, uniquenessNum);
|
||||||
|
uniqueFileNameSegmentCache.set(filepath, finalName);
|
||||||
|
return finalName;
|
||||||
|
}
|
||||||
|
|
||||||
|
function getOutputFilename (entryPath, ext) {
|
||||||
|
const base = relative(manifestDirname, dirname(entryPath));
|
||||||
|
return join(base, `${uniqueFileNameSegment(entryPath, ext)}`);
|
||||||
|
}
|
||||||
|
|
||||||
|
function getOutputPathRelative (outputDir, platform, entryPath, ext) {
|
||||||
|
return join(outputDir, platform, getOutputFilename(entryPath, ext));
|
||||||
|
}
|
||||||
|
|
||||||
|
const scriptEntrypointAbsolutePaths = [];
|
||||||
|
const styleEntrypointAbsolutePathss = [];
|
||||||
|
const otherAssetAbsolutePaths = [];
|
||||||
|
// Gather all JS entry points specified in the manifest
|
||||||
|
(manifestContent.content_scripts || []).forEach(({css, js}) => {
|
||||||
|
css && css.forEach((filename, i) => {
|
||||||
|
const id = resolve(manifestDirname, filename);
|
||||||
|
styleEntrypointAbsolutePathss.push(id);
|
||||||
|
css.splice(i, 1, getOutputFilename(id, 'css'));
|
||||||
|
});
|
||||||
|
js && js.forEach((filename, i) => {
|
||||||
|
const id = resolve(manifestDirname, filename);
|
||||||
|
scriptEntrypointAbsolutePaths.push(id);
|
||||||
|
js.splice(i, 1, getOutputFilename(id, 'js'));
|
||||||
|
});
|
||||||
|
});
|
||||||
|
manifestContent.background?.scripts && manifestContent.background.scripts.forEach((filename, i) => {
|
||||||
|
const id = resolve(manifestDirname, filename);
|
||||||
|
scriptEntrypointAbsolutePaths.push(id);
|
||||||
|
manifestContent.background.scripts.splice(i, 1, getOutputFilename(id));
|
||||||
|
});
|
||||||
|
if (manifestContent.background?.service_worker) {
|
||||||
|
const id = resolve(manifestDirname, manifestContent.background.service_worker);
|
||||||
|
scriptEntrypointAbsolutePaths.push(id);
|
||||||
|
manifestContent.background.service_worker = getOutputFilename(id);
|
||||||
|
}
|
||||||
|
manifestContent.icons && Object.entries(manifestContent.icons).forEach(([size, filename]) => {
|
||||||
|
const id = resolve(manifestDirname, filename);
|
||||||
|
// console.log('icon:', size, filename, getOutputFilename(id));
|
||||||
|
otherAssetAbsolutePaths.push(id);
|
||||||
|
manifestContent.icons[size] = getOutputFilename(id);
|
||||||
|
});
|
||||||
|
(manifestContent.web_accessible_resources || []).forEach((entry, i) => {
|
||||||
|
if (typeof entry === 'string') {
|
||||||
|
// mv2 - single top-level array of items
|
||||||
|
const id = resolve(manifestDirname, entry);
|
||||||
|
otherAssetAbsolutePaths.push(id);
|
||||||
|
manifestContent.web_accessible_resources.splice(i, 1, getOutputFilename(id));
|
||||||
|
} else {
|
||||||
|
// mv3 - array of objects with `resources` keys
|
||||||
|
const {resources} = entry;
|
||||||
|
resources && resources.forEach((filename, j) => {
|
||||||
|
const id = resolve(manifestDirname, filename);
|
||||||
|
otherAssetAbsolutePaths.push(id);
|
||||||
|
resources.splice(j, 1, getOutputFilename(id));
|
||||||
|
});
|
||||||
|
}
|
||||||
|
});
|
||||||
|
|
||||||
|
const platform = 'firefox';
|
||||||
|
return [
|
||||||
|
...scriptEntrypointAbsolutePaths.map(entrypointPath => ({
|
||||||
|
// Get configuration options for this entrypoint from the caller
|
||||||
|
...createConfig(),
|
||||||
|
// Overwrite input and output options
|
||||||
|
input: relative(process.cwd(), entrypointPath),
|
||||||
|
output: {
|
||||||
|
file: getOutputPathRelative('build', platform, entrypointPath, 'js'),
|
||||||
|
format: 'iife',
|
||||||
|
sourcemap: options.sourcemap,
|
||||||
|
},
|
||||||
|
})),
|
||||||
|
|
||||||
|
// A special step that processes the manifest and copies over non-JS
|
||||||
|
// assets in the meantime
|
||||||
|
{
|
||||||
|
input: manifestPathRelative,
|
||||||
|
output: {
|
||||||
|
file: `build/${platform}/manifest.json`,
|
||||||
|
},
|
||||||
|
plugins: [
|
||||||
|
{
|
||||||
|
buildStart () {
|
||||||
|
styleEntrypointAbsolutePathss.forEach(absolutePath => {
|
||||||
|
this.emitFile({
|
||||||
|
type: 'asset',
|
||||||
|
fileName: getOutputFilename(absolutePath, 'css'),
|
||||||
|
source: readFileSync(absolutePath, {encoding: 'utf-8'}),
|
||||||
|
});
|
||||||
|
});
|
||||||
|
otherAssetAbsolutePaths.forEach(absolutePath => {
|
||||||
|
// console.log('rendering binary file', absolutePath);
|
||||||
|
this.emitFile({
|
||||||
|
type: 'asset',
|
||||||
|
fileName: getOutputFilename(absolutePath),
|
||||||
|
source: readFileSync(absolutePath),
|
||||||
|
});
|
||||||
|
});
|
||||||
|
},
|
||||||
|
load (id) {
|
||||||
|
// console.log(id);
|
||||||
|
if (id === manifestPath) {
|
||||||
|
return 'debugger;';
|
||||||
|
}
|
||||||
|
return null;
|
||||||
|
},
|
||||||
|
renderChunk (code, chunk) {
|
||||||
|
// console.log(chunk);
|
||||||
|
if (chunk.facadeModuleId !== manifestPath) {
|
||||||
|
return null;
|
||||||
|
}
|
||||||
|
return JSON.stringify(manifestContent, null, '\t');
|
||||||
|
},
|
||||||
|
},
|
||||||
|
],
|
||||||
|
},
|
||||||
|
];
|
||||||
|
}
|
5
package.json
Normal file
5
package.json
Normal file
|
@ -0,0 +1,5 @@
|
||||||
|
{
|
||||||
|
"name": "rollup-create-webext-config",
|
||||||
|
"version": "0.0.0",
|
||||||
|
"main": "index.mjs",
|
||||||
|
}
|
Loading…
Reference in a new issue