@samual/rolldown-config
Version:
My Rolldown config
121 lines (120 loc) • 3.89 kB
JavaScript
import { parseAsync, traverse } from "@babel/core"
import babelPluginSyntaxTypescript from "@babel/plugin-syntax-typescript"
import babelPresetEnv from "@babel/preset-env"
import babelPresetTypescript from "@babel/preset-typescript"
import { babel } from "@rollup/plugin-babel"
import terser from "@rollup/plugin-terser"
import { expect } from "@samual/assert"
import { babelPluginHere } from "babel-plugin-here"
import { babelPluginVitest } from "babel-plugin-vitest"
import { defu } from "defu"
import { readdir } from "fs/promises"
import { cpus } from "os"
import * as Path from "path"
import { dts } from "rolldown-plugin-dts"
import prettier from "rolldown-plugin-prettier"
const VITEST_EXTENSION_PREFIXES = [".test", ".bench", ".benchmark"],
INCLUDE_EXTENSION = {
".js": { excludePrefix: VITEST_EXTENSION_PREFIXES },
".ts": { excludePrefix: [".d", ...VITEST_EXTENSION_PREFIXES] }
},
IncludeExtensionEntries = Object.entries(INCLUDE_EXTENSION),
rolldownConfig = async ({
sourcePath = "src",
rolldownOptions,
babelOptions,
terserOptions,
prettierOptions,
experimental
} = {}) => {
prettierOptions = defu(prettierOptions, {
parser: "espree",
useTabs: !0,
tabWidth: 4,
arrowParens: "avoid",
printWidth: 120,
semi: !1,
trailingComma: "none"
})
const config = defu(rolldownOptions, {
external: source => !(Path.isAbsolute(source) || "." == source[0]),
input: Object.fromEntries(
(await readdir(sourcePath, { withFileTypes: !0, recursive: !0 }))
.filter(dirent => dirent.isFile())
.map(dirent => Path.join(dirent.parentPath, dirent.name))
.flatMap(path => {
const includeExtensionEntry = IncludeExtensionEntries.find(([extension]) =>
path.endsWith(extension)
)
if (!includeExtensionEntry) return []
const [extension, { excludePrefix: prefixes }] = includeExtensionEntry
return prefixes?.some(prefix => path.endsWith(prefix + extension))
? []
: [[path.slice(sourcePath.length + 1, -extension.length), path]]
})
),
output: { dir: "dist" },
plugins: [
babel(
defu(babelOptions, {
babelHelpers: "bundled",
extensions: [".ts"],
presets: [
[babelPresetEnv, { targets: { node: "22.12" } }],
[babelPresetTypescript, { optimizeConstEnums: !0 }]
],
plugins: [babelPluginHere(), babelPluginVitest()]
})
),
terser(
defu(terserOptions, {
compress: { passes: Infinity, unsafe: !0, sequences: !1, keep_infinity: !0 },
maxWorkers: Math.floor(cpus().length / 2),
mangle: !1,
ecma: 2020
})
),
experimental?.noSideEffects && {
name: "no-side-effects",
async renderChunk(code) {
const ast = expect(
await parseAsync(code, { plugins: [babelPluginSyntaxTypescript] }),
"src/default.ts:178:95"
),
indexes = []
traverse(ast, {
Function(path) {
!path.node.loc ||
path.node.type.endsWith("Method") ||
(path.isExpression() && "VariableDeclarator" != path.parentPath.node.type) ||
!path.isPure() ||
indexes.push(path.node.loc.start.index)
}
})
indexes.sort((a, b) => b - a)
for (const index of indexes)
code = `${code.slice(0, index)}/*@__NO_SIDE_EFFECTS__*/${code.slice(index)}`
return code
}
},
experimental?.disablePrettier ? void 0 : prettier(prettierOptions)
],
preserveEntrySignatures: "strict",
treeshake: { moduleSideEffects: !1 }
})
return experimental?.dts
? [
config,
{
external: config.external,
input: config.input,
output: config.output,
plugins: [
dts({ oxc: {}, emitDtsOnly: !0 }),
experimental.disablePrettier ? void 0 : prettier({ ...prettierOptions, parser: "babel-ts" })
]
}
]
: config
}
export { rolldownConfig }