UNPKG

@modern-js/module-tools

Version:

Simple, powerful, high-performance modern npm package development solution.

269 lines (268 loc) • 10.3 kB
"use strict"; var __create = Object.create; var __defProp = Object.defineProperty; var __getOwnPropDesc = Object.getOwnPropertyDescriptor; var __getOwnPropNames = Object.getOwnPropertyNames; var __getProtoOf = Object.getPrototypeOf; var __hasOwnProp = Object.prototype.hasOwnProperty; var __export = (target, all) => { for (var name2 in all) __defProp(target, name2, { get: all[name2], enumerable: true }); }; var __copyProps = (to, from, except, desc) => { if (from && typeof from === "object" || typeof from === "function") { for (let key of __getOwnPropNames(from)) if (!__hasOwnProp.call(to, key) && key !== except) __defProp(to, key, { get: () => from[key], enumerable: !(desc = __getOwnPropDesc(from, key)) || desc.enumerable }); } return to; }; var __toESM = (mod, isNodeMode, target) => (target = mod != null ? __create(__getProtoOf(mod)) : {}, __copyProps( // If the importer is in node compatibility mode or this is not an ESM // file that has been converted to a CommonJS file using a Babel- // compatible transform (i.e. "__esModule" has not been set), then set // "default" to the CommonJS "module.exports" for node compatibility. isNodeMode || !mod || !mod.__esModule ? __defProp(target, "default", { value: mod, enumerable: true }) : target, mod )); var __toCommonJS = (mod) => __copyProps(__defProp({}, "__esModule", { value: true }), mod); var redirect_exports = {}; __export(redirect_exports, { redirect: () => redirect }); module.exports = __toCommonJS(redirect_exports); var import_path = require("path"); var import_napi = require("@ast-grep/napi"); var import_utils = require("@modern-js/utils"); var import_tsconfig_paths = require("@modern-js/utils/tsconfig-paths"); var import_magic_string = __toESM(require("magic-string")); var import_file = require("../../constants/file"); var import_utils2 = require("../../utils"); var import_asset = require("./asset"); var import_postcssTransformer = require("./style/postcssTransformer"); var PathType; (function(PathType2) { PathType2[PathType2["Absolute"] = 0] = "Absolute"; PathType2[PathType2["Relative"] = 1] = "Relative"; PathType2[PathType2["ModuleId"] = 2] = "ModuleId"; })(PathType || (PathType = {})); function getTypeOfPath(path, compiler) { const isSupportModuleIdAlias = Object.keys(compiler.config.resolve.alias).length > 0; if ((0, import_path.isAbsolute)(path)) { return 0; } if (!path.startsWith(".") && isSupportModuleIdAlias) { return 2; } return 1; } async function redirectImport(compiler, code, modules, aliasRecord, filePath, outputDir, jsExtension, isModule, matchPath) { const str = new import_magic_string.default(code); const extensions = [ ".ts", ".tsx", ".js", ".jsx" ]; await Promise.all(modules.map(async (module2) => { if (!module2.name) { return; } const { start, end } = module2; let { name: name2 } = module2; const ext = (0, import_path.extname)(name2); const { redirect: redirect2 } = compiler.config; const { alias, style } = redirect2; if (alias) { let absoluteImportPath = matchPath ? matchPath(name2, void 0, void 0, extensions) : void 0; for (const alias2 of Object.keys(aliasRecord)) { if (name2.startsWith(`${alias2}/`)) { absoluteImportPath = (0, import_path.join)(aliasRecord[alias2], name2.slice(alias2.length + 1)); break; } if (name2 === alias2) { absoluteImportPath = aliasRecord[alias2]; break; } } if (absoluteImportPath) { if (getTypeOfPath(absoluteImportPath, compiler) === 2) { str.overwrite(start, end, absoluteImportPath); name2 = absoluteImportPath; } else { const relativePath = (0, import_path.relative)((0, import_path.dirname)(filePath), absoluteImportPath); const relativeImportPath = (0, import_utils2.normalizeSlashes)(relativePath.startsWith("..") ? relativePath : `./${relativePath}`); str.overwrite(start, end, relativeImportPath); name2 = relativeImportPath; } } } if (redirect2.autoExtension) { if (ext === "" && name2.startsWith(".") && (jsExtension !== ".js" || isModule)) { str.overwrite(start, end, `${name2}${jsExtension}`); return; } if ((0, import_utils2.isTsExt)(name2)) { str.overwrite(start, end, name2.replace(/\.(m|c)?tsx?$/, jsExtension)); return; } } if (style) { const { originalFilePath, query } = (0, import_utils2.resolvePathAndQuery)(name2); if (query.css_virtual) { const replacedName = (0, import_path.basename)(originalFilePath, (0, import_path.extname)(originalFilePath)).replace(".", "_"); const base = `${replacedName}.css`; const key = query.hash; const contents = compiler.virtualModule.get(key); const fileName = (0, import_path.join)(outputDir, base); compiler.emitAsset(fileName, { type: "asset", contents, fileName, originalFileName: name2 }); const relativeImportPath = (0, import_utils2.normalizeSlashes)(`./${base}`); str.overwrite(start, end, relativeImportPath); } if (!name2.startsWith(".")) { return; } if (ext === ".less" || ext === ".sass" || ext === ".scss" || ext === ".css") { var _compiler_config_style_autoModules; if ((0, import_postcssTransformer.isCssModule)(name2, (_compiler_config_style_autoModules = compiler.config.style.autoModules) !== null && _compiler_config_style_autoModules !== void 0 ? _compiler_config_style_autoModules : true)) { str.overwrite(start, end, `${name2.slice(0, -ext.length)}`); } else { str.overwrite(start, end, `${name2.slice(0, -ext.length)}.css`); } return; } } if (redirect2.asset) { if (import_file.assetExt.filter((ext2) => name2.endsWith(ext2)).length) { const absPath = (0, import_path.resolve)((0, import_path.dirname)(filePath), name2); const { contents: relativeImportPath, loader } = ( // HACK: set callOnLoad true to invoke svgr await import_asset.getAssetContents.apply(compiler, [ absPath, outputDir, true ]) ); if (loader === "jsx") { const ext2 = (0, import_path.extname)(name2); const outputName = `${name2.slice(0, -ext2.length)}.js`; str.overwrite(start, end, outputName); } else { str.overwrite(start, end, `${relativeImportPath}`); } } } })); return str; } const name = "redirect"; const redirect = { name, apply(compiler) { let matchPath; if (import_utils.fs.existsSync(compiler.config.tsconfig)) { const result = (0, import_tsconfig_paths.loadConfig)(compiler.config.tsconfig); if (result.resultType === "success") { const { absoluteBaseUrl, paths, mainFields, addMatchAll } = result; matchPath = (0, import_tsconfig_paths.createMatchPath)(absoluteBaseUrl, paths, mainFields, addMatchAll); } } compiler.hooks.transform.tapPromise({ name }, async (args) => { if (!(0, import_utils2.isJsExt)(args.path) && !(0, import_utils2.isJsLoader)(args.loader)) { return args; } const { code, path: id } = args; const { format, sourceDir, outDir, autoExtension } = compiler.config; const { root } = compiler.context; if (!code || format === "iife" || format === "umd") { return args; } const alias = Object.keys(compiler.config.resolve.alias).length > 0 ? compiler.config.resolve.alias : compiler.config.alias; const absoluteAlias = Object.entries(alias).reduce((result, [name2, target]) => { if (getTypeOfPath(target, compiler) === 1) { result[name2] = (0, import_path.resolve)(compiler.context.root, target); } else { result[name2] = target; } return result; }, {}); try { const sgNode = (0, import_napi.parse)(import_napi.Lang.JavaScript, code).root(); const matcher = { rule: { kind: "string_fragment", any: [ { inside: { stopBy: "end", kind: "import_statement", field: "source" } }, { inside: { stopBy: "end", kind: "export_statement", field: "source" } }, { inside: { kind: "string", inside: { kind: "arguments", inside: { kind: "call_expression", has: { field: "function", regex: "^(import|require)$" } } } } } ] } }; const matchModule = sgNode.findAll(matcher).map((matchNode) => { return { name: matchNode.text(), start: matchNode.range().start.index, end: matchNode.range().end.index }; }); if (matchModule.length > 0) { const { jsExtension, isModule } = (0, import_utils2.getDefaultOutExtension)({ format, root, autoExtension }); const outputPath = (0, import_path.resolve)(outDir, (0, import_path.relative)(sourceDir, id)); const str = await redirectImport(compiler, code, matchModule, absoluteAlias, id, (0, import_path.dirname)(outputPath), jsExtension, isModule, matchPath); return { ...args, code: str.toString(), map: str.generateMap({ hires: true, includeContent: true }) }; } } catch (e) { import_utils.logger.error("[parse error]", e); } return args; }); } }; // Annotate the CommonJS export names for ESM import in node: 0 && (module.exports = { redirect });