Files

132 lines
3.7 KiB
JavaScript
Raw Permalink Blame History

This file contains ambiguous Unicode characters
This file contains Unicode characters that might be confused with other characters. If you think that this is intentional, you can safely ignore this warning. Use the Escape button to reveal them.
// build.mjs
import {build} from 'esbuild';
import fs from 'fs';
import path from 'path';
import {fileURLToPath} from 'url';
const __filename = fileURLToPath(import.meta.url);
const __dirname = path.dirname(__filename);
// 源码目录(你问的“入口目录”)
const VIEWS_DIR = path.join(__dirname, 'views');
// 输出目录
const DIST_DIR = path.join(__dirname, '../htdocs/luci-static/resources/view/hijpass');
// 限定哪些 from 模块名当作 luci 模块(name = require name
const luciModuleNames = new Set(
['view', 'fs', 'form', 'uci', 'ui', 'network', 'baseclass', 'rpc', 'poll']);
/**
* 扫描 views 目录下的所有 .ts 文件,返回绝对路径列表
*/
function scanEntryFiles(dir) {
const files = fs.readdirSync(dir, {withFileTypes: true});
const entries = [];
for (const file of files) {
if (file.isDirectory()) {
// 若你需要递归子目录,这里可以继续深入
const subDir = path.join(dir, file.name);
entries.push(...scanEntryFiles(subDir));
} else if (file.isFile() && file.name.endsWith('.ts')) {
entries.push(path.join(dir, file.name));
}
}
return entries;
}
/**
* 为单个入口文件构建(entryPath 为绝对路径)
*/
async function buildOne(entryPath) {
// 本次构建中用到的 luci 模块名
const usedModules = new Set();
const luciPlugin = {
name: 'luci-from-plugin',
setup(pluginBuild) {
pluginBuild.onResolve({filter: /.*/}, args => {
if (luciModuleNames.has(args.path)) {
usedModules.add(args.path);
return {
path: args.path,
namespace: 'luci-virtual'
};
}
});
pluginBuild.onLoad({filter: /.*/, namespace: 'luci-virtual'}, args => {
const moduleName = args.path;
const code = `
// Virtual luci module: ${moduleName}
export default ${moduleName};
`;
return {
contents: code,
loader: 'ts'
};
});
}
};
// 计算输出文件名:views/demo.ts → dist/demo.js
const rel = path.relative(VIEWS_DIR, entryPath); // demo.ts
const baseName = rel.replace(/\.ts$/, ''); // demo
const outFile = path.join(DIST_DIR, `${baseName}.js`);
await build({
entryPoints: [entryPath],
bundle: true,
platform: 'browser',
format: 'iife',
target: ['es2022'],
outfile: outFile,
sourcemap: false,
minify: true,
globalName: 'LuciView',
plugins: [luciPlugin]
});
const bundled = fs.readFileSync(outFile, 'utf-8');
const requireLines = Array.from(usedModules)
.sort()
.map(name => `'require ${name}';`)
.join('\n');
const snippet = `
'use strict';
${requireLines}
${bundled}
return LuciView.default;
`;
fs.mkdirSync(path.dirname(outFile), {recursive: true});
fs.writeFileSync(outFile, snippet, 'utf-8');
console.log(`Build luci snippet: ${path.relative(__dirname, outFile)}`);
}
/**
* 主流程:扫描 views 目录并构建所有 .ts
*/
async function bundleAll() {
const entries = scanEntryFiles(VIEWS_DIR);
if (entries.length === 0) {
console.warn('No .ts files found in views/ directory');
return;
}
for (const entry of entries) {
// 按顺序构建每个入口;如需并行可用 Promise.all
// 但串行 log 更清晰,出错也好排查
await buildOne(entry);
}
}
bundleAll().catch(err => {
console.error(err);
process.exit(1);
});