253 lines
12 KiB
JavaScript
253 lines
12 KiB
JavaScript
"use strict";
|
|
Object.defineProperty(exports, "__esModule", { value: true });
|
|
exports.buildRouter = void 0;
|
|
const tslib_1 = require("tslib");
|
|
const path_1 = require("path");
|
|
const fs_extra_1 = require("fs-extra");
|
|
const assert_1 = tslib_1.__importDefault(require("assert"));
|
|
const ts = tslib_1.__importStar(require("typescript"));
|
|
const node_watch_1 = tslib_1.__importDefault(require("node-watch"));
|
|
const env_1 = require("./env");
|
|
const { factory } = ts;
|
|
const NameSpaceDescDict = {};
|
|
function checkPageDir(dir, relativePath, ns, type) {
|
|
let changed = false;
|
|
const { pages } = NameSpaceDescDict[ns];
|
|
const subdirs = [];
|
|
const files = (0, fs_extra_1.readdirSync)(dir);
|
|
files.forEach((file) => {
|
|
const filepath = (0, path_1.join)(dir, file);
|
|
const stat = (0, fs_extra_1.statSync)(filepath);
|
|
if (stat.isFile() &&
|
|
['web.tsx', 'web.pc.tsx', 'render.native.tsx', 'render.ios.tsx', 'render.android.tsx', 'index.xml'].includes(file)) {
|
|
if (!pages.hasOwnProperty(dir)) {
|
|
const indexJsonFile = (0, path_1.join)(dir, 'index.json');
|
|
let oakDisablePulldownRefresh = false;
|
|
if ((0, fs_extra_1.existsSync)(indexJsonFile)) {
|
|
const { enablePullDownRefresh = true, } = require(indexJsonFile);
|
|
oakDisablePulldownRefresh =
|
|
!enablePullDownRefresh;
|
|
}
|
|
pages[dir] = {
|
|
path: relativePath.replace(/\\/g, '/'),
|
|
oakDisablePulldownRefresh,
|
|
hasNative: ['render.native.tsx', 'render.ios.tsx', 'render.android.tsx'].includes(file),
|
|
hasWeb: ['web.tsx', 'web.pc.tsx'].includes(file),
|
|
hasWechatMp: file === 'index.xml',
|
|
};
|
|
changed = true;
|
|
}
|
|
else {
|
|
if (['render.native.tsx', 'render.ios.tsx', 'render.android.tsx'].includes(file) && type === 'native') {
|
|
if (pages[dir].hasNative === false) {
|
|
pages[dir].hasNative = true;
|
|
changed = true;
|
|
}
|
|
}
|
|
else if (['web.tsx', 'web.pc.tsx'].includes(file) && type === 'web') {
|
|
if (pages[dir].hasWeb === false) {
|
|
pages[dir].hasWeb = true;
|
|
changed = true;
|
|
}
|
|
}
|
|
else {
|
|
if (pages[dir].hasWechatMp === false && type === 'wechatMp') {
|
|
pages[dir].hasWechatMp = true;
|
|
}
|
|
}
|
|
}
|
|
}
|
|
else if (stat.isDirectory()) {
|
|
subdirs.push(file);
|
|
}
|
|
});
|
|
return {
|
|
subdirs,
|
|
changed,
|
|
};
|
|
}
|
|
function traverseNsDir(nsDir, ns, type) {
|
|
NameSpaceDescDict[ns] = {
|
|
pages: {}
|
|
};
|
|
const { pages } = NameSpaceDescDict[ns];
|
|
const traverse = (dir, relativePath) => {
|
|
const { subdirs } = checkPageDir(dir, relativePath, ns, type);
|
|
subdirs.forEach((subdir) => {
|
|
const dir2 = (0, path_1.join)(dir, subdir);
|
|
const relativePath2 = (0, path_1.join)(relativePath, subdir);
|
|
traverse(dir2, relativePath2);
|
|
});
|
|
};
|
|
traverse(nsDir, '');
|
|
}
|
|
function traversePageDir(projectDir, type) {
|
|
const pageDir = (0, path_1.join)(projectDir, 'src', 'pages');
|
|
const namespaces = (0, fs_extra_1.readdirSync)(pageDir);
|
|
namespaces.forEach((ns) => {
|
|
const nsDir = (0, path_1.join)(pageDir, ns);
|
|
const stat = (0, fs_extra_1.statSync)(nsDir);
|
|
if (stat.isDirectory()) {
|
|
traverseNsDir(nsDir, ns, type);
|
|
}
|
|
});
|
|
}
|
|
function makeWebAllRouters(namespaceDir, projectDir, routerFileDir) {
|
|
const nss = (0, fs_extra_1.readdirSync)(namespaceDir);
|
|
return factory.createArrayLiteralExpression(nss.map((ns) => {
|
|
(0, assert_1.default)(NameSpaceDescDict[ns], `${ns}在pages下没有对应的目录`);
|
|
const { pages } = NameSpaceDescDict[ns];
|
|
const nsIndexJsonFile = (0, path_1.join)(namespaceDir, ns, 'index.json');
|
|
let path2 = `/${ns}`;
|
|
let notFound2 = '', first2 = '';
|
|
if ((0, fs_extra_1.existsSync)(nsIndexJsonFile)) {
|
|
const { path, notFound, first } = require(nsIndexJsonFile);
|
|
if (path) {
|
|
path2 = path.replace(/\\/g, '/');
|
|
}
|
|
if (notFound) {
|
|
notFound2 = notFound.replace(/\\/g, '/');
|
|
}
|
|
if (first) {
|
|
first2 = first.replace(/\\/g, '/');
|
|
if (first2.startsWith('/')) {
|
|
first2 = first2.slice(1);
|
|
}
|
|
}
|
|
}
|
|
let firstPage;
|
|
const children = Object.values(pages).filter((ele) => ele.hasWeb).map(({ path, oakDisablePulldownRefresh }) => {
|
|
const properties = [
|
|
factory.createPropertyAssignment('path', factory.createStringLiteral(path)),
|
|
factory.createPropertyAssignment('namespace', factory.createStringLiteral(path2)),
|
|
factory.createPropertyAssignment('meta', factory.createObjectLiteralExpression([
|
|
factory.createPropertyAssignment('oakDisablePulldownRefresh', oakDisablePulldownRefresh ? factory.createTrue() : factory.createFalse())
|
|
])),
|
|
factory.createPropertyAssignment(factory.createIdentifier("Component"), factory.createCallExpression(factory.createPropertyAccessExpression(factory.createIdentifier("React"), factory.createIdentifier("lazy")), undefined, [factory.createArrowFunction(undefined, undefined, [], undefined, factory.createToken(ts.SyntaxKind.EqualsGreaterThanToken), factory.createCallExpression(factory.createIdentifier('import'), undefined, [
|
|
factory.createStringLiteral((0, path_1.relative)(routerFileDir, (0, path_1.join)(projectDir, 'src', 'pages', ns, path)).replace(/\\/g, '/'))
|
|
]))]))
|
|
];
|
|
if (first2 === path) {
|
|
const firstProperties = [...properties];
|
|
firstProperties.push(factory.createPropertyAssignment('isFirst', factory.createTrue()));
|
|
firstPage = factory.createObjectLiteralExpression(firstProperties, true);
|
|
}
|
|
return factory.createObjectLiteralExpression(properties, true);
|
|
});
|
|
if (firstPage) {
|
|
children.push(firstPage);
|
|
}
|
|
if (notFound2) {
|
|
children.push(factory.createObjectLiteralExpression([
|
|
factory.createPropertyAssignment('path', factory.createStringLiteral('*')),
|
|
factory.createPropertyAssignment('namespace', factory.createStringLiteral(path2)),
|
|
factory.createPropertyAssignment(factory.createIdentifier("Component"), factory.createCallExpression(factory.createPropertyAccessExpression(factory.createIdentifier("React"), factory.createIdentifier("lazy")), undefined, [factory.createArrowFunction(undefined, undefined, [], undefined, factory.createToken(ts.SyntaxKind.EqualsGreaterThanToken), factory.createCallExpression(factory.createIdentifier('import'), undefined, [
|
|
factory.createStringLiteral((0, path_1.relative)(routerFileDir, (0, path_1.join)(projectDir, 'src', 'pages', ns, notFound2)).replace(/\\/g, '/'))
|
|
]))]))
|
|
], true));
|
|
}
|
|
return factory.createObjectLiteralExpression([
|
|
factory.createPropertyAssignment('path', factory.createStringLiteral(path2)),
|
|
factory.createPropertyAssignment('namespace', factory.createStringLiteral(path2)),
|
|
factory.createPropertyAssignment(factory.createIdentifier("Component"), factory.createCallExpression(factory.createPropertyAccessExpression(factory.createIdentifier("React"), factory.createIdentifier("lazy")), undefined, [factory.createArrowFunction(undefined, undefined, [], undefined, factory.createToken(ts.SyntaxKind.EqualsGreaterThanToken), factory.createCallExpression(factory.createIdentifier('import'), undefined, [
|
|
factory.createStringLiteral((0, path_1.relative)(routerFileDir, (0, path_1.join)(namespaceDir, ns)).replace(/\\/g, '/'))
|
|
]))])),
|
|
factory.createPropertyAssignment('children', factory.createArrayLiteralExpression(children))
|
|
], true);
|
|
}), true);
|
|
}
|
|
function judgeUseOakRouterBuilder(statements) {
|
|
const stmt = statements[0];
|
|
return ts.isExpressionStatement(stmt) && ts.isStringLiteral(stmt.expression) && stmt.expression.text === 'use oak router builder';
|
|
}
|
|
function outputInWebAppDir(appDir) {
|
|
const routerFileName = (0, path_1.join)(appDir, 'routers', 'allRouters.ts');
|
|
const templateFileName = (0, path_1.join)(appDir, '../../..', 'node_modules', env_1.OAK_CLI_MODULE_NAME, 'templateFiles', 'allRouters.ts');
|
|
const program = ts.createProgram([templateFileName], {
|
|
removeComments: false,
|
|
});
|
|
const routerFile = program.getSourceFile(templateFileName);
|
|
(0, assert_1.default)(routerFile);
|
|
const namespaceDir = (0, path_1.join)(appDir, 'namespaces');
|
|
const { statements } = routerFile;
|
|
if (judgeUseOakRouterBuilder(statements)) {
|
|
statements.forEach((statement) => {
|
|
if (ts.isVariableStatement(statement)) {
|
|
const declaration = statement.declarationList.declarations.find(declaration => ts.isIdentifier(declaration.name) && declaration.name.text === 'allRouters');
|
|
if (declaration) {
|
|
Object.assign(declaration, {
|
|
initializer: makeWebAllRouters(namespaceDir, (0, path_1.join)(appDir, '../../..'), (0, path_1.dirname)(routerFileName))
|
|
});
|
|
}
|
|
}
|
|
});
|
|
const printer = ts.createPrinter({ newLine: ts.NewLineKind.LineFeed, removeComments: false });
|
|
const result = printer.printNode(ts.EmitHint.Unspecified, routerFile, routerFile);
|
|
(0, fs_extra_1.writeFileSync)(routerFileName, result);
|
|
}
|
|
}
|
|
function outputInWebDir(dir) {
|
|
const srcAppDir = (0, path_1.join)(dir, 'src', 'app');
|
|
outputInWebAppDir(srcAppDir);
|
|
}
|
|
function watchDir(projectDir, startupDir, type) {
|
|
const srcPageDir = (0, path_1.join)(projectDir, 'src', 'pages');
|
|
console.log('watch dir ', srcPageDir);
|
|
if (startupDir.startsWith('web')) {
|
|
const srcAppDir = (0, path_1.join)(projectDir, startupDir, 'src', 'app');
|
|
const apps = (0, fs_extra_1.readdirSync)(srcAppDir);
|
|
const tryOutputAppDir = (ns) => {
|
|
apps.forEach((app) => {
|
|
const appDir = (0, path_1.join)(srcAppDir, app);
|
|
const namespaceDir = (0, path_1.join)(appDir, 'namespaces');
|
|
const namespaces = (0, fs_extra_1.readdirSync)(namespaceDir);
|
|
if (namespaces.includes(ns)) {
|
|
outputInWebAppDir(appDir);
|
|
}
|
|
});
|
|
};
|
|
(0, node_watch_1.default)(srcPageDir, {
|
|
recursive: true,
|
|
filter: new RegExp('web\.tsx|web\.pc\.tsx|index\.xml|render\.(native|ios|android)\.tsx'),
|
|
}, (evt, filepath) => {
|
|
const dir = (0, path_1.dirname)(filepath);
|
|
const relativeDir = (0, path_1.relative)((0, path_1.join)(projectDir, 'src', 'pages'), filepath);
|
|
const ns = relativeDir.split('\\')[0];
|
|
const relativePath = (0, path_1.relative)(ns, (0, path_1.dirname)(relativeDir));
|
|
const { pages } = NameSpaceDescDict[ns];
|
|
if (evt === 'remove') {
|
|
if ((0, fs_extra_1.existsSync)(dir)) {
|
|
const { changed } = checkPageDir(dir, relativePath, ns, type);
|
|
if (changed) {
|
|
tryOutputAppDir(ns);
|
|
}
|
|
}
|
|
else {
|
|
delete pages[dir];
|
|
tryOutputAppDir(ns);
|
|
}
|
|
}
|
|
else {
|
|
const { changed } = checkPageDir(dir, relativePath, ns, type);
|
|
if (changed) {
|
|
tryOutputAppDir(ns);
|
|
}
|
|
}
|
|
});
|
|
}
|
|
}
|
|
function buildRouter(projectDir, startupDir, watch) {
|
|
const type = startupDir.startsWith('web') ? 'web' : (startupDir.startsWith('native') ? 'native' : 'wechatMp');
|
|
traversePageDir(projectDir, type);
|
|
const subDir = (0, fs_extra_1.readdirSync)(projectDir);
|
|
(0, assert_1.default)(subDir.includes(startupDir));
|
|
if (startupDir.startsWith('web')) {
|
|
outputInWebDir((0, path_1.join)(projectDir, startupDir));
|
|
}
|
|
// todo native
|
|
if (watch) {
|
|
watchDir(projectDir, startupDir, type);
|
|
}
|
|
}
|
|
exports.buildRouter = buildRouter;
|