import { container , DefinePlugin , BannerPlugin } from 'webpack' ; import { identifier } from './constants' ; import { getSiteConfig } from './getSiteConfig' ; import { ModuleFederationPluginOptions , RemotesConfig } from './interface' ; import { getUrl } from './utils' ; const DEFAULT_DEPENDENCY_CONFIG_MAIN = 'remoteEntry.js' ; export const getPlugins = ( currentPath ) => { if ( process . env . SPA ) return [ ] ; const depURLs = { } ; const siteConfig = getSiteConfig ( currentPath ) ; if ( typeof siteConfig . name !== 'string' ) { throw new Error ( `The "name" field should be a string type in ${ currentPath }` ) ; } const { main = DEFAULT_DEPENDENCY_CONFIG_MAIN , exports , dependencies , version , registry , ... otherConfig } = siteConfig ; if ( typeof main !== 'string' ) { throw new Error ( `The "main" field should be a string type in ${ currentPath }` ) ; } if ( typeof registry !== 'undefined' && typeof registry !== 'string' ) { throw new Error ( `The "registry" field should be a string type in ${ currentPath }` ) ; } const config = { ... otherConfig , filename : main , exposes : { } , } ; if ( Array . isArray ( exports ) ) { const exposes = { } ; Object . assign ( config . exposes , exports . reduce ( ( acc , name ) => Object . assign ( acc , { [ name ] : name } ) , exposes ) ) ; } else if ( typeof siteConfig . exports !== 'undefined' ) { throw new Error ( `The "exports" field should be a Array<string> type in ${ currentPath }` ) ; } if ( dependencies ) { if ( typeof dependencies !== 'object' ) { throw new Error ( `The "dependencies" field should be a object type in ${ currentPath }` ) ; } config . remotes = Object . entries ( dependencies ) . reduce ( ( previousValue , [ dependency , dependencyConfig ] ) => { if ( typeof registry !== 'undefined' ) { if ( typeof dependencyConfig !== 'string' ) { throw new Error ( `Type Error: ${ dependency } value is ${ dependencyConfig } in the "dependencies" field, and all properties of object "dependencies" should be a string type in ${ currentPath }` ) ; } return previousValue ; } if ( typeof dependencyConfig === 'string' ) { depURLs [ dependency ] = getUrl ( dependencyConfig ) ; return Object . assign ( previousValue , { [ dependency ] : `${ dependency }@${ dependencyConfig }` , } ) ; } else if ( typeof dependencyConfig === 'object' ) { let external = dependencyConfig . external ; if ( ! external ) { if ( typeof dependencyConfig . host !== 'string' ) { throw new Error ( `Type Error: ${ dependency } config "host" field should be a string in the "dependencies" field from ${ currentPath }.` ) ; } external = `${ dependency }@${ dependencyConfig . host }${ /\/$/ . test ( dependencyConfig . host ) ? '' : '/' }${ dependencyConfig . main ?? DEFAULT_DEPENDENCY_CONFIG_MAIN }` ; } const remoteConfig = { external } ; if ( dependencyConfig . shareScope ) { remoteConfig . shareScope = dependencyConfig . shareScope ; } if ( Array . isArray ( external ) ) { depURLs [ dependency ] = external . map ( getUrl ) ; } else { depURLs [ dependency ] = getUrl ( external ) ; } return Object . assign ( previousValue , { [ dependency ] : remoteConfig , } ) ; } else { throw new Error ( `Type Error: ${ dependency } value is ${ dependencyConfig } in the "dependencies" field, and all properties of object "dependencies" should be a object/string type in ${ currentPath }` ) ; } } , { } as Record < string , RemotesConfig > ) ; } const metaData = { dependencies : ( typeof registry !== 'undefined' ? dependencies : depURLs ) ?? { } , ... ( registry ? { registry } : { } ) , ... ( version ? { version } : { } ) , } ; return [ new BannerPlugin ( { banner : `
        window.${ identifier } = window.${ identifier } ? window.${ identifier } : {};
        if (!window.${ identifier }['${ siteConfig . name }']) window.${ identifier }['${ siteConfig . name }'] = ${ JSON . stringify ( metaData ) };` , include : `${ config . filename }` , raw : true , } ) , new DefinePlugin ( { 'process.env.APP_NAME' : JSON . stringify ( `${ siteConfig . name }` ) , 'process.env.FPM_DEPS' : JSON . stringify ( `${ JSON . stringify ( metaData ) }` ) , 'process.env.FPM_REG' : JSON . stringify ( registry ) , ... ( typeof registry !== 'undefined' ? { 'process.env.FPM_MAP' : JSON . stringify ( `${ JSON . stringify ( dependencies ?? { } ) }` ) , } : { 'process.env.DEP_URLS' : JSON . stringify ( `${ JSON . stringify ( depURLs ) }` ) , } ) , } ) , new container . ModuleFederationPlugin ( { ... config , } ) , ] ; } ;