UNPKG

vite-plugin-require-resolve

Version:

A vite plugin deals with require.resolve() assets, for node-browser mixed-context environment like nw.js etc

148 lines (147 loc) 7.26 kB
"use strict"; var __importDefault = (this && this.__importDefault) || function (mod) { return (mod && mod.__esModule) ? mod : { "default": mod }; }; Object.defineProperty(exports, "__esModule", { value: true }); const path_1 = __importDefault(require("path")); const fs_extra_1 = __importDefault(require("fs-extra")); const picocolors_1 = __importDefault(require("picocolors")); const md5_file_1 = __importDefault(require("md5-file")); const strip_comments_1 = __importDefault(require("strip-comments")); const REG_EXP_G = /require\.resolve\(['"][(\.\/)(\.\.\/)][^'"]+['"]\)/g; const REG_EXP_FOR_MATCH = /require\.resolve\(['"]([(\.\/)(\.\.\/)][^'"]+)['"]\)/; const SIZE_GB = 1024 * 1024 * 1024 * 1; const SIZE_MB = 1024 * 1024 * 1; const SIZE_KB = 1024 * 1; const Helper = { AssetsFolderName: '', RelativeAssetsDir: '', AbsoluteAssetsDir: '', ResolvedCodeFileList: [], BlackAssetFileList: [], AssetRequireMap: new Map(), OutputAssetList: [], GetSizeDesc: (InSize) => { if (InSize >= SIZE_GB) { return (InSize / SIZE_GB).toFixed(2) + 'GB'; } else if (InSize >= SIZE_MB) { return (InSize / SIZE_MB).toFixed(2) + 'MB'; } else { return (InSize / SIZE_KB).toFixed(2) + 'KB'; } }, }; function VitePluginRequireResolve() { return { name: 'vite-plugin-require-resolve', apply: 'build', enforce: 'pre', async configResolved(ResolvedConfig) { Helper.AssetsFolderName = ResolvedConfig.build.assetsDir; Helper.RelativeAssetsDir = path_1.default.join(ResolvedConfig.build.outDir, ResolvedConfig.build.assetsDir).replace(/\\/g, '/'); Helper.AbsoluteAssetsDir = path_1.default.resolve(ResolvedConfig.root, ResolvedConfig.build.outDir, ResolvedConfig.build.assetsDir); }, async transform(Code, FileID) { const CodeFileAbsolutePath = FileID.replace(/(\?.*)$/, ''); if (Helper.ResolvedCodeFileList.find(Item => Item === CodeFileAbsolutePath)) { return null; } const CodeWithoutComments = (0, strip_comments_1.default)(Code); const Matches = CodeWithoutComments.match(REG_EXP_G); if (!Matches) { Helper.ResolvedCodeFileList.push(CodeFileAbsolutePath); return null; } let ReturnCode = Code; const CodeFileAbsolutePathParsed = path_1.default.parse(CodeFileAbsolutePath); const ResolvedStatementMap = new Map(); const BlackStatementList = []; for (const RequireResolveStatement of Matches) { if (ResolvedStatementMap.has(RequireResolveStatement) || BlackStatementList.includes(RequireResolveStatement)) { continue; } const AssetDirMatches = RequireResolveStatement.match(REG_EXP_FOR_MATCH); if (!AssetDirMatches || !AssetDirMatches[1]) { continue; } const AssetFileAbsolutePath = path_1.default.resolve(CodeFileAbsolutePathParsed.dir, AssetDirMatches[1]); if (Helper.BlackAssetFileList.includes(AssetFileAbsolutePath)) { continue; } const AssetFileParsedPath = path_1.default.parse(AssetFileAbsolutePath); const ExistedStatement = Helper.AssetRequireMap.get(AssetFileAbsolutePath); if (ExistedStatement) { ResolvedStatementMap.set(RequireResolveStatement, ExistedStatement); ReturnCode = ReturnCode.replaceAll(RequireResolveStatement, ExistedStatement); continue; } if (!fs_extra_1.default.existsSync(AssetFileAbsolutePath)) { console.log('\r' + picocolors_1.default.bgYellow(picocolors_1.default.black('WARN')) + picocolors_1.default.yellow(' [vite-plugin-require-resolve] ') + picocolors_1.default.yellow(`${RequireResolveStatement} can't find target file, in ${CodeFileAbsolutePath}`)); Helper.BlackAssetFileList.push(AssetFileAbsolutePath); BlackStatementList.push(RequireResolveStatement); continue; } const MD5 = md5_file_1.default.sync(AssetFileAbsolutePath).substring(0, 8); const OutputName = AssetFileParsedPath.name + '-' + MD5 + AssetFileParsedPath.ext; const NewStatement = `require.resolve('./${Helper.AssetsFolderName}/${OutputName}')`; const OutputAsset = Helper.OutputAssetList.find(Item => Item.OutputName === OutputName); if (OutputAsset) { if (OutputAsset.AssetPath !== AssetFileAbsolutePath) { OutputAsset.AssetPath = AssetFileAbsolutePath; } } else { Helper.OutputAssetList.push({ AssetPath: AssetFileAbsolutePath, OutputName: OutputName, }); } Helper.AssetRequireMap.set(AssetFileAbsolutePath, NewStatement); ResolvedStatementMap.set(RequireResolveStatement, NewStatement); ReturnCode = ReturnCode.replaceAll(RequireResolveStatement, NewStatement); } Helper.ResolvedCodeFileList.push(CodeFileAbsolutePath); return ReturnCode; }, async closeBundle() { const Tasks = []; const ExpiredAssetList = []; for (const OutputAsset of Helper.OutputAssetList) { if (!fs_extra_1.default.existsSync(OutputAsset.AssetPath)) { ExpiredAssetList.push(OutputAsset.AssetPath); continue; } Tasks.push({ Src: OutputAsset.AssetPath, Dest: path_1.default.resolve(Helper.AbsoluteAssetsDir, OutputAsset.OutputName), Name: OutputAsset.OutputName, }); } Helper.OutputAssetList = Helper.OutputAssetList.filter(Item => !ExpiredAssetList.includes(Item.AssetPath)); const OutputResult = []; await Promise.all(Tasks.map(Task => (async () => { await fs_extra_1.default.copyFile(Task.Src, Task.Dest); OutputResult.push({ Name: Task.Name, Size: (await fs_extra_1.default.stat(Task.Src)).size, }); })())); for (const Result of OutputResult) { console.log('\r' + picocolors_1.default.black(Helper.RelativeAssetsDir + '/') + picocolors_1.default.green(Result.Name) + '\t' + picocolors_1.default.gray(Helper.GetSizeDesc(Result.Size))); } Helper.ResolvedCodeFileList = []; Helper.BlackAssetFileList = []; Helper.AssetRequireMap.clear(); }, }; } exports.default = VitePluginRequireResolve; module.exports = exports.default;