Files
lit.ruv.wtf/tools/blogeditor/build-dist.js

103 lines
4.1 KiB
JavaScript

'use strict';
/**
* Pre-builds the Milkdown Crepe JS + CSS bundles into .vscode/dist/
* Run this before packaging the VSIX: node .vscode/build-dist.js
*/
const path = require('path');
const fs = require('fs');
// Resolve symlinks so node_modules lookup works even in junction'd paths
const ROOT = fs.realpathSync(__dirname);
const DIST_DIR = path.join(ROOT, 'dist');
/**
* Walks up from startDir to find node_modules containing a given package.
* Returns null if not found (never throws).
* @param {string} pkg
* @param {string} startDir
* @returns {string | null}
*/
function resolveFromNearestNodeModules(pkg, startDir) {
let dir = startDir;
while (true) {
const candidate = path.join(dir, 'node_modules', pkg);
if (fs.existsSync(candidate)) return candidate;
const parent = path.dirname(dir);
if (parent === dir) return null;
dir = parent;
}
}
// Walk up from __dirname until we find node_modules with esbuild.
// Also tries process.cwd() in case the script is in a stub folder without node_modules.
const esbuildEntry = resolveFromNearestNodeModules('esbuild', ROOT)
?? resolveFromNearestNodeModules('esbuild', process.cwd());
if (!esbuildEntry) throw new Error('Cannot find esbuild. Run this from the project root that contains node_modules.');
const esbuild = require(path.join(esbuildEntry, 'lib', 'main.js'));
const crepeLib = resolveFromNearestNodeModules('@milkdown/crepe', ROOT)
?? resolveFromNearestNodeModules('@milkdown/crepe', process.cwd());
const CREPE_DIR = path.join(crepeLib, 'lib', 'theme');
// Also need the root for esbuild resolveDir (must contain node_modules/@milkdown)
const ROOT_DIR = path.dirname(path.dirname(esbuildEntry));
const FONT_LOADERS = {
'.woff2': 'dataurl',
'.woff': 'dataurl',
'.ttf': 'dataurl',
'.eot': 'dataurl',
'.svg': 'dataurl',
};
const TEXT_LOADERS = {
'.aff': 'text',
'.dic': 'text',
};
async function main() {
fs.mkdirSync(DIST_DIR, { recursive: true });
console.log('⏳ Bundling Milkdown JS…');
const jsResult = await esbuild.build({
stdin: { contents: `export { Crepe, CrepeFeature } from '@milkdown/crepe';`, resolveDir: ROOT_DIR, loader: 'js' },
bundle: true, format: 'esm', platform: 'browser', target: 'es2022', minify: true, write: false,
});
fs.writeFileSync(path.join(DIST_DIR, 'milkdown.js'), jsResult.outputFiles[0].contents);
console.log(`✓ milkdown.js ${(jsResult.outputFiles[0].contents.byteLength / 1024).toFixed(0)} KB`);
console.log('⏳ Bundling common CSS…');
const cssCommon = await esbuild.build({
entryPoints: [path.join(CREPE_DIR, 'common', 'style.css')],
bundle: true, write: false, loader: FONT_LOADERS,
});
fs.writeFileSync(path.join(DIST_DIR, 'milkdown-common.css'), cssCommon.outputFiles[0].contents);
console.log(`✓ milkdown-common.css ${(cssCommon.outputFiles[0].contents.byteLength / 1024).toFixed(0)} KB`);
console.log('⏳ Bundling theme CSS…');
const cssTheme = await esbuild.build({
entryPoints: [path.join(CREPE_DIR, 'frame-dark', 'style.css')],
bundle: true, write: false, loader: FONT_LOADERS,
});
fs.writeFileSync(path.join(DIST_DIR, 'milkdown-theme.css'), cssTheme.outputFiles[0].contents);
console.log(`✓ milkdown-theme.css ${(cssTheme.outputFiles[0].contents.byteLength / 1024).toFixed(0)} KB`);
console.log('⏳ Bundling spellcheck JS…');
const spellcheckJs = await esbuild.build({
entryPoints: [path.join(ROOT, 'spellcheck.js')],
bundle: true,
format: 'esm',
platform: 'browser',
target: 'es2022',
minify: true,
write: false,
loader: TEXT_LOADERS,
});
fs.writeFileSync(path.join(DIST_DIR, 'spellcheck.js'), spellcheckJs.outputFiles[0].contents);
console.log(`✓ spellcheck.js ${(spellcheckJs.outputFiles[0].contents.byteLength / 1024).toFixed(0)} KB`);
console.log('\n✓ dist/ ready — run: npx @vscode/vsce package --out blog-editor.vsix --no-dependencies');
}
main().catch(err => { console.error(err); process.exit(1); });