import * as nodePath from 'path' ; import * as fs from 'fs' ; import * as mimeType from 'mime-types' ; import * as parser from '@babel/parser' ; import traverse from '@babel/traverse' ; import { readConfig , resolveMainFilePath } from '@tarojs/helper' ; import { globalAny } from './types/index' ; const RN_CSS_EXT = [ '.css' , '.scss' , '.sass' , '.less' , '.styl' , '.stylus' ] ; export function getConfigFilePath ( filePath ) { return resolveMainFilePath ( `${ filePath . replace ( nodePath . extname ( filePath ) , '' ) }.config` ) ; } export function getConfigContent ( path ) { if ( ! path ) return { } ; const fileConfigPath = getConfigFilePath ( path ) ; const content = readConfig ( fileConfigPath ) ; return content ; } export function getStyleCode ( code , basePath ) { const ast = parser . parse ( code , { sourceType : 'module' , plugins : [ 'jsx' , 'typescript' , 'classProperties' , 'decorators-legacy' ] } ) ; const styleTypes = RN_CSS_EXT ; const styleSource = [ ] ; traverse ( ast , { ImportDeclaration ( path ) { const node = path . node ; const resource = node . source . value ; const ext = nodePath . extname ( resource ) ; if ( ! styleTypes . includes ( ext ) ) { return ; } let sourceName = '' ; if ( node . specifiers . length ) { sourceName = node . specifiers [ 0 ] . local . name ; } const realPath = nodePath . resolve ( basePath , resource ) ; const fileName = nodePath . basename ( realPath ) ; styleSource . push ( { name : sourceName , path : realPath , fileName : fileName } ) ; } } ) ; return styleSource ; } export function isPageFile ( file , sourceDir ) { if ( ( /node_modules/ . test ( file ) ) || file . indexOf ( sourceDir ) === - 1 ) return false ; const pagesList = globalAny . __taroAppPages || [ ] ; const dirname = nodePath . dirname ( file ) . replace ( /\\/g , '/' ) ; const fileObj = nodePath . parse ( file ) ; const name = fileObj . name . split ( '.' ) [ 0 ] ; const filePath = `${ dirname }/${ name }` ; const filename = nodePath . basename ( file ) . replace ( nodePath . extname ( file ) , '' ) ; return pagesList . includes ( filePath ) && ! ( filename . endsWith ( '.config' ) ) ; } function isJSXSource ( file , code ) { let result = false ; if ( /.(j|t)sx$/ . test ( file ) ) { result = true ; } else if ( file . endsWith ( '.ts' ) ) { result = false ; } else { const ast = parser . parse ( code , { sourceType : 'module' , plugins : [ 'jsx' , 'classProperties' , 'decorators-legacy' ] } ) ; traverse ( ast , { JSXElement ( ) { result = true ; } } ) ; } return result ; } export function isSourceComponent ( file , code , sourceDir ) { if ( ( /node_modules/ . test ( file ) ) || file . indexOf ( sourceDir ) === - 1 ) return false ; return isJSXSource ( file , code ) ; } export function isNPMComponent ( file , code , rn ) { if ( ! rn ?. resolve ?. include ?. find ( npm => file . includes ( nodePath . join ( 'node_modules' , npm ) ) ) ) { return false ; } return isJSXSource ( file , code ) ; } export function getFileContent ( fileName ) { let code = '' ; if ( ! fs . existsSync ( fileName ) ) return code ; try { code = fs . readFileSync ( fileName , 'utf-8' ) . toString ( ) ; } catch ( error ) { code = '' ; } return code ; } export function getCommonStyle ( appPath , basePath ) { let styles = [ ] ; const jsExt = [ 'tsx' , 'ts' , 'jsx' , 'js' ] ; let codeStr = '' ; for ( let i = 0 ; i < jsExt . length ; i ++ ) { const rnfilePath = `${ appPath }.rn.${ jsExt [ i ] }` ; const rnFileContent = getFileContent ( rnfilePath ) ; if ( ! rnFileContent ) { codeStr = rnFileContent ; break ; } } if ( ! codeStr ) { for ( let i = 0 ; i < jsExt . length ; i ++ ) { const filePath = `${ appPath }.${ jsExt [ i ] }` ; const fileContent = getFileContent ( filePath ) ; if ( fileContent ) { codeStr = fileContent ; break ; } } } if ( ! codeStr ) return styles ; styles = getStyleCode ( codeStr , basePath ) ; return styles ; } export function parseBase64Image ( iconPath , baseRoot ) { const imagePath = nodePath . join ( baseRoot , iconPath ) ; const fileMimeType = mimeType . lookup ( imagePath ) ; if ( ! fileMimeType . toString ( ) . includes ( 'image' ) ) { return iconPath ; } const data = fs . readFileSync ( imagePath ) ; const buff = Buffer . from ( data ) . toString ( 'base64' ) ; const base64 = 'data:' + fileMimeType + ';base64,' + buff ; return base64 ; }