|
| 1 | +import virtual from '@rollup/plugin-virtual'; |
| 2 | +import { glob } from 'tinyglobby'; |
| 3 | + |
| 4 | +import type { Plugin } from 'rollup'; |
| 5 | + |
| 6 | +import type { RollupMultiEntryOptions } from '../types'; |
| 7 | + |
| 8 | +import { extractDirectories } from './utils'; |
| 9 | + |
| 10 | +const DEFAULT_OUTPUT = 'multi-entry.js'; |
| 11 | +const AS_IMPORT = 'import'; |
| 12 | +const AS_EXPORT = 'export * from'; |
| 13 | + |
| 14 | +export default function multiEntry(config: RollupMultiEntryOptions = {}): Plugin { |
| 15 | + let entryFileName = config.entryFileName ?? DEFAULT_OUTPUT; |
| 16 | + let include: string[] = []; |
| 17 | + let exclude: string[] = []; |
| 18 | + let exports = config.exports ?? true; |
| 19 | + |
| 20 | + const exporter = (path: string) => `${exports ? AS_EXPORT : AS_IMPORT} ${JSON.stringify(path)}`; |
| 21 | + |
| 22 | + let virtualisedEntry: { |
| 23 | + resolveId(id: string, importer?: string): string | null; |
| 24 | + load(id: string): string | null; |
| 25 | + }; |
| 26 | + |
| 27 | + return { |
| 28 | + name: 'multi-entry', |
| 29 | + |
| 30 | + options(options) { |
| 31 | + if (options.input !== entryFileName) { |
| 32 | + if (typeof options.input === 'string') { |
| 33 | + include = [options.input]; |
| 34 | + } else if (Array.isArray(options.input)) { |
| 35 | + include = options.input; |
| 36 | + } else if (options.input) { |
| 37 | + // Consider options.input as a configuration object for this plugin instead |
| 38 | + // of an `{ [entryAlias: string]: string; }` map object |
| 39 | + const input = options.input as RollupMultiEntryOptions; |
| 40 | + entryFileName = input.entryFileName ?? DEFAULT_OUTPUT; |
| 41 | + include = typeof input.include === 'string' ? [input.include] : input.include ?? []; |
| 42 | + exclude = typeof input.exclude === 'string' ? [input.exclude] : input.exclude ?? []; |
| 43 | + exports = input.exports ?? true; |
| 44 | + } |
| 45 | + } |
| 46 | + |
| 47 | + return { |
| 48 | + ...options, |
| 49 | + input: entryFileName |
| 50 | + }; |
| 51 | + }, |
| 52 | + |
| 53 | + outputOptions(options) { |
| 54 | + return { |
| 55 | + ...options, |
| 56 | + entryFileNames: config.preserveModules ? options.entryFileNames : entryFileName |
| 57 | + }; |
| 58 | + }, |
| 59 | + |
| 60 | + async buildStart(options) { |
| 61 | + const patterns = include.concat(exclude.map((pattern) => `!${pattern}`)); |
| 62 | + const entries = patterns.length |
| 63 | + ? glob(patterns, { absolute: true }) |
| 64 | + .then((paths) => paths.sort()) |
| 65 | + .then((paths) => paths.map(exporter).join('\n')) |
| 66 | + : Promise.resolve(''); |
| 67 | + virtualisedEntry = virtual({ [options.input as unknown as string]: await entries }) as any; |
| 68 | + |
| 69 | + if (this.meta.watchMode) { |
| 70 | + for (const dir of extractDirectories(patterns)) this.addWatchFile(dir); |
| 71 | + } |
| 72 | + }, |
| 73 | + |
| 74 | + resolveId(id, importer) { |
| 75 | + return virtualisedEntry && virtualisedEntry.resolveId(id, importer); |
| 76 | + }, |
| 77 | + |
| 78 | + load(id) { |
| 79 | + return virtualisedEntry && virtualisedEntry.load(id); |
| 80 | + } |
| 81 | + }; |
| 82 | +} |
0 commit comments