rollup.base.mjs (81 lines of code) (raw):
import { nodeResolve } from '@rollup/plugin-node-resolve';
import commonjs from '@rollup/plugin-commonjs';
import swc from '@rollup/plugin-swc';
import { readFileSync } from 'node:fs';
import { relative, resolve } from 'node:path';
const pkg = JSON.parse(readFileSync('./package.json', 'utf-8'));
const cwd = process.cwd();
const deps = new Set([...Object.keys(pkg.dependencies || {}), ...Object.keys(pkg.peerDependencies || {})]);
export default {
input: 'build/esm/index.js',
external: (id, parent) => {
// this function decides if a module should be bundled or not (external)
// a module is not bundled if it points to one of our dependencies
// if it's not a dependency but still resolves outside the build/esm dir, an error is thrown
const path = normalizePath(id, parent);
const depId = npmPackage(id);
if (deps.has(depId)) {
console.log('exclude:', path);
return true;
}
if (!path.startsWith('build/esm/')) {
// this will throw if we accidentally import something that isn't local and wasn't listed among dependencies
throw new Error(`Attempt to bundle external dependency ${path} for import ${id}. Are we missing a dependency?`);
}
console.log('include:', path);
return false;
},
output: [
{
file: 'dist/index.esm.js',
format: 'es',
sourcemap: true,
generatedCode: 'es2015',
},
{
file: 'dist/index.cjs.js',
format: 'cjs',
sourcemap: true,
generatedCode: 'es2015',
},
],
plugins: [
nodeResolve(),
commonjs(),
swc({
swc: {
jsc: {
target: 'es2015',
},
},
}),
],
};
/**
* Return the path relative to cwd for a give import. Npm package imports will be returned as if they were directly in cwd.
*
* @param id the imported path
* @param parent absolute path of the file containing the import, or undefined if it's the entry point
* @returns path relative to cwd
*/
function normalizePath(id, parent = '') {
const absolute = id.startsWith('.') ? resolve(parent, id) : id;
return relative(cwd, absolute);
}
/**
* Return the npm package name of an import, if applicable.
*
* @param id an import path
* @returns the npm package name if id is determined to point to an npm package, '' otherwise.
*/
function npmPackage(id) {
// relative or absolute ids are not npm packages
if (id.startsWith('.') || id.startsWith('/')) return '';
// we're only ever interested in the first two parts the id (the second is needed if the first part specifies a scope)
const parts = id.split('/', 2);
if (parts[0].startsWith('@')) {
// it's a scoped package, so it will include one backslash
return parts.join('/');
}
return parts[0];
}