chore: scaffold MV3 extension with TypeScript + esbuild toolchain
This commit is contained in:
commit
8c05cffa67
6
.gitignore
vendored
Normal file
6
.gitignore
vendored
Normal file
|
|
@ -0,0 +1,6 @@
|
||||||
|
node_modules/
|
||||||
|
build/
|
||||||
|
web-ext-artifacts/
|
||||||
|
*.xpi
|
||||||
|
.DS_Store
|
||||||
|
.claude/settings.local.json
|
||||||
57
esbuild.config.mjs
Normal file
57
esbuild.config.mjs
Normal file
|
|
@ -0,0 +1,57 @@
|
||||||
|
import esbuild from 'esbuild';
|
||||||
|
import { fileURLToPath } from 'node:url';
|
||||||
|
import { dirname, resolve } from 'node:path';
|
||||||
|
|
||||||
|
const watch = process.argv.includes('--watch');
|
||||||
|
const __dirname = dirname(fileURLToPath(import.meta.url));
|
||||||
|
|
||||||
|
// isomorphic-git's `.` subpath export only points at the CJS build, which
|
||||||
|
// does a top-level `require('crypto')` that esbuild can't bundle for the
|
||||||
|
// browser. The package ships an ESM entry at ./index.js but the exports
|
||||||
|
// map hides it. Redirect the bare specifier to the ESM file by hand.
|
||||||
|
const isogitEsmPlugin = {
|
||||||
|
name: 'isogit-esm',
|
||||||
|
setup(build) {
|
||||||
|
const esmEntry = resolve(__dirname, 'node_modules/isomorphic-git/index.js');
|
||||||
|
build.onResolve({ filter: /^isomorphic-git$/ }, () => ({ path: esmEntry }));
|
||||||
|
},
|
||||||
|
};
|
||||||
|
|
||||||
|
const common = {
|
||||||
|
bundle: true,
|
||||||
|
format: 'iife',
|
||||||
|
target: ['firefox115'],
|
||||||
|
platform: 'browser',
|
||||||
|
mainFields: ['browser', 'module', 'main'],
|
||||||
|
conditions: ['browser', 'import', 'default'],
|
||||||
|
logLevel: 'info',
|
||||||
|
sourcemap: true,
|
||||||
|
minify: false,
|
||||||
|
define: {
|
||||||
|
'process.env.NODE_ENV': '"production"',
|
||||||
|
'global': 'globalThis',
|
||||||
|
},
|
||||||
|
plugins: [isogitEsmPlugin],
|
||||||
|
};
|
||||||
|
|
||||||
|
// Only the background bundle pulls in isomorphic-git and therefore needs
|
||||||
|
// the Buffer polyfill. popup/options talk to the background via runtime
|
||||||
|
// messages and stay tiny.
|
||||||
|
const polyfillInject = [resolve(__dirname, 'src/common/polyfills.ts')];
|
||||||
|
|
||||||
|
const entries = [
|
||||||
|
{ entryPoints: ['src/background/index.ts'], outfile: 'build/background.js', inject: polyfillInject },
|
||||||
|
{ entryPoints: ['src/popup/popup.ts'], outfile: 'build/popup.js' },
|
||||||
|
{ entryPoints: ['src/options/options.ts'], outfile: 'build/options.js' },
|
||||||
|
];
|
||||||
|
|
||||||
|
if (watch) {
|
||||||
|
for (const e of entries) {
|
||||||
|
const ctx = await esbuild.context({ ...common, ...e });
|
||||||
|
await ctx.watch();
|
||||||
|
}
|
||||||
|
console.log('watching…');
|
||||||
|
} else {
|
||||||
|
await Promise.all(entries.map(e => esbuild.build({ ...common, ...e })));
|
||||||
|
console.log('build ok');
|
||||||
|
}
|
||||||
15
manifest.json
Normal file
15
manifest.json
Normal file
|
|
@ -0,0 +1,15 @@
|
||||||
|
{
|
||||||
|
"manifest_version": 3,
|
||||||
|
"name": "Passchmop",
|
||||||
|
"version": "0.1.0",
|
||||||
|
"description": "Git-backed, client-side-encrypted password manager.",
|
||||||
|
"browser_specific_settings": {
|
||||||
|
"gecko": {
|
||||||
|
"id": "passchmop@schmop",
|
||||||
|
"strict_min_version": "115.0",
|
||||||
|
"data_collection_permissions": {
|
||||||
|
"required": ["none"]
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
5386
package-lock.json
generated
Normal file
5386
package-lock.json
generated
Normal file
File diff suppressed because it is too large
Load Diff
25
package.json
Normal file
25
package.json
Normal file
|
|
@ -0,0 +1,25 @@
|
||||||
|
{
|
||||||
|
"name": "passchmop",
|
||||||
|
"version": "0.1.0",
|
||||||
|
"description": "Firefox password manager with a client-side-encrypted git-backed vault",
|
||||||
|
"private": true,
|
||||||
|
"type": "module",
|
||||||
|
"scripts": {
|
||||||
|
"build": "node esbuild.config.mjs",
|
||||||
|
"watch": "node esbuild.config.mjs --watch",
|
||||||
|
"typecheck": "tsc --noEmit",
|
||||||
|
"run": "web-ext run --source-dir=. --start-url=about:debugging",
|
||||||
|
"package": "web-ext build --source-dir=. --overwrite-dest"
|
||||||
|
},
|
||||||
|
"dependencies": {
|
||||||
|
"@isomorphic-git/lightning-fs": "^4.6.0",
|
||||||
|
"buffer": "^6.0.3",
|
||||||
|
"isomorphic-git": "^1.25.0"
|
||||||
|
},
|
||||||
|
"devDependencies": {
|
||||||
|
"@types/firefox-webext-browser": "^143.0.0",
|
||||||
|
"esbuild": "^0.25.0",
|
||||||
|
"typescript": "^6.0.3",
|
||||||
|
"web-ext": "^8.0.0"
|
||||||
|
}
|
||||||
|
}
|
||||||
23
tsconfig.json
Normal file
23
tsconfig.json
Normal file
|
|
@ -0,0 +1,23 @@
|
||||||
|
{
|
||||||
|
"compilerOptions": {
|
||||||
|
"target": "ES2022",
|
||||||
|
"module": "ESNext",
|
||||||
|
"moduleResolution": "Bundler",
|
||||||
|
"lib": ["ES2022", "DOM", "DOM.Iterable"],
|
||||||
|
"types": ["firefox-webext-browser"],
|
||||||
|
"strict": true,
|
||||||
|
"noImplicitAny": true,
|
||||||
|
"strictNullChecks": true,
|
||||||
|
"noUncheckedIndexedAccess": true,
|
||||||
|
"noImplicitOverride": true,
|
||||||
|
"noFallthroughCasesInSwitch": true,
|
||||||
|
"esModuleInterop": true,
|
||||||
|
"allowSyntheticDefaultImports": true,
|
||||||
|
"skipLibCheck": true,
|
||||||
|
"resolveJsonModule": true,
|
||||||
|
"isolatedModules": true,
|
||||||
|
"noEmit": true,
|
||||||
|
"forceConsistentCasingInFileNames": true
|
||||||
|
},
|
||||||
|
"include": ["src/**/*.ts"]
|
||||||
|
}
|
||||||
Loading…
Reference in New Issue
Block a user