@@ -97,6 +97,9 @@ export class IOSProjectService
9797{
9898 private static IOS_PROJECT_NAME_PLACEHOLDER = "__PROJECT_NAME__" ;
9999 private static IOS_PLATFORM_NAME = "ios" ;
100+ // CLI-managed folder under the platform root where we write generated
101+ // artifacts (e.g. plugin modulemaps) so we never write into node_modules
102+ private static GENERATED_PLUGINS_DIR_NAME = ".plugins" ;
100103
101104 constructor (
102105 $fs : IFileSystem ,
@@ -530,7 +533,10 @@ export class IOSProjectService
530533 singlePlatformFramework ,
531534 path . extname ( singlePlatformFramework ) ,
532535 ) ;
533- let frameworkBinaryPath = path . join ( singlePlatformFramework , frameworkName )
536+ let frameworkBinaryPath = path . join (
537+ singlePlatformFramework ,
538+ frameworkName ,
539+ ) ;
534540 if ( library . BinaryPath ) {
535541 frameworkBinaryPath = path . join (
536542 frameworkPath ,
@@ -548,7 +554,9 @@ export class IOSProjectService
548554 frameworkPath ,
549555 path . extname ( frameworkPath ) ,
550556 ) ;
551- return await isDynamicFrameworkBundle ( path . join ( frameworkPath , frameworkName ) ) ;
557+ return await isDynamicFrameworkBundle (
558+ path . join ( frameworkPath , frameworkName ) ,
559+ ) ;
552560 }
553561 }
554562
@@ -658,7 +666,29 @@ export class IOSProjectService
658666 ) ;
659667 project . addToHeaderSearchPaths ( { relativePath : relativeHeaderSearchPath } ) ;
660668
661- this . generateModulemap ( headersSubpath , libraryName ) ;
669+ // Write the generated modulemap into a CLI-managed folder under the
670+ // platform root (never into node_modules). The modulemap references the
671+ // plugin's headers in-place via relative paths, so nothing is copied.
672+ const modulemapDir = path . join (
673+ this . getPlatformData ( projectData ) . projectRoot ,
674+ IOSProjectService . GENERATED_PLUGINS_DIR_NAME ,
675+ libraryName ,
676+ ) ;
677+ const hasModulemap = this . generateModulemap (
678+ headersSubpath ,
679+ libraryName ,
680+ modulemapDir ,
681+ ) ;
682+ if ( hasModulemap ) {
683+ // Put the modulemap dir on the header search path so clang discovers
684+ // the module there instead of inside node_modules.
685+ project . addToHeaderSearchPaths ( {
686+ relativePath : this . getLibSubpathRelativeToProjectPath (
687+ modulemapDir ,
688+ projectData ,
689+ ) ,
690+ } ) ;
691+ }
662692 this . savePbxProj ( project , projectData ) ;
663693 }
664694
@@ -1682,6 +1712,19 @@ export class IOSProjectService
16821712 project . removeFromHeaderSearchPaths ( {
16831713 relativePath : relativeHeaderSearchPath ,
16841714 } ) ;
1715+
1716+ // Remove the generated modulemap dir search path (see addStaticLibrary)
1717+ const modulemapDir = path . join (
1718+ this . getPlatformData ( projectData ) . projectRoot ,
1719+ IOSProjectService . GENERATED_PLUGINS_DIR_NAME ,
1720+ path . basename ( staticLibPath , ".a" ) ,
1721+ ) ;
1722+ project . removeFromHeaderSearchPaths ( {
1723+ relativePath : this . getLibSubpathRelativeToProjectPath (
1724+ modulemapDir ,
1725+ projectData ,
1726+ ) ,
1727+ } ) ;
16851728 } ,
16861729 ) ;
16871730
@@ -1691,29 +1734,42 @@ export class IOSProjectService
16911734 private generateModulemap (
16921735 headersFolderPath : string ,
16931736 libraryName : string ,
1694- ) : void {
1737+ modulemapDir : string ,
1738+ ) : boolean {
16951739 const headersFilter = ( fileName : string , containingFolderPath : string ) =>
16961740 path . extname ( fileName ) === ".h" &&
16971741 this . $fs . getFsStats ( path . join ( containingFolderPath , fileName ) ) . isFile ( ) ;
16981742 const headersFolderContents = this . $fs . readDirectory ( headersFolderPath ) ;
1699- let headers = _ ( headersFolderContents )
1700- . filter ( ( item ) => headersFilter ( item , headersFolderPath ) )
1701- . value ( ) ;
1743+ const headerFiles = headersFolderContents . filter ( ( item ) =>
1744+ headersFilter ( item , headersFolderPath ) ,
1745+ ) ;
17021746
1703- if ( ! headers . length ) {
1704- this . $fs . deleteFile ( path . join ( headersFolderPath , "module.modulemap" ) ) ;
1705- return ;
1747+ const modulemapPath = path . join ( modulemapDir , "module.modulemap" ) ;
1748+
1749+ if ( ! headerFiles . length ) {
1750+ if ( this . $fs . exists ( modulemapPath ) ) {
1751+ this . $fs . deleteFile ( modulemapPath ) ;
1752+ }
1753+ return false ;
17061754 }
17071755
1708- headers = _ . map ( headers , ( value ) => `header "${ value } "` ) ;
1756+ // Reference the plugin's headers (still in node_modules) relative to the
1757+ // generated modulemap's location, so we don't copy headers or write into
1758+ // node_modules.
1759+ const headers = _ . map ( headerFiles , ( value ) => {
1760+ const relativeHeaderPath = path . relative (
1761+ modulemapDir ,
1762+ path . join ( headersFolderPath , value ) ,
1763+ ) ;
1764+ return `header "${ relativeHeaderPath } "` ;
1765+ } ) ;
17091766
17101767 const modulemap = `module ${ libraryName } { explicit module ${ libraryName } { ${ headers . join (
17111768 " " ,
17121769 ) } } }`;
1713- this . $fs . writeFile (
1714- path . join ( headersFolderPath , "module.modulemap" ) ,
1715- modulemap ,
1716- ) ;
1770+ this . $fs . ensureDirectoryExists ( modulemapDir ) ;
1771+ this . $fs . writeFile ( modulemapPath , modulemap ) ;
1772+ return true ;
17171773 }
17181774
17191775 private async mergeProjectXcconfigFiles (
0 commit comments