@airbnb/nimbus
Version:
Centralized CLI for JavaScript and TypeScript dev tools.
179 lines (178 loc) • 7.75 kB
JavaScript
;
/* eslint-disable no-restricted-syntax, no-await-in-loop */
var __importDefault = (this && this.__importDefault) || function (mod) {
return (mod && mod.__esModule) ? mod : { "default": mod };
};
Object.defineProperty(exports, "__esModule", { value: true });
const fs_1 = __importDefault(require("fs"));
const chalk_1 = __importDefault(require("chalk"));
const execa_1 = __importDefault(require("execa"));
const edit_json_file_1 = __importDefault(require("edit-json-file"));
const enquirer_1 = require("enquirer");
const core_1 = require("@beemo/core");
const constants_1 = require("../constants");
const installDeps_1 = __importDefault(require("../helpers/installDeps"));
const removeDeps_1 = __importDefault(require("../helpers/removeDeps"));
const pkgPath = core_1.Path.resolve('package.json').path();
function writeJsFile(configPath, config) {
fs_1.default.writeFileSync(configPath, `module.exports = ${JSON.stringify(config, null, 2)}`, 'utf8');
}
async function copyAndInstallDepsFromModule(moduleName, isYarn, isMonorepo) {
const pkg = require(`${moduleName}/package.json`);
const deps = Object.keys(pkg.dependencies || {}).filter((dep) => !dep.includes('@beemo') && !dep.includes('@airbnb/nimbus'));
await installDeps_1.default(deps, isYarn, isMonorepo);
await removeDeps_1.default([moduleName], isYarn, isMonorepo);
}
function escapeRegExp(string) {
return string.replace(/[.*+?^${}()|[\]\\]/g, '\\$&');
}
function migrateDotfiles() {
const toRemove = [
'# Configs',
'# Configs (provided by Nimbus)',
'.babelrc',
'.eslintignore',
'.eslintrc.js',
'.flowconfig',
'.prettierignore',
'babel.config.js',
'jest.config.js',
'prettier.config.js',
'tsconfig.json',
'tsconfig.eslint.json',
'tsconfig.options.json',
'*.tsbuildinfo',
];
try {
const dotPath = core_1.Path.resolve('.gitignore').path();
let data = fs_1.default.readFileSync(dotPath, 'utf8');
toRemove.forEach((value) => {
data = data.replace(new RegExp(`${escapeRegExp(value)}\n?`, 'g'), '');
});
fs_1.default.writeFileSync(dotPath, data.trim(), 'utf8');
}
catch (error) {
// Ignore
}
}
function migratePackageScripts(nimbus) {
var _a, _b, _c;
const pkg = edit_json_file_1.default(pkgPath);
const scripts = (_a = pkg.get('scripts')) !== null && _a !== void 0 ? _a : {};
const srcFolder = nimbus.settings.srcFolder || 'src';
const testFolder = nimbus.settings.testFolder || 'test';
if ((_b = scripts.prepare) === null || _b === void 0 ? void 0 : _b.includes('create-config')) {
delete scripts.prepare;
}
if ((_c = scripts.release) === null || _c === void 0 ? void 0 : _c.includes('auto-release')) {
delete scripts.release;
}
Object.keys(scripts).forEach((key) => {
const value = scripts[key];
const esm = value.includes('--esm');
scripts[key] = value
.replace('nimbus babel', `${esm ? 'ESM=true ' : ''}babel ./${srcFolder} --out-dir ./${esm ? 'esm' : 'lib'}`)
.replace('--esm', '')
.replace('nimbus eslint', `eslint --color --report-unused-disable-directives ./${srcFolder} ./${testFolder}`)
.replace('nimbus jest', 'jest --colors')
.replace('--coverage', '--coverage --logHeapUsage --detectOpenHandles')
.replace('nimbus prettier', `prettier --write ./${srcFolder} ./${testFolder}`)
.replace('nimbus typescript', 'tsc')
.replace('nimbus webpack', 'webpack --colors --progress --bail')
.replace('nimbus-webpack-server', 'webpack-dev-server')
.trim();
});
pkg.set('scripts', scripts);
pkg.save();
}
function migrateEslint() {
const configPath = core_1.Path.resolve('.eslintrc.js').path();
const { extends: extendPaths, ...rootConfig } = require(configPath);
let config = { extends: [] };
extendPaths.forEach((extendPath) => {
if (extendPath.startsWith('.')) {
config = {
...config,
...require(extendPath),
};
}
else {
config.extends.push(extendPath);
}
});
config = {
...config,
...rootConfig,
};
delete config.parserOptions;
writeJsFile(configPath, config);
}
function migrateJest() {
const configPath = core_1.Path.resolve('jest.config.js').path();
const config = require(configPath);
delete config.moduleNameMapper;
delete config.setupFiles;
delete config.setupFilesAfterEnv;
delete config.testEnvironment;
console.log(`${chalk_1.default.gray('[jest]')} ${chalk_1.default.yellow('Jest config has been migrated but the following settings were removed: moduleNameMapper, setupFiles, setupFilesAfterEnv, testEnvironment')}`);
console.log(`${chalk_1.default.gray('[jest]')} ${chalk_1.default.yellow('This included custom serializers, transformers, mocks, setup files, and more provided by Nimbus. These will need to be manually configured now.')}`);
writeJsFile(configPath, config);
}
function migrateWebpack() {
const configPath = core_1.Path.resolve('webpack.config.js').path();
const url = 'https://github.com/airbnb/nimbus/blob/master/packages/config-webpack/index.js';
console.log(`${chalk_1.default.gray('[webpack]')} ${chalk_1.default.yellow('Webpack config could not be migrated.')}`);
console.log(`${chalk_1.default.gray('[webpack]')} ${chalk_1.default.yellow(`Please copy portions of this config manually: ${url}`)}`);
writeJsFile(configPath, {});
}
async function eject() {
console.log(constants_1.BANNER);
console.log(`${chalk_1.default.cyan('[1/5]')} Ejecting Nimbus`);
const nimbus = edit_json_file_1.default(pkgPath).get('nimbus');
if (!nimbus) {
throw new Error("Project isn't Nimbus enabled.");
}
const response = await enquirer_1.prompt([
{
type: 'confirm',
name: 'monorepo',
message: 'Is this a monorepo?',
},
{
type: 'confirm',
name: 'yarn',
message: 'Are you using Yarn?',
},
]);
await execa_1.default('nimbus', ['create-config', '--silent'], { preferLocal: true });
console.log(`${chalk_1.default.cyan('[2/5]')} Updating package scripts`);
migratePackageScripts(nimbus);
console.log(`${chalk_1.default.cyan('[3/5]')} Migrating drivers`);
for (const driver of nimbus.drivers) {
console.log(`${chalk_1.default.gray(`[${driver}]`)} Migrating config`);
if (driver === 'eslint') {
migrateEslint();
}
else if (driver === 'jest') {
migrateJest();
}
else if (driver === 'webpack') {
migrateWebpack();
}
console.log(`${chalk_1.default.gray(`[${driver}]`)} Updating dependencies`);
await copyAndInstallDepsFromModule(`@airbnb/config-${driver}`, response.yarn, response.monorepo);
// Remove the driver from the package in case the eject script fails later on.
// This allows us to pickup where we left off.
const pkg = edit_json_file_1.default(pkgPath);
pkg.set('nimbus.drivers', pkg.get('nimbus.drivers').filter((d) => d !== driver));
pkg.save();
}
console.log(`${chalk_1.default.cyan('[4/5]')} Removing config`);
await removeDeps_1.default(['@airbnb/nimbus'], response.yarn, response.monorepo);
const pkg = edit_json_file_1.default(pkgPath);
pkg.unset('nimbus');
pkg.save();
console.log(`${chalk_1.default.cyan('[5/5]')} Updating dotfiles`);
migrateDotfiles();
}
exports.eject = eject;