Skip to content

Commit

Permalink
Automatically discover .mjs and .cjs configs
Browse files Browse the repository at this point in the history
  • Loading branch information
lukastaegert committed Mar 23, 2020
1 parent 14716ad commit 7908222
Show file tree
Hide file tree
Showing 14 changed files with 100 additions and 67 deletions.
41 changes: 41 additions & 0 deletions cli/run/getConfigPath.ts
Original file line number Diff line number Diff line change
@@ -0,0 +1,41 @@
import { readdirSync, realpathSync } from 'fs';
import * as path from 'path';
import relative from 'require-relative';
import { handleError } from '../logging';

const DEFAULT_CONFIG_BASE = 'rollup.config';

export function getConfigPath(commandConfig: any): string {
const cwd = process.cwd();
if (commandConfig === true) {
return path.join(cwd, findConfigFileNameInCwd());
}
if (commandConfig.slice(0, 5) === 'node:') {
const pkgName = commandConfig.slice(5);
try {
return relative.resolve(`rollup-config-${pkgName}`, cwd);
} catch (err) {
try {
return relative.resolve(pkgName, cwd);
} catch (err) {
if (err.code === 'MODULE_NOT_FOUND') {
handleError({
code: 'MISSING_EXTERNAL_CONFIG',
message: `Could not resolve config file "${commandConfig}"`
});
}
throw err;
}
}
}
return realpathSync(commandConfig);
}

function findConfigFileNameInCwd(): string {
const filesInWorkingDir = new Set(readdirSync(process.cwd()));
for (const extension of ['mjs', 'cjs']) {
const fileName = `${DEFAULT_CONFIG_BASE}.${extension}`;
if (filesInWorkingDir.has(fileName)) return fileName;
}
return `${DEFAULT_CONFIG_BASE}.js`;
}
80 changes: 27 additions & 53 deletions cli/run/index.ts
Original file line number Diff line number Diff line change
@@ -1,13 +1,12 @@
import { realpathSync } from 'fs';
import * as path from 'path';
import relative from 'require-relative';
import { InputOptions } from '../../src/rollup/types';
import { mergeOptions } from '../../src/utils/mergeOptions';
import { GenericConfigObject } from '../../src/utils/parseOptions';
import { getAliasName } from '../../src/utils/relativeId';
import { handleError } from '../logging';
import batchWarnings from './batchWarnings';
import build from './build';
import { getConfigPath } from './getConfigPath';
import loadConfigFile from './loadConfigFile';
import { stdinName, stdinPlugin } from './stdin';
import watch from './watch';
Expand Down Expand Up @@ -60,47 +59,21 @@ export default function runRollup(command: any) {
});
}

let configFile = command.config === true ? 'rollup.config.js' : command.config;

if (configFile) {
if (configFile.slice(0, 5) === 'node:') {
const pkgName = configFile.slice(5);
try {
configFile = relative.resolve(`rollup-config-${pkgName}`, process.cwd());
} catch (err) {
try {
configFile = relative.resolve(pkgName, process.cwd());
} catch (err) {
if (err.code === 'MODULE_NOT_FOUND') {
handleError({
code: 'MISSING_EXTERNAL_CONFIG',
message: `Could not resolve config file ${configFile}`
});
}

throw err;
}
}
} else {
// find real path of config so it matches what Node provides to callbacks in require.extensions
configFile = realpathSync(configFile);
}

if (command.config) {
const configFile = getConfigPath(command.config);
if (command.watch) process.env.ROLLUP_WATCH = 'true';

return loadConfigFile(configFile, command)
.then(configs => execute(configFile, configs, command))
.catch(handleError);
} else {
if (!command.input && (command.stdin || !process.stdin.isTTY)) {
command.input = stdinName;
}
return execute(configFile, [{ input: [] }], command);
}
if (!command.input && (command.stdin || !process.stdin.isTTY)) {
command.input = stdinName;
}
return execute(null, [{ input: [] }], command);
}

