-
Notifications
You must be signed in to change notification settings - Fork 8
/
rollup-multi-plugin.ts
68 lines (61 loc) · 2.44 KB
/
rollup-multi-plugin.ts
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
import type FastGlob from 'fast-glob'
import fastGlob from 'fast-glob'
import path from 'path'
import type { Plugin } from 'rollup'
// This was taken from https://github.com/alfredosalzillo/rollup-plugin-multi-input
// We maintain our copy here because rollup-plugin-multi-input has issues with exporting types
const pluginName = 'rollup-plugin-multi-input'
const isString = (value: unknown): value is string => typeof value === 'string'
/**
* default multi-input Options
* */
const defaultOptions = {
// `path.sep` is used for windows support
relative: `src${path.sep}`,
}
// extract the output file name from a file name
const outputFileName = (filePath: string) => filePath.replace(/\.[^/.]+$/, '').replace(/\\/g, '/')
export type MultiInputOptions = {
glob?: FastGlob.Options
relative?: string
transformOutputPath?: (path: string, fileName: string) => string
}
/**
* multiInput is a rollup plugin to use multiple entry point and preserve the directory
* structure in the dist folder
* */
export const multiInput = (options: MultiInputOptions = defaultOptions): Plugin => {
const { glob: globOptions, relative = defaultOptions.relative, transformOutputPath } = options
return {
name: pluginName,
options(conf) {
// flat to enable input to be a string or an array
const inputs = [conf.input].flat()
// separate globs inputs string from others to enable input to be a mixed array too
const globs = inputs.filter(isString)
const others = inputs.filter((value) => !isString(value))
const normalizedGlobs = globs.map((glob) => glob.replace(/\\/g, '/'))
// get files from the globs strings and return as a Rollup entries Object
const entries = fastGlob.sync(normalizedGlobs, globOptions).map((name) => {
const filePath = path.relative(relative, name)
const isRelative = !filePath.startsWith(`..${path.sep}`)
const relativeFilePath = isRelative ? filePath : path.relative(`.${path.sep}`, name)
if (transformOutputPath) {
return [outputFileName(transformOutputPath(relativeFilePath, name)), name]
}
return [outputFileName(relativeFilePath), name]
})
const input = Object.assign(
{},
Object.fromEntries(entries),
// add no globs input to the result
...others,
)
// return the new configuration with the glob input and the non string inputs
return {
...conf,
input,
}
},
}
}