UNPKG

@ices/locale-webpack-plugin

Version:
162 lines 6.94 kB
"use strict"; Object.defineProperty(exports, "__esModule", { value: true }); exports.createDeclarations = exports.getModuleDetails = void 0; const tslib_1 = require("tslib"); const fs_1 = tslib_1.__importDefault(require("fs")); const path_1 = tslib_1.__importDefault(require("path")); const utils_1 = require("./utils"); // 确保模块依赖被正确声明 function ensureDependencies(moduleName, version) { const pkgPath = path_1.default.resolve('package.json'); const pkgModule = require(pkgPath); const { dependencies = {}, devDependencies = {} } = pkgModule; let needUpdate = false; let depsVersion; if ((depsVersion = devDependencies[moduleName])) { delete devDependencies[moduleName]; needUpdate = true; } if (!dependencies[moduleName]) { dependencies[moduleName] = depsVersion || `^${version}`; needUpdate = true; } if (!pkgModule.dependencies) { pkgModule.dependencies = dependencies; } if (needUpdate) { (0, utils_1.writeFileSync)(pkgPath, JSON.stringify(pkgModule, null, 2)); } } // 追加引用声明到工程的types声明文件 // 如果工程没有在代码里导入模块包,tsc不会去找已经在package.json里声明了的模块 // 只有在代码里导入了模块,tsc才会根据依赖解析规则去找声明文件 // 所以,这里还是需要把声明引用添加到工程的声明文件中去 function appendReferenceToProject(moduleName) { const cwd = fs_1.default.realpathSync(process.cwd()); if (cwd === (0, utils_1.getSelfContext)()) { return; } const typesPath = ensureFileHelper(['src/react-app-env.d.ts', 'src/types.d.ts'], cwd, false); if (typesPath) { const refCode = `/// <reference types="${moduleName}" />`; const content = fs_1.default.readFileSync(typesPath, 'utf8'); if (!new RegExp(`^\s*${(0, utils_1.escapeRegExpCharacters)(refCode)}\s*$`, 'm').test(content)) { (0, utils_1.writeFileSync)(typesPath, `${refCode}\n${content}`); } } } // 追加引用声明到Lib的types声明文件 function appendReferenceToLib(moduleDetails, declarationFile) { const { packageModule, context } = moduleDetails; const { types, typings } = packageModule; // 查找声明文件 const typesPath = ensureFileHelper([types, typings, 'index.d.ts'], context); // 追加资源模块声明引用 const refPath = (0, utils_1.normalizePath)(path_1.default.join(context, declarationFile), path_1.default.dirname(typesPath)); const refCode = `/// <reference path="${refPath}" />`; const content = fs_1.default.readFileSync(typesPath, 'utf8'); if (!new RegExp(`^\s*${(0, utils_1.escapeRegExpCharacters)(refCode)}\s*$`, 'm').test(content)) { (0, utils_1.writeFileSync)(typesPath, `${refCode}\n${content}`); } // 同步types声明 if (!(0, utils_1.isSamePath)(typesPath, packageModule.types, context)) { packageModule.types = (0, utils_1.normalizePath)(typesPath, context); (0, utils_1.writeFileSync)(path_1.default.join(context, 'package.json'), JSON.stringify(packageModule, null, 2)); } } // 检查文件路径列表,并确保存在至少一个文件(非目录) // 最后一个文件会被创建,如果所有路径都不存在的话 function ensureFileHelper(paths, context, createLast = true) { let file; const tests = [...paths]; while ((file = tests.shift())) { if (typeof file === 'string') { const filePath = path_1.default.join(context, file); if (fs_1.default.existsSync(filePath) && !fs_1.default.statSync(filePath).isDirectory()) { return filePath; } if (!tests.length && createLast) { // 最后一个文件了,还不存在,创建这个文件 (0, utils_1.writeFileSync)(filePath, ''); return filePath; } } } return ''; } // 资源模块导出代码 function getResourceModuleCode(ext, declarationExports) { return ('\n' + `declare module ${JSON.stringify(`*${ext.startsWith('.') ? '' : '.'}${ext}`)} {\n${declarationExports}\n}\n`); } // 解析模块包描述文件路径 function resolveModulePackage(name) { const cwd = fs_1.default.realpathSync(process.cwd()); const selfDir = (0, utils_1.getSelfContext)(); let pkgPath = ''; try { // 从当前工作目录解析依赖包 pkgPath = require.resolve(name, { paths: [cwd] }); } catch (e) { if (selfDir && cwd !== selfDir) { // 从自身模块目录解析依赖包 // 模块自测时需要在当前模块下引入依赖包 try { pkgPath = require.resolve(name, { paths: [selfDir] }); } catch (e) { throw new Error(`Can not resolve module path of ${name}`); } } } return pkgPath; } /** * 获取Locale组件模块的详情 * @param name 模块名称 */ function getModuleDetails(name) { // 解析模块的包描述文件路径 const pkgPath = resolveModulePackage(`${name}/package.json`); const context = path_1.default.dirname(pkgPath); const packageModule = require(pkgPath); const loaderPath = ensureFileHelper([packageModule.loader, 'loader.js', 'lib/loader.js'], context, false); if (!loaderPath) { throw new Error(`Can not get loader of module ${name}`); } return { name, context, packageModule, loaderModule: require(loaderPath), }; } exports.getModuleDetails = getModuleDetails; /** * 创建资源模块的类型声明文件。 * @param moduleDetails 可用于处理资源模块的Lib模块详情。 * @param extensions 支持的资源类型后缀名称。 * @param targetFile 类型声明文件的路径名称(相对于Lib模块根目录)。 */ function createDeclarations(moduleDetails, extensions, targetFile) { const { loaderModule, packageModule, context, name } = moduleDetails; const { getModuleExports } = loaderModule; if (typeof getModuleExports !== 'function') { throw new Error(`Can not find the export method named by getModuleExports for ${name}`); } const declarationExports = getModuleExports({}); if (typeof declarationExports !== 'string') { throw new Error(`Module exports declaration of ${name} is not a string value`); } const declarationCodes = []; for (const ext of extensions) { declarationCodes.push(getResourceModuleCode(ext, declarationExports)); } (0, utils_1.writeFileSync)(path_1.default.join(context, targetFile), declarationCodes.join('')); appendReferenceToLib(moduleDetails, targetFile); ensureDependencies(name, packageModule.version); appendReferenceToProject(name); } exports.createDeclarations = createDeclarations; //# sourceMappingURL=module.js.map