From eca045bc119ab1ab97ff02e3aa7134a03cb32620 Mon Sep 17 00:00:00 2001 From: Jack Westbrook Date: Tue, 25 Feb 2025 09:11:09 +0100 Subject: [PATCH] Build: Reduce repetition in rollup configs (#93916) * build(packages): add extendable pieces of rollup config * build(packages): rewrite rollup configs to make use of extendable parts --- packages/grafana-data/rollup.config.ts | 50 ++-------------- .../grafana-e2e-selectors/rollup.config.ts | 50 ++-------------- packages/grafana-flamegraph/rollup.config.ts | 50 ++-------------- packages/grafana-icons/package.json | 1 + packages/grafana-icons/rollup.config.ts | 42 ++------------ packages/grafana-prometheus/rollup.config.ts | 51 ++-------------- packages/grafana-runtime/rollup.config.ts | 50 ++-------------- packages/grafana-schema/rollup.config.ts | 57 +++--------------- packages/grafana-ui/rollup.config.ts | 48 ++------------- packages/rollup.config.parts.ts | 58 +++++++++++++++++++ 10 files changed, 109 insertions(+), 348 deletions(-) create mode 100644 packages/rollup.config.parts.ts diff --git a/packages/grafana-data/rollup.config.ts b/packages/grafana-data/rollup.config.ts index 9894024f99c..5a913449466 100644 --- a/packages/grafana-data/rollup.config.ts +++ b/packages/grafana-data/rollup.config.ts @@ -1,53 +1,15 @@ -import resolve from '@rollup/plugin-node-resolve'; import { createRequire } from 'node:module'; -import path from 'path'; -import dts from 'rollup-plugin-dts'; -import esbuild from 'rollup-plugin-esbuild'; -import { nodeExternals } from 'rollup-plugin-node-externals'; + +import { entryPoint, plugins, esmOutput, cjsOutput, tsDeclarationOutput } from '../rollup.config.parts'; const rq = createRequire(import.meta.url); const pkg = rq('./package.json'); -const legacyOutputDefaults = { - esModule: true, - interop: 'compat', -}; - export default [ { - input: 'src/index.ts', - plugins: [ - nodeExternals({ deps: true, packagePath: './package.json' }), - resolve(), - esbuild({ - target: 'es2018', - tsconfig: 'tsconfig.build.json', - }), - ], - output: [ - { - format: 'cjs', - sourcemap: true, - dir: path.dirname(pkg.publishConfig.main), - ...legacyOutputDefaults, - }, - { - format: 'esm', - sourcemap: true, - dir: path.dirname(pkg.publishConfig.module), - preserveModules: true, - // @ts-expect-error (TS cannot assure that `process.env.PROJECT_CWD` is a string) - preserveModulesRoot: path.join(process.env.PROJECT_CWD, `packages/grafana-data/src`), - ...legacyOutputDefaults, - }, - ], - }, - { - input: './compiled/index.d.ts', - plugins: [dts()], - output: { - file: pkg.publishConfig.types, - format: 'es', - }, + input: entryPoint, + plugins, + output: [cjsOutput(pkg), esmOutput(pkg, 'grafana-data')], }, + tsDeclarationOutput(pkg), ]; diff --git a/packages/grafana-e2e-selectors/rollup.config.ts b/packages/grafana-e2e-selectors/rollup.config.ts index b70662c33a8..338dae23ac9 100644 --- a/packages/grafana-e2e-selectors/rollup.config.ts +++ b/packages/grafana-e2e-selectors/rollup.config.ts @@ -1,53 +1,15 @@ -import resolve from '@rollup/plugin-node-resolve'; import { createRequire } from 'node:module'; -import path from 'path'; -import dts from 'rollup-plugin-dts'; -import esbuild from 'rollup-plugin-esbuild'; -import { nodeExternals } from 'rollup-plugin-node-externals'; + +import { cjsOutput, entryPoint, esmOutput, plugins, tsDeclarationOutput } from '../rollup.config.parts'; const rq = createRequire(import.meta.url); const pkg = rq('./package.json'); -const legacyOutputDefaults = { - esModule: true, - interop: 'compat', -}; - export default [ { - input: 'src/index.ts', - plugins: [ - nodeExternals({ deps: true, packagePath: './package.json' }), - resolve(), - esbuild({ - target: 'es2018', - tsconfig: 'tsconfig.build.json', - }), - ], - output: [ - { - format: 'cjs', - sourcemap: true, - dir: path.dirname(pkg.publishConfig.main), - ...legacyOutputDefaults, - }, - { - format: 'esm', - sourcemap: true, - dir: path.dirname(pkg.publishConfig.module), - preserveModules: true, - // @ts-expect-error (TS cannot assure that `process.env.PROJECT_CWD` is a string) - preserveModulesRoot: path.join(process.env.PROJECT_CWD, `packages/grafana-e2e-selectors/src`), - ...legacyOutputDefaults, - }, - ], - }, - { - input: './compiled/index.d.ts', - plugins: [dts()], - output: { - file: pkg.publishConfig.types, - format: 'es', - }, + input: entryPoint, + plugins, + output: [cjsOutput(pkg), esmOutput(pkg, 'grafana-e2e-selectors')], }, + tsDeclarationOutput(pkg), ]; diff --git a/packages/grafana-flamegraph/rollup.config.ts b/packages/grafana-flamegraph/rollup.config.ts index 86d0ad86cfa..dbd64b4abdb 100644 --- a/packages/grafana-flamegraph/rollup.config.ts +++ b/packages/grafana-flamegraph/rollup.config.ts @@ -1,53 +1,15 @@ -import resolve from '@rollup/plugin-node-resolve'; import { createRequire } from 'node:module'; -import path from 'path'; -import dts from 'rollup-plugin-dts'; -import esbuild from 'rollup-plugin-esbuild'; -import { nodeExternals } from 'rollup-plugin-node-externals'; + +import { cjsOutput, entryPoint, esmOutput, plugins, tsDeclarationOutput } from '../rollup.config.parts'; const rq = createRequire(import.meta.url); const pkg = rq('./package.json'); -const legacyOutputDefaults = { - esModule: true, - interop: 'compat', -}; - export default [ { - input: 'src/index.ts', - plugins: [ - nodeExternals({ deps: true, packagePath: './package.json' }), - resolve(), - esbuild({ - target: 'es2018', - tsconfig: 'tsconfig.build.json', - }), - ], - output: [ - { - format: 'cjs', - sourcemap: true, - dir: path.dirname(pkg.publishConfig.main), - ...legacyOutputDefaults, - }, - { - format: 'esm', - sourcemap: true, - dir: path.dirname(pkg.publishConfig.module), - preserveModules: true, - // @ts-expect-error (TS cannot assure that `process.env.PROJECT_CWD` is a string) - preserveModulesRoot: path.join(process.env.PROJECT_CWD, `packages/grafana-ui/src`), - ...legacyOutputDefaults, - }, - ], - }, - { - input: './compiled/index.d.ts', - plugins: [dts()], - output: { - file: pkg.publishConfig.types, - format: 'es', - }, + input: entryPoint, + plugins, + output: [cjsOutput(pkg), esmOutput(pkg, 'grafana-flamegraph')], }, + tsDeclarationOutput(pkg), ]; diff --git a/packages/grafana-icons/package.json b/packages/grafana-icons/package.json index dec83cf36f8..c08c70e14ed 100644 --- a/packages/grafana-icons/package.json +++ b/packages/grafana-icons/package.json @@ -16,6 +16,7 @@ "types": "src/index.ts", "publishConfig": { "main": "dist/index.js", + "module": "dist/index.js", "types": "dist/index.d.ts", "access": "public" }, diff --git a/packages/grafana-icons/rollup.config.ts b/packages/grafana-icons/rollup.config.ts index 6bf3c3b536e..fde6ca115b0 100644 --- a/packages/grafana-icons/rollup.config.ts +++ b/packages/grafana-icons/rollup.config.ts @@ -1,45 +1,15 @@ -import resolve from '@rollup/plugin-node-resolve'; import { createRequire } from 'node:module'; -import path from 'path'; -import dts from 'rollup-plugin-dts'; -import esbuild from 'rollup-plugin-esbuild'; -import { nodeExternals } from 'rollup-plugin-node-externals'; + +import { entryPoint, esmOutput, plugins, tsDeclarationOutput } from '../rollup.config.parts'; const rq = createRequire(import.meta.url); const pkg = rq('./package.json'); -const legacyOutputDefaults = { - esModule: true, - interop: 'compat', -}; - export default [ { - input: 'src/index.ts', - plugins: [ - nodeExternals({ deps: true, packagePath: './package.json' }), - resolve(), - esbuild({ - target: 'es2018', - tsconfig: 'tsconfig.build.json', - }), - ], - output: [ - { - format: 'esm', - sourcemap: true, - dir: path.dirname(pkg.publishConfig.main), - preserveModules: true, - ...legacyOutputDefaults, - }, - ], - }, - { - input: 'src/index.ts', - plugins: [dts()], - output: { - file: pkg.publishConfig.types, - format: 'es', - }, + input: entryPoint, + plugins, + output: esmOutput(pkg, 'grafana-icons'), }, + tsDeclarationOutput(pkg, { input: 'src/index.ts' }), ]; diff --git a/packages/grafana-prometheus/rollup.config.ts b/packages/grafana-prometheus/rollup.config.ts index 7e630257c36..5c7d9dd3c04 100644 --- a/packages/grafana-prometheus/rollup.config.ts +++ b/packages/grafana-prometheus/rollup.config.ts @@ -1,55 +1,16 @@ import image from '@rollup/plugin-image'; -import resolve from '@rollup/plugin-node-resolve'; import { createRequire } from 'node:module'; -import path from 'path'; -import dts from 'rollup-plugin-dts'; -import esbuild from 'rollup-plugin-esbuild'; -import { nodeExternals } from 'rollup-plugin-node-externals'; + +import { cjsOutput, entryPoint, esmOutput, plugins, tsDeclarationOutput } from '../rollup.config.parts'; const rq = createRequire(import.meta.url); const pkg = rq('./package.json'); -const legacyOutputDefaults = { - esModule: true, - interop: 'compat', -}; - export default [ { - input: 'src/index.ts', - plugins: [ - nodeExternals({ deps: true, packagePath: './package.json' }), - resolve(), - esbuild({ - target: 'es2018', - tsconfig: 'tsconfig.build.json', - }), - image(), - ], - output: [ - { - format: 'cjs', - sourcemap: true, - dir: path.dirname(pkg.publishConfig.main), - ...legacyOutputDefaults, - }, - { - format: 'esm', - sourcemap: true, - dir: path.dirname(pkg.publishConfig.module), - preserveModules: true, - // @ts-expect-error (TS cannot assure that `process.env.PROJECT_CWD` is a string) - preserveModulesRoot: path.join(process.env.PROJECT_CWD, `packages/grafana-prometheus/src`), - ...legacyOutputDefaults, - }, - ], - }, - { - input: './compiled/index.d.ts', - plugins: [dts()], - output: { - file: pkg.publishConfig.types, - format: 'es', - }, + input: entryPoint, + plugins: [...plugins, image()], + output: [cjsOutput(pkg), esmOutput(pkg, 'grafana-prometheus')], }, + tsDeclarationOutput(pkg), ]; diff --git a/packages/grafana-runtime/rollup.config.ts b/packages/grafana-runtime/rollup.config.ts index 25992a93441..02f523deee1 100644 --- a/packages/grafana-runtime/rollup.config.ts +++ b/packages/grafana-runtime/rollup.config.ts @@ -1,53 +1,15 @@ -import resolve from '@rollup/plugin-node-resolve'; import { createRequire } from 'node:module'; -import path from 'path'; -import dts from 'rollup-plugin-dts'; -import esbuild from 'rollup-plugin-esbuild'; -import { nodeExternals } from 'rollup-plugin-node-externals'; + +import { cjsOutput, entryPoint, esmOutput, plugins, tsDeclarationOutput } from '../rollup.config.parts'; const rq = createRequire(import.meta.url); const pkg = rq('./package.json'); -const legacyOutputDefaults = { - esModule: true, - interop: 'compat', -}; - export default [ { - input: 'src/index.ts', - plugins: [ - nodeExternals({ deps: true, packagePath: './package.json' }), - resolve(), - esbuild({ - target: 'es2018', - tsconfig: 'tsconfig.build.json', - }), - ], - output: [ - { - format: 'cjs', - sourcemap: true, - dir: path.dirname(pkg.publishConfig.main), - ...legacyOutputDefaults, - }, - { - format: 'esm', - sourcemap: true, - dir: path.dirname(pkg.publishConfig.module), - preserveModules: true, - // @ts-expect-error (TS cannot assure that `process.env.PROJECT_CWD` is a string) - preserveModulesRoot: path.join(process.env.PROJECT_CWD, `packages/grafana-runtime/src`), - ...legacyOutputDefaults, - }, - ], - }, - { - input: './compiled/index.d.ts', - plugins: [dts()], - output: { - file: pkg.publishConfig.types, - format: 'es', - }, + input: entryPoint, + plugins, + output: [cjsOutput(pkg), esmOutput(pkg, 'grafana-runtime')], }, + tsDeclarationOutput(pkg), ]; diff --git a/packages/grafana-schema/rollup.config.ts b/packages/grafana-schema/rollup.config.ts index 6a2f736c944..aa0c96aff06 100644 --- a/packages/grafana-schema/rollup.config.ts +++ b/packages/grafana-schema/rollup.config.ts @@ -1,57 +1,22 @@ -import resolve from '@rollup/plugin-node-resolve'; import { glob } from 'glob'; import { createRequire } from 'node:module'; import { fileURLToPath } from 'node:url'; import path from 'path'; -import dts from 'rollup-plugin-dts'; -import esbuild from 'rollup-plugin-esbuild'; -import { nodeExternals } from 'rollup-plugin-node-externals'; + +import { cjsOutput, entryPoint, esmOutput, plugins, tsDeclarationOutput } from '../rollup.config.parts'; const rq = createRequire(import.meta.url); const pkg = rq('./package.json'); -const legacyOutputDefaults = { - esModule: true, - interop: 'compat', -}; +const [_, noderesolve, esbuild] = plugins; export default [ { - input: 'src/index.ts', - plugins: [ - nodeExternals({ deps: true, packagePath: './package.json' }), - resolve(), - esbuild({ - target: 'es2018', - tsconfig: 'tsconfig.build.json', - }), - ], - output: [ - { - format: 'cjs', - sourcemap: true, - dir: path.dirname(pkg.publishConfig.main), - ...legacyOutputDefaults, - }, - { - format: 'esm', - sourcemap: true, - dir: path.dirname(pkg.publishConfig.module), - preserveModules: true, - // @ts-expect-error (TS cannot assure that `process.env.PROJECT_CWD` is a string) - preserveModulesRoot: path.join(process.env.PROJECT_CWD, `packages/grafana-schema/src`), - ...legacyOutputDefaults, - }, - ], - }, - { - input: './dist/esm/index.d.ts', - plugins: [dts()], - output: { - file: pkg.publishConfig.types, - format: 'es', - }, + input: entryPoint, + plugins, + output: [cjsOutput(pkg), esmOutput(pkg, 'grafana-schema')], }, + tsDeclarationOutput(pkg, { input: './dist/esm/index.d.ts' }), { input: Object.fromEntries( glob @@ -61,13 +26,7 @@ export default [ fileURLToPath(new URL(file, import.meta.url)), ]) ), - plugins: [ - resolve(), - esbuild({ - target: 'es2018', - tsconfig: 'tsconfig.build.json', - }), - ], + plugins: [noderesolve, esbuild], output: { format: 'esm', dir: path.dirname(pkg.publishConfig.module), diff --git a/packages/grafana-ui/rollup.config.ts b/packages/grafana-ui/rollup.config.ts index b18618dd7ea..d3cb5c2d8b8 100644 --- a/packages/grafana-ui/rollup.config.ts +++ b/packages/grafana-ui/rollup.config.ts @@ -1,12 +1,9 @@ -import resolve from '@rollup/plugin-node-resolve'; import { createRequire } from 'node:module'; -import path from 'path'; import copy from 'rollup-plugin-copy'; -import dts from 'rollup-plugin-dts'; -import esbuild from 'rollup-plugin-esbuild'; -import { nodeExternals } from 'rollup-plugin-node-externals'; import svg from 'rollup-plugin-svg-import'; +import { cjsOutput, entryPoint, esmOutput, plugins, tsDeclarationOutput } from '../rollup.config.parts'; + const rq = createRequire(import.meta.url); const icons = rq('../../public/app/core/icons/cached.json'); const pkg = rq('./package.json'); @@ -15,51 +12,18 @@ const iconSrcPaths = icons.map((iconSubPath) => { return `../../public/img/icons/${iconSubPath}.svg`; }); -const legacyOutputDefaults = { - esModule: true, - interop: 'compat', -}; - export default [ { - input: 'src/index.ts', + input: entryPoint, plugins: [ - nodeExternals({ deps: true, packagePath: './package.json' }), + ...plugins, svg({ stringify: true }), - resolve(), copy({ targets: [{ src: iconSrcPaths, dest: './dist/public/' }], flatten: false, }), - esbuild({ - target: 'es2018', - tsconfig: 'tsconfig.build.json', - }), - ], - output: [ - { - format: 'cjs', - sourcemap: true, - dir: path.dirname(pkg.publishConfig.main), - ...legacyOutputDefaults, - }, - { - format: 'esm', - sourcemap: true, - dir: path.dirname(pkg.publishConfig.module), - preserveModules: true, - // @ts-expect-error (TS cannot assure that `process.env.PROJECT_CWD` is a string) - preserveModulesRoot: path.join(process.env.PROJECT_CWD, `packages/grafana-ui/src`), - ...legacyOutputDefaults, - }, ], + output: [cjsOutput(pkg), esmOutput(pkg, 'grafana-ui')], }, - { - input: './compiled/index.d.ts', - plugins: [dts()], - output: { - file: pkg.publishConfig.types, - format: 'es', - }, - }, + tsDeclarationOutput(pkg), ]; diff --git a/packages/rollup.config.parts.ts b/packages/rollup.config.parts.ts new file mode 100644 index 00000000000..ca805b07ed9 --- /dev/null +++ b/packages/rollup.config.parts.ts @@ -0,0 +1,58 @@ +// This file contains the common parts of the rollup configuration that are shared across multiple packages. +import nodeResolve from '@rollup/plugin-node-resolve'; +import { dirname, resolve } from 'node:path'; +import dts from 'rollup-plugin-dts'; +import esbuild from 'rollup-plugin-esbuild'; +import { nodeExternals } from 'rollup-plugin-node-externals'; + +// This is the path to the root of the grafana project +// Prefer PROJECT_CWD env var set by yarn berry +const projectCwd = process.env.PROJECT_CWD ?? '../../'; + +export const entryPoint = 'src/index.ts'; + +// Plugins that are shared across all rollup configurations. Their order can affect build output. +// Externalising and resolving modules should happen before transformation. +export const plugins = [ + nodeExternals({ deps: true, packagePath: './package.json' }), + nodeResolve(), + esbuild({ + target: 'es2018', + tsconfig: 'tsconfig.build.json', + }), +]; + +// Generates a rollup configuration for commonjs output. +export function cjsOutput(pkg) { + return { + format: 'cjs', + sourcemap: true, + dir: dirname(pkg.publishConfig.main), + esModule: true, + interop: 'compat', + }; +} + +// Generate a rollup configuration for es module output. +export function esmOutput(pkg, pkgName) { + return { + format: 'esm', + sourcemap: true, + dir: dirname(pkg.publishConfig.module), + preserveModules: true, + preserveModulesRoot: resolve(projectCwd, `packages/${pkgName}/src`), + }; +} + +// Generate a rollup configuration for rolling up typescript declaration files into a single file. +export function tsDeclarationOutput(pkg, overrides = {}) { + return { + input: './compiled/index.d.ts', + plugins: [dts()], + output: { + file: pkg.publishConfig.types, + format: 'es', + }, + ...overrides, + }; +}