UNPKG

@aniyajs/rotor

Version:

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

261 lines (222 loc) 7.58 kB
"use strict"; const fs = require("fs-extra"); const paths = require("./paths"); const execa = require("execa"); const path = require("path"); const escape = require("escape-string-regexp"); const { reddirResolveFile, progressBarHandle } = require("./common"); const compileWithTempConfig = require("./compileTempFile"); const { cleanupTempConfig } = require("./compileTempFile"); const isEnvDevelopment = process.env.NODE_ENV === "development"; /** * 初始化 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 (fs.pathExistsSync(paths.appTempCachePath)) { fs.removeSync(paths.appTempCachePath); } if (fs.pathExistsSync(paths.appConfigTempPath)) { fs.removeSync(paths.appConfigTempPath); } if (fs.pathExistsSync(paths.appEnvConfigTempPath)) { fs.removeSync(paths.appEnvConfigTempPath); } 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} isFirstStart 是否是首次启动 * @return {*} */ async function initTempHandle(envFileReg, cacheListenPaths = [], isFirstStart) { if (!fs.existsSync(paths.appConfigJs)) { return Promise.resolve(false); } fs.ensureDirSync(paths.appTempCachePath); try { // // 在 `meta.json` 中缓存部分路径数据 // const metaJson = fs.readJSONSync(paths.appTempMetaJs); // 获取config及深度依赖路径 const cacheConfigFilePaths = cacheListenPaths // 过滤所有非文件路径 .filter((cacheListenPath) => { try { const pathStats = fs.statSync(cacheListenPath); if (pathStats.isFile()) { return true; } else { return false; } } catch (error) { return false; } }); let mockResolveFiles = []; // 仅在测试环境生效 // 当mock文件存在时,将mock文件转换为commonjs模块内容 if (isFirstStart || !fs.pathExistsSync(paths.appMockTempPath)) { if (fs.pathExistsSync(paths.appMockTempPath)) { fs.removeSync(paths.appMockTempPath); } if ( fs.existsSync(paths.appMockPath) && !!fs.readdirSync(paths.appMockPath).length ) { 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); const mockFilePath = path.join( paths.appMockTempPath, mockBasenameNoExtname ); // 转为 POSIX 路径(正斜杠) const posixMockPath = mockFilePath.replace(/\\/g, "/"); mockTempIndexJsContent += ` const ${mockBasenameNoExtname} = require('${posixMockPath}').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), (mockResolveFile) => { compileWithTempConfig( mockResolveFile, // 支持数组 paths.appMockTempPath ); } ); // 所有编译完成后清理临时 tsconfig cleanupTempConfig(); console.log(); return Promise.resolve(tempInfo); } 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); } if (fs.pathExistsSync(paths.appEnvConfigTempPath)) { fs.removeSync(paths.appEnvConfigTempPath); } let appConfigTempIndexJs = path.join(paths.appConfigTempPath, "config.js"); let appConfigTemp = paths.appConfigTempPath; let appEnvConfigTemp = paths.appEnvConfigTempPath; let appEnvConfigTempJs = ""; compileWithTempConfig(paths.appConfigJs, paths.appConfigTempPath); if (!fs.existsSync(appConfigTempIndexJs)) { appConfigTempIndexJs = path.join( paths.appConfigTempPath, "config/config.js" ); appConfigTemp = path.join(paths.appConfigTempPath, "config"); } // 生成环境配置文件缓存 let envResolveFiles = []; let envFilePaths = []; if (envFileReg) { const configFiles = fs.readdirSync(paths.appConfigPath); const envFiles = configFiles.filter((configFile) => envFileReg.test(configFile) ); envFiles.forEach((envFile) => { const envFileBaseName = path.basename(envFile, path.extname(envFile)); appEnvConfigTempJs = path.join( paths.appEnvConfigTempPath, `${envFileBaseName}.js` ); envFilePaths.push(path.resolve(paths.appConfigPath, envFile)); }); if (envFiles && envFiles.length) { // 生成环境配置文件缓存。 compileWithTempConfig(envFilePaths, paths.appEnvConfigTempPath); } if (!fs.existsSync(appEnvConfigTempJs)) { appEnvConfigTemp = path.join(paths.appEnvConfigTempPath, `config`); } envResolveFiles = envFiles.map((envFile) => { const envFileSuffix = path.extname(envFile); const envFileFine = envFile.replace(envFileSuffix, ""); return path.join(appEnvConfigTemp, `${envFileFine}.js`); }); } // 所需的文件已创建。 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({ appConfigTemp, appEnvConfigTemp, appConfigTempIndexJs, }); } } catch (error) { return Promise.reject(error); } } module.exports = { initRequireFileHandle, initTempHandle, initConfigTemp, };