import type { NodePath } from '@babel/traverse' ; import type { CallExpression , Import } from '@babel/types' ; import type { Plugin } from '../types.h' ; import { resolveMethod } from './properties/resolve' ; import { requireSyncMethod } from './properties/requireSync' ; import { isReadyMethod } from './properties/isReady' ; import { importAsyncMethod } from './properties/importAsync' ; import { requireAsyncMethod } from './properties/requireAsync' ; import { chunkNameMethod } from './properties/chunkName' ; interface InnerState { tramvaiReactLazyLocal : string ; } export const lazyComponentPlugin = ( api ) => { const { types : t } = api ; return { pre ( ) { this . tramvaiReactLazyLocal = null ; } , visitor : { ImportDeclaration ( path ) { if ( path . get ( 'source' ) . node . value === '@tramvai/react' ) { const specifiers = path . get ( 'specifiers' ) ; for ( const specifier of specifiers ) { if ( t . isImportSpecifier ( specifier . node ) && t . isIdentifier ( specifier . node . imported ) && specifier . node . imported . name === 'lazy' ) { this . tramvaiReactLazyLocal = specifier . node . local . name ; break ; } } } } , CallExpression ( path ) { if ( ! this . tramvaiReactLazyLocal ) { return ; } if ( path . get ( 'callee' ) . isIdentifier ( { name : this . tramvaiReactLazyLocal } ) ) { const imports = [ ] ; path . traverse ( { Import ( importPath ) { imports . push ( importPath ) ; } , } ) ; if ( imports . length !== 1 ) { return ; } const lazyCallPath = path ; const importPath = imports [ 0 ] . parentPath as NodePath < CallExpression > ; const funcPath = importPath . parentPath ; if ( ! funcPath . isFunctionExpression ( ) && ! funcPath . isArrowFunctionExpression ( ) ) { return ; } const properties = [ chunkNameMethod , requireSyncMethod , isReadyMethod , importAsyncMethod , requireAsyncMethod , resolveMethod , ] . map ( ( init ) => init ( api ) ) ; const opts = { lazyCallPath , funcPath , importPath } ; funcPath . replaceWith ( t . objectExpression ( properties . map ( ( factory ) => factory ( opts ) ) ) ) ; } } , } , } ; } ; export default lazyComponentPlugin ;