async function execute(
configFile: string,
configFile: string | null,
configs: GenericConfigObject[],
command: any
): Promise<void> {
Expand All @@ -110,27 +83,11 @@ async function execute(
for (const config of configs) {
const warnings = batchWarnings();
try {
const { inputOptions, outputOptions } = mergeOptions(config, command,
warnings.add);
const { inputOptions, outputOptions } = mergeOptions(config, command, warnings.add);
if (command.stdin !== false) {
inputOptions.plugins!.push(stdinPlugin());
}
if (command.plugin) {
const plugins = Array.isArray(command.plugin) ? command.plugin : [command.plugin];
for (const plugin of plugins) {
if (/[={}]/.test(plugin)) {
// -p plugin=value
// -p "{transform(c,i){...}}"
loadAndRegisterPlugin(inputOptions, plugin);
} else {
// split out plugins joined by commas
// -p node-resolve,commonjs,buble
plugin
.split(',')
.forEach((plugin: string) => loadAndRegisterPlugin(inputOptions, plugin));
}
}
}
addCommandPluginsToInputOptions(inputOptions, command.plugin);
await build(inputOptions, outputOptions, warnings, command.silent);
} catch (err) {
warnings.flush();
Expand All @@ -140,6 +97,23 @@ async function execute(
}
}

function addCommandPluginsToInputOptions(inputOptions: InputOptions, commandPlugin: unknown) {
if (commandPlugin) {
const plugins = Array.isArray(commandPlugin) ? commandPlugin : [commandPlugin];
for (const plugin of plugins) {
if (/[={}]/.test(plugin)) {
// -p plugin=value
// -p "{transform(c,i){...}}"
loadAndRegisterPlugin(inputOptions, plugin);
} else {
// split out plugins joined by commas
// -p node-resolve,commonjs,buble
plugin.split(',').forEach((plugin: string) => loadAndRegisterPlugin(inputOptions, plugin));
}
}
}
}

function loadAndRegisterPlugin(inputOptions: InputOptions, pluginText: string) {
let plugin: any = null;
let pluginArg: any = undefined;
Expand Down
1 change: 0 additions & 1 deletion cli/run/loadConfigFile.ts
Original file line number Diff line number Diff line change
Expand Up @@ -45,7 +45,6 @@ async function getDefaultFromTranspiledConfigFile(
onwarn: warnings.add,
treeshake: false
});
// TODO Lukas test warnings are displayed
if (!silent && warnings.count > 0) {
stderr(color.bold(`loaded ${relativeId(fileName)} with warnings`));
warnings.flush();
Expand Down
2 changes: 1 addition & 1 deletion cli/run/watch.ts
Original file line number Diff line number Diff line change
Expand Up @@ -15,7 +15,7 @@ import { getResetScreen } from './resetScreen';
import { printTimings } from './timings';

export default function watch(
configFile: string,
configFile: string | null,
configs: GenericConfigObject[],
command: any,
silent = false
Expand Down
3 changes: 1 addition & 2 deletions test/cli/samples/config-cjs-dirname/_config.js
Original file line number Diff line number Diff line change
@@ -1,5 +1,4 @@
module.exports = {
description: 'does not transpile cjs configs and provides correct __dirname',
// TODO Lukas add auto-discovery
command: 'rollup --config rollup.config.cjs'
command: 'rollup -c'
};
4 changes: 2 additions & 2 deletions test/cli/samples/config-cjs-dirname/_expected.js
Original file line number Diff line number Diff line change
@@ -1,5 +1,5 @@
console.log('nested');
console.log('');
console.log('nested/plugin.js');
console.log('plugin.js');
var main = 42;

export default main;
2 changes: 1 addition & 1 deletion test/cli/samples/config-cjs-dirname/nested/plugin.js
Original file line number Diff line number Diff line change
Expand Up @@ -2,6 +2,6 @@ const path = require('path');

module.exports = () => ({
transform(code) {
return `console.log('${path.relative(process.cwd(), __dirname)}');\n${code}`;
return `console.log('${path.relative(process.cwd(), __filename)}');\n${code}`;
}
});
2 changes: 1 addition & 1 deletion test/cli/samples/config-cjs-dirname/plugin.js
Original file line number Diff line number Diff line change
Expand Up @@ -2,6 +2,6 @@ const path = require('path');

module.exports = () => ({
transform(code) {
return `console.log('${path.relative(process.cwd(), __dirname)}');\n${code}`;
return `console.log('${path.relative(process.cwd(), __filename)}');\n${code}`;
}
});
3 changes: 1 addition & 2 deletions test/cli/samples/config-mjs-plugins/_config.js
Original file line number Diff line number Diff line change
@@ -1,6 +1,5 @@
module.exports = {
description: 'supports native esm as well as CJS plugins when using .mjs in Node 13+',
minNodeVersion: 13,
// TODO Lukas add auto-discovery
command: 'rollup --config rollup.config.mjs'
command: 'rollup -c'
};
2 changes: 2 additions & 0 deletions test/cli/samples/config-mjs-plugins/_expected.js
Original file line number Diff line number Diff line change
@@ -1,6 +1,8 @@
#!/usr/bin/env node
'use strict';

console.log('nested/plugin.mjs');
console.log('plugin.mjs');
var main = 42;

module.exports = main;
8 changes: 8 additions & 0 deletions test/cli/samples/config-mjs-plugins/nested/plugin.mjs
Original file line number Diff line number Diff line change
@@ -0,0 +1,8 @@
import { relative } from 'path';
import { fileURLToPath } from 'url';

export default () => ({
transform(code) {
return `console.log('${relative(process.cwd(), fileURLToPath(import.meta.url))}');\n${code}`;
}
});
8 changes: 8 additions & 0 deletions test/cli/samples/config-mjs-plugins/plugin.mjs
Original file line number Diff line number Diff line change
@@ -0,0 +1,8 @@
import { relative } from 'path';
import { fileURLToPath } from 'url';

export default () => ({
transform(code) {
return `console.log('${relative(process.cwd(), fileURLToPath(import.meta.url))}');\n${code}`;
}
});
8 changes: 5 additions & 3 deletions test/cli/samples/config-mjs-plugins/rollup.config.mjs
Original file line number Diff line number Diff line change
@@ -1,10 +1,12 @@
// This is an ESM plugin
// And this is CJS
// This is a CJS plugin
import replace from '@rollup/plugin-replace/dist/rollup-plugin-replace.cjs.js';
// This is an ESM plugin
import { shebang } from 'rollup-plugin-thatworks';
import nestedPlugin from './nested/plugin.mjs';
import plugin from './plugin.mjs';

export default {
input: 'main.js',
output: { format: 'cjs' },
plugins: [shebang(), replace({ ANSWER: 42 })]
plugins: [shebang(), replace({ ANSWER: 42 }), plugin(), nestedPlugin()]
};
3 changes: 2 additions & 1 deletion test/cli/samples/node-config-not-found/_config.js
Original file line number Diff line number Diff line change
Expand Up @@ -5,6 +5,7 @@ module.exports = {
command: 'rollup --config node:baz',
error: () => true,
stderr(stderr) {
assertStderrIncludes(stderr, '[!] Could not resolve config file node:baz');
// TODO Lukas is this documented?
assertStderrIncludes(stderr, '[!] Could not resolve config file "node:baz"');
}
};

0 comments on commit 7908222

Please sign in to comment.