UNPKG

rollup-plugin-node-externals

Version:

Automatically declare NodeJS built-in modules and npm dependencies as 'external' in Rollup config

116 lines 5.08 kB
import path from 'node:path'; import fs from 'node:fs/promises'; import { createRequire, isBuiltin } from 'node:module'; const { name, version } = createRequire(import.meta.url)('#package.json'); const workspaceRootFiles = [ 'pnpm-workspace.yaml', 'lerna.json', ]; const defaults = { builtins: true, builtinsPrefix: 'add', packagePath: [], deps: true, devDeps: false, peerDeps: true, optDeps: true, include: [], exclude: [] }; const isString = (str) => typeof str === 'string' && str.length > 0; function nodeExternals(options = {}) { const config = { ...defaults, ...options }; let include = [], exclude = []; const isIncluded = (id) => include.length > 0 && include.some(rx => rx.test(id)), isExcluded = (id) => exclude.length > 0 && exclude.some(rx => rx.test(id)); return { name: name.replace(/^rollup-plugin-/, ''), version, enforce: 'pre', async buildStart() { [include, exclude] = ['include', 'exclude'].map(option => [] .concat(config[option]) .reduce((result, entry, index) => { if (entry instanceof RegExp) result.push(entry); else if (isString(entry)) result.push(new RegExp('^' + entry.replace(/[.*+?^${}()|[\]\\]/g, '\\$&') + '$')); else if (entry) this.warn(`Ignoring wrong entry type #${index} in '${option}' option: ${JSON.stringify(entry)}`); return result; }, [])); const packagePaths = [] .concat(config.packagePath) .filter(isString) .map(packagePath => path.resolve(packagePath)); if (packagePaths.length === 0) { search: for (let current = process.cwd(), previous = undefined; previous !== current; previous = current, current = path.dirname(current)) { let name = path.join(current, 'package.json'); let stat = await fs.stat(name).catch(() => null); if (stat?.isFile()) packagePaths.push(name); name = path.join(current, '.git'); stat = await fs.stat(name).catch(() => null); if (stat?.isDirectory()) break; for (const file of workspaceRootFiles) { name = path.join(current, file); stat = await fs.stat(name).catch(() => null); if (stat?.isFile()) break search; } } } const dependencies = {}; for (const packagePath of packagePaths) { const buffer = await fs.readFile(packagePath).catch((err) => err); if (buffer instanceof Error) { return this.error({ message: `Cannot read file ${packagePath}, error: ${buffer.code}.`, stack: undefined }); } try { const pkg = JSON.parse(buffer.toString()); Object.assign(dependencies, config.deps ? pkg.dependencies : undefined, config.devDeps ? pkg.devDependencies : undefined, config.peerDeps ? pkg.peerDependencies : undefined, config.optDeps ? pkg.optionalDependencies : undefined); this.addWatchFile(packagePath); if (Array.isArray(pkg.workspaces)) break; } catch { this.error({ message: `File ${JSON.stringify(packagePath)} does not look like a valid package.json file.`, stack: undefined }); } } const names = Object.keys(dependencies); if (names.length > 0) include.push(new RegExp('^(?:' + names.join('|') + ')(?:/.+)?$')); }, resolveId(specifier, _, { isEntry }) { if (isEntry || /^(?:\0|\.{1,2}\/)/.test(specifier) || path.isAbsolute(specifier)) { return null; } if (isBuiltin(specifier)) { const stripped = specifier.replace(/^node:/, ''); return { id: config.builtinsPrefix === 'ignore' ? specifier : config.builtinsPrefix === 'add' || !isBuiltin(stripped) ? 'node:' + stripped : stripped, external: (config.builtins || isIncluded(specifier)) && !isExcluded(specifier), moduleSideEffects: false }; } return isIncluded(specifier) && !isExcluded(specifier) ? false : null; } }; } export default nodeExternals; export { nodeExternals }; //# sourceMappingURL=index.js.map