import { getOptions } from 'loader-utils' ; import { loader } from 'webpack' ; import recast from 'recast' ; import { types } from 'recast' ; import { classDecoratorCompiler , classPropertyCompiler } from './compiler' ; export param { string } source returns { string } export default function indivLoader ( source ) { const that = this ; let rootPath = that . context ; const options = getOptions ( that ) ; let useTypeScript = false ; if ( /\.ts$/ . test ( that . resourcePath ) || /\.tsx$/ . test ( that . resourcePath ) ) useTypeScript = true ; if ( /\.js$/ . test ( that . resourcePath ) || /\.jsx$/ . test ( that . resourcePath ) ) useTypeScript = false ; if ( options && options . useTypeScript ) useTypeScript = true ; if ( options && options . templateRootPath ) rootPath = options . templateRootPath ; const parseVnodeOptions = { components : [ ] , directives : [ ] , } ; const componentMap = new Map < string , { templateUrl : string ; templateString : string ; classBody : any ; } > ( ) ; let ast ; try { if ( useTypeScript ) ast = recast . parse ( source , { parser : require ( 'recast/parsers/typescript' ) } ) ; if ( ! useTypeScript ) ast = recast . parse ( source , { parser : require ( 'recast/parsers/babel' ) } ) ; recast . visit ( ast , { visitClassDeclaration ( this , path ) { classDecoratorCompiler ( rootPath , path . value , parseVnodeOptions , componentMap ) ; this . traverse ( path ) ; } , } ) ; } catch ( e ) { that . emitError ( e ) ; } componentMap . forEach ( ( templateInfo ) => { that . addDependency ( templateInfo . templateUrl ) ; classPropertyCompiler ( templateInfo , useTypeScript ) ; } ) ; return recast . print ( ast ) . code ; }