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