新增分析和最小化打包后端功能
This commit is contained in:
parent
9a5b453d5c
commit
dc5ab0953d
|
|
@ -0,0 +1,11 @@
|
|||
type AnalysisOptions = {
|
||||
outputDir: string;
|
||||
includeNodeModules: boolean;
|
||||
};
|
||||
/**
|
||||
* 分析项目中的模块
|
||||
* @param dir 项目目录
|
||||
* @param output 输出目录
|
||||
*/
|
||||
export declare const analysis: (dir: string, config: AnalysisOptions) => void;
|
||||
export {};
|
||||
|
|
@ -0,0 +1,76 @@
|
|||
"use strict";
|
||||
Object.defineProperty(exports, "__esModule", { value: true });
|
||||
exports.analysis = void 0;
|
||||
const tslib_1 = require("tslib");
|
||||
const fs_1 = tslib_1.__importDefault(require("fs"));
|
||||
const path_1 = tslib_1.__importDefault(require("path"));
|
||||
/**
|
||||
* 分析项目中的模块
|
||||
* @param dir 项目目录
|
||||
* @param output 输出目录
|
||||
*/
|
||||
const analysis = (dir, config) => {
|
||||
const BuiltinModule = require("module");
|
||||
// 兼容一些模拟环境下的 module 构造函数
|
||||
const Module = module.constructor.length > 1 ? module.constructor : BuiltinModule;
|
||||
// 保存原始的 _resolveFilename 方法
|
||||
const oldResolveFilename = Module._resolveFilename;
|
||||
const successImported = new Set();
|
||||
// 重写 _resolveFilename 方法
|
||||
Module._resolveFilename = function (request, // 模块请求路径
|
||||
parent, // 调用方模块
|
||||
isMain, // 是否是主模块
|
||||
rFoptions // 解析选项
|
||||
) {
|
||||
// 调用原始的 _resolveFilename 方法
|
||||
const filename = oldResolveFilename.call(this, request, parent, isMain, rFoptions);
|
||||
// 记录成功导入的模块
|
||||
successImported.add(filename);
|
||||
// 返回解析后的模块路径
|
||||
return filename;
|
||||
};
|
||||
const filterProjectModules = (modulePath) => {
|
||||
if (config.includeNodeModules) {
|
||||
return modulePath.includes(dir);
|
||||
}
|
||||
return modulePath.includes(dir) && !modulePath.includes('node_modules');
|
||||
};
|
||||
/**
|
||||
* 将所有的文件复制到指定目录,并保持目录结构
|
||||
* @param files 文件列表 string[]
|
||||
* @param dest 目标目录
|
||||
* @param root 原目录的根目录
|
||||
*/
|
||||
const copyFiles = (files, dest, root) => {
|
||||
files.forEach(file => {
|
||||
const relativePath = path_1.default.relative(root, file);
|
||||
const destPath = path_1.default.join(dest, relativePath);
|
||||
fs_1.default.mkdirSync(path_1.default.dirname(destPath), { recursive: true });
|
||||
fs_1.default.copyFileSync(file, destPath);
|
||||
});
|
||||
};
|
||||
const { watch } = require("./watch");
|
||||
watch(dir).then(s => {
|
||||
setTimeout(() => {
|
||||
console.log('shutting down...');
|
||||
s().then(() => {
|
||||
console.log('server stoped');
|
||||
// 把导入成功的输出
|
||||
const project = Array.from(successImported).filter(filterProjectModules);
|
||||
// 添加本地的scripts下的所有文件和package.json
|
||||
const scriptsDir = path_1.default.join(dir, 'scripts');
|
||||
const pkgPath = path_1.default.join(dir, 'package.json');
|
||||
const files = fs_1.default.readdirSync(scriptsDir);
|
||||
const scriptFiles = files.map(file => path_1.default.join(scriptsDir, file));
|
||||
project.push(pkgPath, ...scriptFiles);
|
||||
// 复制文件
|
||||
const dest = path_1.default.join(dir, config.outputDir);
|
||||
fs_1.default.mkdirSync(dest, { recursive: true });
|
||||
copyFiles(project, dest, dir);
|
||||
console.warn('分析结果以项目启动所需依赖为准,如果涉及动态导入,请设计routine,在项目启动时进行加载!');
|
||||
process.exit(0);
|
||||
});
|
||||
}, 1000);
|
||||
});
|
||||
};
|
||||
exports.analysis = analysis;
|
||||
|
|
@ -103,6 +103,7 @@ function packageJsonContent({ name, version, description, cliName, cliBinName, i
|
|||
"run:android": "oak-cli run -p android",
|
||||
"server:init": "${serverInitScript}",
|
||||
"server:start": "${serverStartWatchScript}",
|
||||
"server:ana": "cross-env ENABLE_TRACE=true cross-env NODE_ENV=development cross-env OAK_PLATFORM=server node --stack-size=65500 scripts/analysis.js",
|
||||
"postinstall": "npm run make:dep"
|
||||
},
|
||||
"keywords": [],
|
||||
|
|
@ -272,8 +273,7 @@ function packageJsonContent({ name, version, description, cliName, cliBinName, i
|
|||
"webpack-dev-server": "^4.15.1",
|
||||
"webpack-manifest-plugin": "^4.0.2",
|
||||
"workbox-webpack-plugin": "^6.4.1",
|
||||
"chokidar": "^4.0.1",
|
||||
"module-alias": "^2.2.3"
|
||||
"chokidar": "^4.0.1"
|
||||
},
|
||||
"browserslist": {
|
||||
"production": [
|
||||
|
|
@ -305,16 +305,9 @@ function packageJsonContent({ name, version, description, cliName, cliBinName, i
|
|||
},
|
||||
"resolutions": {
|
||||
"readable-stream": "3.6.2"
|
||||
},
|
||||
"_moduleAliases": {
|
||||
"@project": "./lib",
|
||||
"@oak-general-business": "./node_modules/oak-general-business/lib",
|
||||
"@oak-frontend-base": "./node_modules/oak-frontend-base/lib",
|
||||
"@oak-app-domain": "./lib/oak-app-domain"
|
||||
}
|
||||
}
|
||||
`;
|
||||
// _moduleAliases用于lib内运行时的模块声明,重载之后require的路径还会保留@project,需要这样的方式来进行路径alias
|
||||
}
|
||||
function tsConfigJsonContent() {
|
||||
return `{
|
||||
|
|
|
|||
|
|
@ -0,0 +1,86 @@
|
|||
import fs from 'fs'
|
||||
import path from 'path'
|
||||
|
||||
type AnalysisOptions = {
|
||||
outputDir: string
|
||||
includeNodeModules: boolean
|
||||
}
|
||||
|
||||
/**
|
||||
* 分析项目中的模块
|
||||
* @param dir 项目目录
|
||||
* @param output 输出目录
|
||||
*/
|
||||
export const analysis = (dir: string, config: AnalysisOptions) => {
|
||||
const BuiltinModule = require("module");
|
||||
// 兼容一些模拟环境下的 module 构造函数
|
||||
const Module = module.constructor.length > 1 ? module.constructor : BuiltinModule;
|
||||
// 保存原始的 _resolveFilename 方法
|
||||
const oldResolveFilename = Module._resolveFilename;
|
||||
const successImported = new Set<string>();
|
||||
// 重写 _resolveFilename 方法
|
||||
Module._resolveFilename = function (
|
||||
request: string, // 模块请求路径
|
||||
parent: typeof Module, // 调用方模块
|
||||
isMain: boolean, // 是否是主模块
|
||||
rFoptions: object | undefined // 解析选项
|
||||
) {
|
||||
// 调用原始的 _resolveFilename 方法
|
||||
const filename = oldResolveFilename.call(this, request, parent, isMain, rFoptions);
|
||||
|
||||
// 记录成功导入的模块
|
||||
successImported.add(filename);
|
||||
|
||||
// 返回解析后的模块路径
|
||||
return filename;
|
||||
}
|
||||
|
||||
const filterProjectModules = (modulePath: string) => {
|
||||
if (config.includeNodeModules) {
|
||||
return modulePath.includes(dir)
|
||||
}
|
||||
return modulePath.includes(dir) && !modulePath.includes('node_modules');
|
||||
}
|
||||
|
||||
/**
|
||||
* 将所有的文件复制到指定目录,并保持目录结构
|
||||
* @param files 文件列表 string[]
|
||||
* @param dest 目标目录
|
||||
* @param root 原目录的根目录
|
||||
*/
|
||||
const copyFiles = (files: string[], dest: string, root: string) => {
|
||||
files.forEach(file => {
|
||||
const relativePath = path.relative(root, file)
|
||||
const destPath = path.join(dest, relativePath)
|
||||
fs.mkdirSync(path.dirname(destPath), { recursive: true })
|
||||
fs.copyFileSync(file, destPath)
|
||||
})
|
||||
}
|
||||
|
||||
const { watch } = require("./watch") as { watch: (pwd: string) => Promise<() => Promise<void>> }
|
||||
|
||||
watch(dir).then(s => {
|
||||
setTimeout(() => {
|
||||
console.log('shutting down...')
|
||||
s().then(() => {
|
||||
console.log('server stoped')
|
||||
// 把导入成功的输出
|
||||
const project = Array.from(successImported).filter(filterProjectModules)
|
||||
|
||||
// 添加本地的scripts下的所有文件和package.json
|
||||
const scriptsDir = path.join(dir, 'scripts')
|
||||
const pkgPath = path.join(dir, 'package.json')
|
||||
const files = fs.readdirSync(scriptsDir)
|
||||
const scriptFiles = files.map(file => path.join(scriptsDir, file))
|
||||
project.push(pkgPath, ...scriptFiles)
|
||||
|
||||
// 复制文件
|
||||
const dest = path.join(dir, config.outputDir)
|
||||
fs.mkdirSync(dest, { recursive: true });
|
||||
copyFiles(project, dest, dir)
|
||||
console.warn('分析结果以项目启动所需依赖为准,如果涉及动态导入,请设计routine,在项目启动时进行加载!');
|
||||
process.exit(0)
|
||||
})
|
||||
}, 1000)
|
||||
})
|
||||
}
|
||||
|
|
@ -110,6 +110,7 @@ export function packageJsonContent({
|
|||
"run:android": "oak-cli run -p android",
|
||||
"server:init": "${serverInitScript}",
|
||||
"server:start": "${serverStartWatchScript}",
|
||||
"server:ana": "cross-env ENABLE_TRACE=true cross-env NODE_ENV=development cross-env OAK_PLATFORM=server node --stack-size=65500 scripts/analysis.js",
|
||||
"postinstall": "npm run make:dep"
|
||||
},
|
||||
"keywords": [],
|
||||
|
|
|
|||
|
|
@ -0,0 +1,8 @@
|
|||
/* eslint-disable @typescript-eslint/no-require-imports */
|
||||
const { analysis } = require('@xuchangzju/oak-cli/lib/server/analysis');
|
||||
const pwd = process.cwd();
|
||||
|
||||
analysis(pwd, {
|
||||
outputDir: 'backend_gen',
|
||||
includeNodeModules: true,
|
||||
});
|
||||
Loading…
Reference in New Issue