blob: c4bd709fd4f6151afb181dd1ca620ad6face6e72 [file]
#!/usr/bin/env node
const fs = require('fs');
const path = require('path');
const repoRoot = path.resolve(__dirname, '..');
const entryArg = process.argv[2] || 'src/js/edit/index.js';
const outputArg = process.argv[3] || 'public/js/vg-editor.js';
const entryPath = path.resolve(repoRoot, entryArg);
const outputPath = path.resolve(repoRoot, outputArg);
const prependedFiles = [
path.resolve(repoRoot, 'public/js/tagify.min.js')
];
const seen = new Set();
const ordered = [];
const importPattern = /^\s*import\s+(?:[^'";]+\s+from\s+)?['"]([^'"]+)['"]\s*;?\s*$/gm;
function normalizeModulePath(fromFile, specifier) {
if (!specifier.startsWith('.')) {
throw new Error('Only relative imports are supported: ' + specifier);
}
var resolved = path.resolve(path.dirname(fromFile), specifier);
if (!path.extname(resolved)) {
resolved = resolved + '.js';
}
return resolved;
}
function ensureParentDir(filePath) {
const dirPath = path.dirname(filePath);
if (!fs.existsSync(dirPath)) {
fs.mkdirSync(dirPath, { recursive: true });
}
}
function collectModules(filePath) {
if (seen.has(filePath)) {
return;
}
seen.add(filePath);
const source = fs.readFileSync(filePath, 'utf8');
let match;
while ((match = importPattern.exec(source)) !== null) {
const dep = normalizeModulePath(filePath, match[1]);
collectModules(dep);
}
ordered.push({
filePath,
source
});
}
function stripModuleSyntax(source) {
const lines = source.split(/\r?\n/);
const out = [];
let skippingExportList = false;
for (let i = 0; i < lines.length; i++) {
const line = lines[i];
const trimmed = line.trim();
if (skippingExportList) {
if (trimmed === '};' || trimmed === '}') {
skippingExportList = false;
}
continue;
}
if (/^import\b/.test(trimmed)) {
continue;
}
if (/^export\s*\{/.test(trimmed)) {
if (!(trimmed.includes('}'))) {
skippingExportList = true;
}
continue;
}
if (/^export\s+default\b/.test(trimmed)) {
out.push(line.replace(/^\s*export\s+default\s+/, ''));
continue;
}
if (/^export\s+(var|let|const|function|class)\b/.test(trimmed)) {
out.push(line.replace(/^\s*export\s+/, ''));
continue;
}
out.push(line);
}
return out.join('\n').replace(/\s+$/, '') + '\n';
}
collectModules(entryPath);
const renderedModules = ordered
.map(function (moduleInfo) {
return stripModuleSyntax(moduleInfo.source).replace(/\s+$/, '');
})
.filter(function (moduleSource) {
return moduleSource.trim().length > 0;
});
const prependedChunks = prependedFiles.map(function (filePath) {
return fs.readFileSync(filePath, 'utf8').replace(/\s+$/, '');
});
const output = prependedChunks.concat(renderedModules).join('\n\n') + '\n';
ensureParentDir(outputPath);
fs.writeFileSync(outputPath, output);
process.stdout.write(
'Bundled ' + ordered.length + ' module(s) and ' + prependedChunks.length +
' prepended file(s) into ' + path.relative(repoRoot, outputPath) + '\n'
);