UNPKG

@aniyajs/rotor

Version:

基于webpack5开发的一款专注于打包、运行的工具

265 lines (236 loc) 7.48 kB
const fs = require("fs-extra"); const paths = require("./paths"); const execa = require("execa"); const path = require("path"); const { reddirResolveFile, progressBarHandle } = require("./common"); const escape = require("escape-string-regexp"); const isEnvDevelopment = process.env.NODE_ENV === "development"; // 转换commonjs模块通用部分命令 const commandArgs = [ "--module", "commonjs", "--allowJs", "--resolveJsonModule", "--esModuleInterop", "--outDir", ]; /** * 初始化 meta.json * * @returns {boolean} */ function initRequireFileHandle() { return new Promise((resolve, reject) => { try { // 首次进入应用清除所有缓存 fs.existsSync(paths.appTempPath) && fs.removeSync(paths.appTempPath); // 初始化appTempMetaJs文件 fs.ensureFileSync(paths.appTempMetaJs); if (isEnvDevelopment) { fs.writeJSONSync( paths.appTempMetaJs, { cacheListenPaths: [] }, { spaces: 2, }, ); } else { fs.writeJSONSync(paths.appTempMetaJs, {}); } resolve(true); } catch (error) { reject(error); } }); } /** * 缓存自定义配置文件。 * mock、config * * @param {RegExp} envFileReg 匹配环境变量文件 * @param {string[]} cacheListenPaths 所有被监听的路径 * @param {boolean} changeMock mock被改变 * @param {boolean} changeConfig config被改变 * @return {*} */ async function initTempHandle( envFileReg, cacheListenPaths = [], changeMock = false, changeConfig = false, ) { try { const filterPathReg = new RegExp(`^${escape(paths.appMockPath)}/.+$`); // 在 `meta.json` 中缓存部分路径数据 const metaJson = fs.readJSONSync(paths.appTempMetaJs); // 获取config及深度依赖路径 const cacheConfigFilePaths = changeConfig ? cacheListenPaths // 过滤所有非文件路径 .filter((cacheListenPath) => { try { const pathStats = fs.statSync(cacheListenPath); if (pathStats.isFile()) { return true; } else { return false; } } catch (error) { return false; } }) // 过滤mock文件路径 .filter((cacheListenPath) => !filterPathReg.test(cacheListenPath)) : []; let mockResolveFiles = []; // 仅在测试环境生效 // 当mock文件存在时,将mock文件转换为commonjs模块内容 if ( fs.existsSync(paths.appMockPath) && !!fs.readdirSync(paths.appMockPath).length && isEnvDevelopment && changeMock ) { mockResolveFiles = reddirResolveFile(paths.appMockPath); let mockTempIndexJsContent = ""; let mockBasenameNoExtnames = []; mockResolveFiles.forEach((mockResolveFile) => { const mockExtname = path.extname(mockResolveFile); const mockBasename = path.basename(mockResolveFile); const mockBasenameNoExtname = mockBasename.slice( 0, -mockExtname.length, ); mockBasenameNoExtnames.push(mockBasenameNoExtname); mockTempIndexJsContent += ` const ${mockBasenameNoExtname} = require('${path.join( paths.appMockTempPath, mockBasenameNoExtname, )}').default;`; }); mockTempIndexJsContent += ` module.exports = { ${mockBasenameNoExtnames.join(",\n")} } `; // 为mock缓存文件提供一个入口文件 fs.ensureFileSync(paths.appMockTempIndexJs); fs.writeFileSync(paths.appMockTempIndexJs, mockTempIndexJsContent); } const tempInfo = await progressBarHandle( cacheConfigFilePaths, mockResolveFiles, async () => await initConfigTemp(envFileReg), // const res = await (() => { // return new Promise(resolve => { // setTimeout(() => { // resolve({ // appConfigIndexDirTempPath: '/Users/00513436/Desktop/code/cur/aniyajs-app/src/.aniya/aniya-config/config', // appConfigTempIndexJs: '/Users/00513436/Desktop/code/cur/aniyajs-app/src/.aniya/aniya-config/config/config.js' // }); // }, 5000); // }); // })(); (mockResolveFile) => { const mockCommandArgs = [ ...commandArgs, paths.appMockTempPath, mockResolveFile, ]; execa.sync("tsc", mockCommandArgs, { cwd: process.cwd(), }); }, ); if (changeConfig) { return Promise.resolve(tempInfo); } else { return Promise.resolve(metaJson.paths); } } catch (error) { return Promise.reject(error); } } /** * 缓存config及深度依赖为commonjs文件 * * @param {*} envFileReg 多环境配置文件匹配规则 * @returns */ async function initConfigTemp(envFileReg) { try { if (fs.pathExistsSync(paths.appConfigTempPath)) { fs.removeSync(paths.appConfigTempPath); } // 生成配置文件缓存 const configCommandArgs = [ ...commandArgs, paths.appConfigTempPath, paths.appConfigJs, ]; execa.sync("tsc", configCommandArgs, { cwd: process.cwd(), }); // 因为TSC命令生成的文件目录是不确定的。 // 获取生成的缓存文件目录。 const commandEnvConfigArgs = [...commandArgs]; const appConfigTempPath1 = paths.appConfigTempPath; const appConfigTempIndexJs1 = path.join(appConfigTempPath1, "config.js"); const appConfigTempPath2 = path.join(paths.appConfigTempPath, "config"); const appConfigTempIndexJs2 = path.join(appConfigTempPath2, "config.js"); let appConfigTempIndexJs = appConfigTempIndexJs1; let appConfigIndexDirTempPath = appConfigTempPath1; if (fs.existsSync(appConfigTempIndexJs1)) { commandEnvConfigArgs.push(appConfigTempPath1); } else { commandEnvConfigArgs.push(appConfigTempPath2); appConfigIndexDirTempPath = appConfigTempPath2; appConfigTempIndexJs = appConfigTempIndexJs2; } let envResolveFiles = []; if (envFileReg) { const configFiles = fs.readdirSync(paths.appConfigPath); const envFiles = configFiles.filter((configFile) => envFileReg.test(configFile), ); envFiles.forEach((envFile) => { commandEnvConfigArgs.push(path.resolve(paths.appConfigPath, envFile)); }); envResolveFiles = envFiles.map((envFile) => { const envFileSuffix = path.extname(envFile); const envFileFine = envFile.replace(envFileSuffix, ""); return path.join(appConfigIndexDirTempPath, `${envFileFine}.js`); }); if (envFiles && envFiles.length) { // 生成环境配置文件缓存。 execa.sync("tsc", commandEnvConfigArgs, { cwd: process.cwd(), }); } } // 所需的文件已创建。 let exists = []; [appConfigTempIndexJs, ...envResolveFiles].forEach((xxPath) => { if (fs.existsSync(xxPath)) { exists.push(true); } else { exists.push(false); } }); if (exists.find((exist) => !exist) != null) { return Promise.resolve(false); } else { return Promise.resolve({ appConfigIndexDirTempPath, appConfigTempIndexJs, }); } } catch (error) { return Promise.reject(error); } } module.exports = { initRequireFileHandle, initTempHandle, initConfigTemp, };