diff --git a/.changeset/yellow-frogs-melt.md b/.changeset/yellow-frogs-melt.md new file mode 100644 index 000000000..8dae57125 --- /dev/null +++ b/.changeset/yellow-frogs-melt.md @@ -0,0 +1,5 @@ +--- +"@callstack/repack": major +--- + +BREAKING CHANGES: Removed `entryName` config option from `DevelopmentPlugin`, `OutputPlugin` and `RepackPlugin` - it is now obtained automatically from configuration diff --git a/packages/repack/src/plugins/DevelopmentPlugin.ts b/packages/repack/src/plugins/DevelopmentPlugin.ts index 5770fe162..60f4804c1 100644 --- a/packages/repack/src/plugins/DevelopmentPlugin.ts +++ b/packages/repack/src/plugins/DevelopmentPlugin.ts @@ -12,7 +12,6 @@ type PackageJSON = { version: string }; * {@link DevelopmentPlugin} configuration options. */ export interface DevelopmentPluginConfig { - entryName?: string; platform: string; devServer?: DevServerOptions; } @@ -143,7 +142,7 @@ export class DevelopmentPlugin implements RspackPluginInstance { } ); } else { - if (!this.config.entryName) { + if (!('main' in compiler.options.entry)) { // Add dev entries as global entries for (const entry of devEntries) { new compiler.webpack.EntryPlugin(compiler.context, entry, { @@ -158,25 +157,21 @@ export class DevelopmentPlugin implements RspackPluginInstance { ); } - const entries = - compiler.options.entry[this.config.entryName].import ?? []; + const entries = compiler.options.entry.main.import ?? []; const scriptManagerEntryIndex = entries.findIndex((entry) => entry.includes('InitializeScriptManager') ); if (scriptManagerEntryIndex !== -1) { // Insert devEntries after 'InitializeScriptManager' - compiler.options.entry[this.config.entryName].import = [ + compiler.options.entry.main.import = [ ...entries.slice(0, scriptManagerEntryIndex + 1), ...devEntries, ...entries.slice(scriptManagerEntryIndex + 1), ]; } else { // 'InitializeScriptManager' entry not found, insert devEntries before the normal entries - compiler.options.entry[this.config.entryName].import = [ - ...devEntries, - ...entries, - ]; + compiler.options.entry.main.import = [...devEntries, ...entries]; } } } diff --git a/packages/repack/src/plugins/NativeEntryPlugin.ts b/packages/repack/src/plugins/NativeEntryPlugin.ts index c52f774f7..26b217419 100644 --- a/packages/repack/src/plugins/NativeEntryPlugin.ts +++ b/packages/repack/src/plugins/NativeEntryPlugin.ts @@ -8,10 +8,6 @@ import type { import { isRspackCompiler } from './utils/isRspackCompiler.js'; export interface NativeEntryPluginConfig { - /** - * Name of the chunk that is the first to load on the device. - */ - entryName: string; /** * Absolute location to JS file with initialization logic for React Native. * Useful if you want to built for out-of-tree platforms. @@ -40,6 +36,10 @@ export class NativeEntryPlugin implements RspackPluginInstance { } apply(compiler: Compiler) { + if ('main' in compiler.options.entry) { + return; + } + const reactNativePath = this.getReactNativePath( compiler.options.resolve.alias?.['react-native'] ); @@ -89,14 +89,16 @@ export class NativeEntryPlugin implements RspackPluginInstance { ); } else { const prependEntries = (entryConfig: EntryStaticNormalized) => { - if (!(this.config.entryName in entryConfig)) { + // temporary placeholder for entry name + // removed in PR that removes workaround for reordering entries + if (!('main' in entryConfig)) { throw new Error( - `Entry '${this.config.entryName}' does not exist in the entry configuration` + `Entry 'main' does not exist in the entry configuration` ); } - entryConfig[this.config.entryName].import = [ + entryConfig.main.import = [ ...entries, - ...(entryConfig[this.config.entryName].import ?? []), + ...(entryConfig.main.import ?? []), ]; return entryConfig; }; diff --git a/packages/repack/src/plugins/OutputPlugin/OutputPlugin.ts b/packages/repack/src/plugins/OutputPlugin/OutputPlugin.ts index 66bac9bc8..9b33eff0a 100644 --- a/packages/repack/src/plugins/OutputPlugin/OutputPlugin.ts +++ b/packages/repack/src/plugins/OutputPlugin/OutputPlugin.ts @@ -26,7 +26,6 @@ export class OutputPlugin implements RspackPluginInstance { validateConfig(config); this.config.enabled = this.config.enabled ?? true; - this.config.entryName = this.config.entryName ?? 'main'; this.config.extraChunks = this.config.extraChunks ?? [ { include: /.*/, @@ -140,6 +139,31 @@ export class OutputPlugin implements RspackPluginInstance { const matchChunkToSpecs = this.createChunkMatcher(matchObject); const auxiliaryAssets = new Set(); + const entryChunkNames = new Set(); + + compiler.hooks.entryOption.tap( + 'RepackOutputPlugin', + (_, entryNormalized) => { + if (typeof entryNormalized === 'function') { + throw new Error( + '[RepackOutputPlugin] Dynamic entry (function) is not supported.' + ); + } + + Object.keys(entryNormalized).forEach((entryName) => { + const entryChunkName = + entryNormalized[entryName].runtime || entryName; + entryChunkNames.add(entryChunkName); + }); + + if (entryChunkNames.size > 1) { + throw new Error( + '[RepackOutputPlugin] Multiple entry chunks found. ' + + 'Only one entry chunk is allowed as a native entrypoint.' + ); + } + } + ); compiler.hooks.done.tapPromise('RepackOutputPlugin', async (stats) => { const compilationStats = stats.toJson({ @@ -205,7 +229,7 @@ export class OutputPlugin implements RspackPluginInstance { for (const chunk of localChunks) { // Process entry chunk - only one entry chunk is allowed here localAssetsCopyProcessor?.enqueueChunk(chunk, { - isEntry: chunk.id! === this.config.entryName, + isEntry: entryChunkNames.has(chunk.id!.toString()), sourceMapFile: this.getRelatedSourceMap(chunk), }); } diff --git a/packages/repack/src/plugins/OutputPlugin/config.ts b/packages/repack/src/plugins/OutputPlugin/config.ts index 043624ee2..f567d21a9 100644 --- a/packages/repack/src/plugins/OutputPlugin/config.ts +++ b/packages/repack/src/plugins/OutputPlugin/config.ts @@ -22,7 +22,6 @@ const configSchema: Schema = { context: { type: 'string' }, platform: { type: 'string' }, enabled: { type: 'boolean' }, - entryName: { type: 'string' }, output: { type: 'object', properties: { diff --git a/packages/repack/src/plugins/OutputPlugin/types.ts b/packages/repack/src/plugins/OutputPlugin/types.ts index 6fc8c91c4..e8764c90b 100644 --- a/packages/repack/src/plugins/OutputPlugin/types.ts +++ b/packages/repack/src/plugins/OutputPlugin/types.ts @@ -70,9 +70,6 @@ export interface OutputPluginConfig { */ enabled?: boolean; - /** The entry chunk name, `main` by default. */ - entryName?: string; - /** * Output options specifying where to save generated bundle, source map and assets. */ diff --git a/packages/repack/src/plugins/RepackPlugin.ts b/packages/repack/src/plugins/RepackPlugin.ts index e87a2d3d1..15fbb4f2a 100644 --- a/packages/repack/src/plugins/RepackPlugin.ts +++ b/packages/repack/src/plugins/RepackPlugin.ts @@ -43,9 +43,6 @@ export interface RepackPluginConfig { */ output: OutputPluginConfig['output']; - /** The entry chunk name, `main` by default. */ - entryName?: string; - /** * Absolute location to JS file with initialization logic for React Native. * Useful if you want to built for out-of-tree platforms. @@ -126,29 +123,12 @@ export class RepackPlugin implements RspackPluginInstance { this.config.logger = this.config.logger ?? true; } - private getEntryName(compiler: Compiler) { - if (this.config.entryName) { - return this.config.entryName; - } - - if ( - typeof compiler.options.entry === 'object' && - 'main' in compiler.options.entry - ) { - return 'main'; - } - - return undefined; - } - /** * Apply the plugin. * * @param compiler Webpack compiler instance. */ apply(compiler: Compiler) { - const entryName = this.getEntryName(compiler); - new compiler.webpack.DefinePlugin({ __DEV__: JSON.stringify(this.config.mode === 'development'), }).apply(compiler); @@ -159,19 +139,15 @@ export class RepackPlugin implements RspackPluginInstance { new OutputPlugin({ platform: this.config.platform, - enabled: !this.config.devServer && !!entryName, + enabled: !this.config.devServer, context: this.config.context, output: this.config.output, - entryName: this.config.entryName, extraChunks: this.config.extraChunks, }).apply(compiler); - if (entryName) { - new NativeEntryPlugin({ - entryName, - initializeCoreLocation: this.config.initializeCore, - }).apply(compiler); - } + new NativeEntryPlugin({ + initializeCoreLocation: this.config.initializeCore, + }).apply(compiler); new RepackTargetPlugin({ hmr: this.config.devServer?.hmr, @@ -179,7 +155,6 @@ export class RepackPlugin implements RspackPluginInstance { new DevelopmentPlugin({ devServer: this.config.devServer, - entryName, platform: this.config.platform, }).apply(compiler);