spinjs
Version:
[](https://gitter.im/sysgears/spinjs?utm_source=badge&utm_medium=badge&utm_campaign=pr-badge&utm_content=badge) [ • 5.51 kB
text/typescript
import * as fs from 'fs';
import * as path from 'path';
import * as merge from 'webpack-merge';
import { Builders } from './Builder';
import { ConfigPlugin } from './ConfigPlugin';
import createRequire from './createRequire';
import EnhancedError from './EnhancedError';
import inferConfig from './inferConfig';
import Spin from './Spin';
import Stack from './Stack';
interface ReadConfigOptions {
filePath: string;
inferedConfig?: any;
builderOverrides?: any;
}
export default class ConfigReader {
private spin: Spin;
private plugins: ConfigPlugin[];
constructor(spin: Spin, plugins: ConfigPlugin[]) {
this.spin = spin;
this.plugins = plugins;
}
public readConfig(options: ReadConfigOptions): Builders {
const { filePath, inferedConfig, builderOverrides } = options;
if (fs.existsSync(filePath) && fs.statSync(filePath).isDirectory()) {
const dir = filePath;
const candidates = ['.spinrc.json', '.spinrc', '.spinrc.js', 'package.json'];
for (const fileName of candidates) {
const configPath = path.join(dir, fileName);
const derivedConfig = inferConfig(path.join(dir, 'package.json'));
try {
const builders = this.readConfig({ filePath: configPath, inferedConfig: derivedConfig, builderOverrides });
if (builders) {
return builders;
}
} catch (e) {
e.message = `while processing ${configPath}: ${e.message}`;
throw e;
}
}
} else {
const derivedConfig = inferedConfig || inferConfig(path.join(path.dirname(filePath), 'package.json'));
let configObject: any;
if (fs.existsSync(filePath)) {
process.chdir(path.dirname(filePath));
try {
const extname = path.extname(filePath);
if (['.json', ''].indexOf(extname) >= 0) {
try {
configObject = JSON.parse(fs.readFileSync(filePath).toString());
if (path.basename(filePath) === 'package.json') {
configObject = configObject.spin;
}
} catch (e) {
throw new EnhancedError(`Error parsing ${path.resolve(filePath)}`, e);
}
} else {
const exports = require(path.resolve(filePath));
configObject = exports instanceof Function ? exports(this.spin) : exports;
}
} finally {
process.chdir(this.spin.cwd);
}
}
return typeof configObject === 'undefined' && !fs.existsSync(filePath)
? undefined
: this._createBuilders(
filePath,
configObject && configObject.builders ? configObject : this.spin.merge(derivedConfig, configObject),
builderOverrides
);
}
}
private _createBuilders(filePath: string, config: any, builderOverrides: any): Builders {
if (typeof config === 'string' || (typeof config === 'object' && config.constructor === Array)) {
config = {
builders: {
app: config
}
};
}
config.options = config.options || {};
const relativePath = path.relative(this.spin.cwd, path.dirname(filePath));
const builders: Builders = {};
const { stack, plugins, ...options } = config.options;
for (const name of Object.keys(config.builders || {})) {
const builderVal = config.builders[name];
const builder: any = this.spin.mergeWithInStrategy(
typeof builderVal === 'object' && builderVal.constructor !== Array ? { ...builderVal } : { stack: builderVal },
builderOverrides
);
builder.name = name;
builder.require = createRequire(path.resolve(relativePath));
builder.stack = new Stack(
builder.name,
config.options.stack || [],
typeof builder === 'object' ? builder.stack : builder
);
builder.plugins = (config.plugins || []).concat(builder.plugins || []);
builder.roles = builder.roles || ['build', 'watch'];
const merged = merge(options, builder);
for (const key of Object.keys(merged)) {
builder[key] = merged[key];
}
const builderId = `${relativePath}[${builder.name}]`;
builder.id = builderId;
builder.configPath = filePath;
builders[builderId] = builder;
// TODO: remove backendBuildDir, frontendBuildDir in 0.5.x
builder.buildDir = builder.backendBuildDir || builder.frontendBuildDir ? undefined : builder.buildDir || 'build';
builder.nodeDebugger = typeof builder.nodeDebugger !== 'undefined' ? builder.nodeDebugger : true;
builder.webpackDll = typeof builder.webpackDll !== 'undefined' ? builder.webpackDll : true;
builder.sourceMap = typeof builder.sourceMap !== 'undefined' ? builder.sourceMap : true;
builder.minify = typeof builder.minify !== 'undefined' ? builder.minify : true;
builder.cache =
typeof builder.cache === 'string' && builder.cache !== 'auto'
? builder.cache
: typeof builder.cache !== 'undefined'
? builder.cache
: 'auto';
if (builder.derived) {
builder.dllBuildDir =
builder.dllBuildDir ||
path.join(typeof builder.cache === 'string' && builder.cache !== 'auto' ? builder.cache : '.cache', 'dll');
} else {
builder.dllBuildDir = builder.dllBuildDir || 'build/dll';
}
builder.plugins = this.plugins.concat((builder.plugins || []).map(pluginName => new (require(pluginName))()));
}
return builders;
}
}