Press n or j to go to the next uncovered block, b, p or k for the previous block.
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44 45 46 47 48 49 50 51 52 53 54 55 56 57 58 59 60 61 62 63 64 65 66 67 68 69 70 71 72 73 74 75 76 77 78 79 80 81 82 83 84 85 86 87 88 89 90 91 92 93 94 95 96 97 98 99 100 101 102 103 104 105 106 107 108 109 110 111 112 113 114 115 116 117 118 119 120 121 122 123 | 1x 1x 37x 37x 1x 96x 91x 5x 5x 4x 1x 1x 1x 90x 4x 86x 86x 86x 2x 84x 18x 66x 40x 26x 7x 19x 18x 90x 90x 90x 90x 90x 90x 90x 36x 36x 36x 36x 36x 8x 28x 3x 28x 36x 6x 6x 27x 9x | import { declare } from '@babel/helper-plugin-utils'; import { existsSync, lstatSync } from 'fs'; import { resolve, extname, dirname } from 'path'; import { types } from '@babel/core'; const { importDeclaration, exportNamedDeclaration, exportAllDeclaration, stringLiteral } = types // Checks if the module has an active extension const isActiveExtension = (module, observedScriptExtensions) => { const ext = extname(module).toLowerCase().replace(/[^a-z]/, ''); return observedScriptExtensions.includes(ext); }; // Checks if the module is a Node module export const isNodeModule = (module) => { if (module.startsWith('.') || module.startsWith('/')) { return false; } try { require.resolve(module); return true; } catch (e) { Eif (e.code === 'MODULE_NOT_FOUND') { return false; } // console.error(e); } }; const skipModule = (module, { replace, extension, skipUnlistedExtensions, observedScriptExtensions }) => { // If the module path does not start with "." (not a relative path) or is a Node module, skip it directly if (!module.startsWith('.') || isNodeModule(module)) { return true; } // Get the module's extension and convert it to lowercase const moduleExtension = extname(module).toLowerCase(); const moduleExtensionWithoutDot = moduleExtension.replace(/^\./, ''); // If the module's extension is not in the list of observed script extensions, skip it if ( skipUnlistedExtensions == true && moduleExtension != "" && !observedScriptExtensions.includes(moduleExtensionWithoutDot) ) { return true; } // If the module has no extension, do not skip it (because an extension might need to be added) if (!moduleExtension) { return false; } // If the module already has the target extension (after converting to lowercase), skip it if (moduleExtension === `.${extension.toLowerCase()}`) { return true; } // When replace is true, allow replacing the existing extension, so do not skip if (replace) { return false; // Do not skip, allow replacing the extension } // When replace is false, skip if the module has an "active" extension return isActiveExtension(module, observedScriptExtensions); }; // Generates a module path declaration export const makeDeclaration = ({ declaration, args }) => (path, state) => { const { node } = path; const { source, exportKind, importKind } = node; const { replace = false, extension = 'js', skipUnlistedExtensions = false, observedScriptExtensions = ['js', 'ts', 'jsx', 'tsx', 'mjs', 'cjs'] } = state.opts; // If there is no source or it's a type-only import/export, return directly const isTypeOnly = exportKind === 'type' || importKind === 'type'; Iif (!source || isTypeOnly) return; const module = source.value; // If the module should be skipped, return directly if (skipModule(module, { replace, extension, skipUnlistedExtensions, observedScriptExtensions })) return; const dirPath = resolve(dirname(module), module) const hasModuleExt = extname(module).length && isActiveExtension(module, observedScriptExtensions); let newModuleName = hasModuleExt ? module.slice(0, -extname(module).length) : module; // Generates the new path based on the module path const pathLiteral = () => { if (existsSync(dirPath) && lstatSync(dirPath).isDirectory()) { return `${module}${newModuleName.endsWith('/') ? '' : '/'}index.${extension}`; } if (newModuleName.endsWith('/')) { newModuleName = `${module}index`; } return `${newModuleName}.${extension}`; }; path.replaceWith( declaration( ...args(path), stringLiteral(pathLiteral()) ) ); }; export default declare((api, options) => { api.assertVersion(7); return { name: 'add-import-extension', visitor: { ImportDeclaration: makeDeclaration({ ...options, declaration: importDeclaration, args: ({ node: { specifiers } }) => [specifiers] }), ExportNamedDeclaration: makeDeclaration({ ...options, declaration: exportNamedDeclaration, args: ({ node: { declaration, specifiers } }) => [declaration, specifiers] }), ExportAllDeclaration: makeDeclaration({ ...options, declaration: exportAllDeclaration, args: () => [] }) } }; }) |