refactor: build config
This commit is contained in:
parent
f8d07874ae
commit
af6a70678b
4
TODO.md
4
TODO.md
|
@ -15,8 +15,8 @@
|
|||
- [x] `flecks.expandedFlecks()` should use `platforms`
|
||||
- [ ] config validation
|
||||
- [ ] hints for hook types
|
||||
- [ ] localConfig discovered by hook
|
||||
- [ ] renamed to 'build/config'?
|
||||
- [x] localConfig discovered by hook
|
||||
- [x] renamed to 'build/config'?
|
||||
- [ ] automatically generated list of build config
|
||||
- [ ] static documentation site generator
|
||||
- [ ] autogenerated config dox page
|
||||
|
|
|
@ -17,9 +17,9 @@ module.exports = require('../src/bootstrap/fleck.neutrinorc');
|
|||
module.exports.use.push((neutrino) => {
|
||||
['eslintrc', 'eslint.defaults'].forEach((filename) => {
|
||||
neutrino.config
|
||||
.entry(`build/.${filename}`)
|
||||
.entry(`server/build/.${filename}`)
|
||||
.clear()
|
||||
.add(`./src/build/${filename}`);
|
||||
.add(`./src/server/build/${filename}`);
|
||||
})
|
||||
});
|
||||
|
||||
|
@ -44,7 +44,7 @@ module.exports.use.unshift(
|
|||
airbnb({
|
||||
eslint: {
|
||||
baseConfig: {
|
||||
...require('../src/build/eslint.defaults'),
|
||||
...require('../src/server/build/eslint.defaults'),
|
||||
env: {
|
||||
mocha: true,
|
||||
},
|
||||
|
|
|
@ -62,20 +62,16 @@ Have fun!
|
|||
|
||||
## Resolution order 🤔
|
||||
|
||||
The flecks server provides an interface (`flecks.localConfig()`) for gathering configuration files
|
||||
The flecks server provides an interface (`flecks.buildConfig()`) for gathering configuration files
|
||||
from the `build` directory. The resolution order is determined by a few variables:
|
||||
|
||||
- `filename` specifies the name of the configuration file, e.g. `babel.config.js`.
|
||||
- `filename` specifies the name of the configuration file, e.g. `server.neutrinorc.js`.
|
||||
|
||||
- `general` specifies a general variation of the given configuration. `@flecks/server` looks for
|
||||
an overridden `server.neutrinorc.js` when building, however `general` is set to `.neutrinorc.js`,
|
||||
so it will also accept overrides of that more general configuration file.
|
||||
- `general` specifies a general variation of the given configuration. The general form of `server.neutrinorc.js` is `.neutrinorc.js`.
|
||||
|
||||
- `root` specifies an alternative location to search. Defaults to `FLECKS_CORE_ROOT`.
|
||||
|
||||
- `fleck` specifies the fleck owning the configuration. `@flecks/core` owns `babel.config.js`,
|
||||
`@flecks/server` owns `server.neutrinorc.js`, etc. This only really matters if you are writing a
|
||||
fleck that owns its configuration.
|
||||
- `fleck` specifies the fleck owning the configuration. `@flecks/server` owns `server.neutrinorc.js`.
|
||||
|
||||
Given these considerations, and supposing we had the above variables set like:
|
||||
|
||||
|
@ -86,7 +82,7 @@ const root = '/foo/bar/baz';
|
|||
const fleck = '@flecks/server';
|
||||
```
|
||||
|
||||
We would then expect flecks to search using the following resolution order:
|
||||
Flecks will then search the following paths top-down until it finds the build configuration:
|
||||
|
||||
- `/foo/bar/baz/build/server.neutrinorc.js`
|
||||
- `/foo/bar/baz/build/.neutrinorc.js`
|
||||
|
|
|
@ -26,6 +26,14 @@ export default {
|
|||
}
|
||||
},
|
||||
|
||||
/**
|
||||
* Register build configuration.
|
||||
*/
|
||||
'@flecks/core.build.config': () => [
|
||||
'.myrc.js',
|
||||
['mygeneralrc.js', {specifier: (specific) => `${specific}.mygeneralrc.js`}],
|
||||
],
|
||||
|
||||
/**
|
||||
* Define CLI commands.
|
||||
*/
|
||||
|
|
|
@ -24,14 +24,6 @@
|
|||
},
|
||||
"files": [
|
||||
"build",
|
||||
"build/.eslint.defaults.js",
|
||||
"build/.eslint.defaults.js.map",
|
||||
"build/.eslintrc.js",
|
||||
"build/.eslintrc.js.map",
|
||||
"build/babel.config.js",
|
||||
"build/babel.config.js.map",
|
||||
"build/webpack.config.js",
|
||||
"build/webpack.config.js.map",
|
||||
"cli.js",
|
||||
"cli.js.map",
|
||||
"empty.js",
|
||||
|
@ -40,6 +32,14 @@
|
|||
"index.js.map",
|
||||
"server.js",
|
||||
"server.js.map",
|
||||
"server/build/.eslint.defaults.js",
|
||||
"server/build/.eslint.defaults.js.map",
|
||||
"server/build/.eslintrc.js",
|
||||
"server/build/.eslintrc.js.map",
|
||||
"server/build/babel.config.js",
|
||||
"server/build/babel.config.js.map",
|
||||
"server/build/webpack.config.js",
|
||||
"server/build/webpack.config.js.map",
|
||||
"src",
|
||||
"start.js",
|
||||
"start.js.map",
|
||||
|
|
|
@ -1,9 +1,9 @@
|
|||
const neutrino = require('neutrino');
|
||||
|
||||
const R = require('../bootstrap/require');
|
||||
const {targetNeutrino} = require('../server/commands');
|
||||
const D = require('../debug');
|
||||
const {default: Flecks} = require('../server/flecks');
|
||||
const R = require('../../bootstrap/require');
|
||||
const D = require('../../debug');
|
||||
const {targetNeutrino} = require('../commands');
|
||||
const {default: Flecks} = require('../flecks');
|
||||
|
||||
const debug = D('@flecks/core/.eslintrc.js');
|
||||
|
|
@ -14,9 +14,9 @@ import flatten from 'lodash.flatten';
|
|||
import intersection from 'lodash.intersection';
|
||||
import neutrino from 'neutrino';
|
||||
|
||||
import {targetNeutrino} from '../server/commands';
|
||||
import Flecks from '../server/flecks';
|
||||
import D from '../debug';
|
||||
import D from '../../debug';
|
||||
import {targetNeutrino} from '../commands';
|
||||
import Flecks from '../flecks';
|
||||
|
||||
const debug = D('@flecks/core/build/webpack.config.js');
|
||||
|
|
@ -50,10 +50,15 @@ export const targetNeutrinos = (flecks) => {
|
|||
const [fleck, targets] = entries[i];
|
||||
targets
|
||||
.forEach((target) => {
|
||||
targetNeutrinos[targetNeutrino(target)] = flecks.localConfig(
|
||||
`${target}.neutrinorc.js`,
|
||||
fleck,
|
||||
{general: '.neutrinorc.js'},
|
||||
targetNeutrinos[targetNeutrino(target)] = flecks.resolveBuildConfig(
|
||||
[
|
||||
FLECKS_CORE_ROOT,
|
||||
flecks.resolvePath(fleck),
|
||||
],
|
||||
[
|
||||
`${target}.neutrinorc.js`,
|
||||
'.neutrinorc.js',
|
||||
],
|
||||
);
|
||||
});
|
||||
}
|
||||
|
@ -107,7 +112,7 @@ export default (program, flecks) => {
|
|||
verbose,
|
||||
} = opts;
|
||||
debug('Building...', opts);
|
||||
const webpackConfig = flecks.localConfig('webpack.config.js', '@flecks/core');
|
||||
const webpackConfig = flecks.buildConfig('webpack.config.js');
|
||||
const cmd = [
|
||||
'npx', 'webpack',
|
||||
'--colors',
|
||||
|
@ -144,11 +149,7 @@ export default (program, flecks) => {
|
|||
process.env.FLECKS_CORE_BUILD_TARGET = target;
|
||||
const cmd = [
|
||||
'npx', 'eslint',
|
||||
'--config', flecks.localConfig(
|
||||
`${target}.eslintrc.js`,
|
||||
'@flecks/core',
|
||||
{general: '.eslintrc.js'},
|
||||
),
|
||||
'--config', flecks.buildConfig('.eslintrc.js', target),
|
||||
'--format', 'codeframe',
|
||||
'--ext', 'js',
|
||||
'.',
|
||||
|
|
|
@ -45,7 +45,7 @@ export default class ServerFlecks extends Flecks {
|
|||
Object.keys(this.flecks)
|
||||
.sort((l, r) => (l < r ? 1 : -1))
|
||||
.forEach((fleck) => {
|
||||
const prefix = `FLECKS_ENV_${this.constructor.environmentalize(fleck).toUpperCase()}`;
|
||||
const prefix = `FLECKS_ENV_${this.constructor.environmentalize(fleck)}`;
|
||||
keys
|
||||
.filter((key) => key.startsWith(`${prefix}_`) && -1 === seen.indexOf(key))
|
||||
.map((key) => {
|
||||
|
@ -66,6 +66,22 @@ export default class ServerFlecks extends Flecks {
|
|||
}
|
||||
});
|
||||
});
|
||||
this.buildConfigs = Object.fromEntries(
|
||||
Object.entries(this.invoke('@flecks/core.build.config'))
|
||||
.map(([fleck, configs]) => (
|
||||
configs.map((config) => {
|
||||
const defaults = {
|
||||
fleck,
|
||||
root: FLECKS_CORE_ROOT,
|
||||
};
|
||||
if (Array.isArray(config)) {
|
||||
return [config[0], {...defaults, ...config[1]}];
|
||||
}
|
||||
return [config, defaults];
|
||||
})
|
||||
))
|
||||
.flat(),
|
||||
);
|
||||
this.resolver = resolver;
|
||||
this.rcs = rcs;
|
||||
}
|
||||
|
@ -263,11 +279,16 @@ export default class ServerFlecks extends Flecks {
|
|||
debug('compiling: %s', root);
|
||||
const resolved = dirname(R.resolve(join(root, 'package.json')));
|
||||
const sourcepath = this.sourcepath(resolved);
|
||||
const configFile = this.localConfig(
|
||||
const configFile = this.resolveBuildConfig(
|
||||
resolver,
|
||||
'babel.config.js',
|
||||
'@flecks/core',
|
||||
{root: join(sourcepath, '..')},
|
||||
[
|
||||
resolved,
|
||||
FLECKS_CORE_ROOT,
|
||||
this.resolvePath(resolver, '@flecks/core/server'),
|
||||
],
|
||||
[
|
||||
'babel.config.js',
|
||||
],
|
||||
);
|
||||
const register = R('@babel/register');
|
||||
const config = {
|
||||
|
@ -354,11 +375,30 @@ export default class ServerFlecks extends Flecks {
|
|||
});
|
||||
}
|
||||
|
||||
buildConfig(path, specific) {
|
||||
const config = this.buildConfigs[path];
|
||||
if (!config) {
|
||||
throw new Error(`Unknown build config '${path}'`);
|
||||
}
|
||||
const paths = [];
|
||||
if (config.specifier) {
|
||||
paths.push(config.specifier(specific));
|
||||
}
|
||||
paths.push(path);
|
||||
const roots = [config.root];
|
||||
if (config.root !== FLECKS_CORE_ROOT) {
|
||||
roots.push(FLECKS_CORE_ROOT);
|
||||
}
|
||||
roots.push(this.resolvePath(this.resolve(config.fleck)));
|
||||
return this.constructor.resolveBuildConfig(this.resolver, roots, paths);
|
||||
}
|
||||
|
||||
static environmentalize(key) {
|
||||
return key
|
||||
// - `@flecks/core` -> `FLECKS_CORE`
|
||||
.replace(/[^a-zA-Z0-9]/g, '_')
|
||||
.replace(/_*(.*)_*/, '$1');
|
||||
.replace(/_*(.*)_*/, '$1')
|
||||
.toUpperCase();
|
||||
}
|
||||
|
||||
fleckIsAliased(fleck) {
|
||||
|
@ -379,50 +419,6 @@ export default class ServerFlecks extends Flecks {
|
|||
return realpath !== resolved;
|
||||
}
|
||||
|
||||
localConfig(path, fleck, options) {
|
||||
return this.constructor.localConfig(this.resolver, path, fleck, options);
|
||||
}
|
||||
|
||||
static localConfig(resolver, path, fleck, {general = path, root = FLECKS_CORE_ROOT} = {}) {
|
||||
let configFile;
|
||||
try {
|
||||
const localConfig = join(root, 'build', path);
|
||||
statSync(localConfig);
|
||||
configFile = localConfig;
|
||||
}
|
||||
catch (error) {
|
||||
try {
|
||||
const localConfig = join(root, 'build', general);
|
||||
statSync(localConfig);
|
||||
configFile = localConfig;
|
||||
}
|
||||
catch (error) {
|
||||
try {
|
||||
const localConfig = join(FLECKS_CORE_ROOT, 'build', path);
|
||||
statSync(localConfig);
|
||||
configFile = localConfig;
|
||||
}
|
||||
catch (error) {
|
||||
try {
|
||||
const localConfig = join(FLECKS_CORE_ROOT, 'build', general);
|
||||
statSync(localConfig);
|
||||
configFile = localConfig;
|
||||
}
|
||||
catch (error) {
|
||||
const resolved = this.resolve(resolver, fleck);
|
||||
try {
|
||||
configFile = R.resolve(join(resolved, 'build', path));
|
||||
}
|
||||
catch (error) {
|
||||
configFile = R.resolve(join(resolved, 'build', general));
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
return configFile;
|
||||
}
|
||||
|
||||
rcs() {
|
||||
return this.rcs;
|
||||
}
|
||||
|
@ -435,6 +431,38 @@ export default class ServerFlecks extends Flecks {
|
|||
return resolver[fleck] || fleck;
|
||||
}
|
||||
|
||||
resolveBuildConfig(roots, paths) {
|
||||
return this.constructor.resolveBuildConfig(this.resolver, roots, paths);
|
||||
}
|
||||
|
||||
static resolveBuildConfig(resolver, roots, paths) {
|
||||
for (let i = 0; i < roots.length; ++i) {
|
||||
const root = roots[i];
|
||||
for (let j = 0; j < paths.length; ++j) {
|
||||
const path = paths[j];
|
||||
const resolved = join(root, 'build', path);
|
||||
try {
|
||||
statSync(resolved);
|
||||
return resolved;
|
||||
}
|
||||
// eslint-disable-next-line no-empty
|
||||
catch (error) {}
|
||||
}
|
||||
}
|
||||
throw new Error(`Couldn't resolve build file '${paths.pop()}'`);
|
||||
}
|
||||
|
||||
resolvePath(path) {
|
||||
return this.constructor.resolvePath(this.resolver, path);
|
||||
}
|
||||
|
||||
static resolvePath(resolver, path) {
|
||||
const resolved = R.resolve(this.resolve(resolver, path));
|
||||
const ext = extname(resolved);
|
||||
const base = basename(resolved, ext);
|
||||
return join(dirname(resolved), 'index' === base ? '' : base);
|
||||
}
|
||||
|
||||
root(fleck) {
|
||||
return this.constructor.root(this.resolver, fleck);
|
||||
}
|
||||
|
@ -491,11 +519,7 @@ export default class ServerFlecks extends Flecks {
|
|||
.forEach((root) => {
|
||||
const resolved = dirname(R.resolve(join(root, 'package.json')));
|
||||
const sourcepath = this.sourcepath(resolved);
|
||||
const configFile = this.localConfig(
|
||||
'babel.config.js',
|
||||
'@flecks/core',
|
||||
{root: resolved},
|
||||
);
|
||||
const configFile = this.buildConfig('babel.config.js');
|
||||
debug('compiling: %s with %s', root, configFile);
|
||||
const babel = {
|
||||
configFile,
|
||||
|
@ -503,8 +527,8 @@ export default class ServerFlecks extends Flecks {
|
|||
...babelmerge(...rcBabel.map(([, babel]) => babel)),
|
||||
};
|
||||
compileLoader({
|
||||
ignore: [dirname(sourcepath, '..')],
|
||||
include: [dirname(sourcepath, '..')],
|
||||
ignore: [join(sourcepath, '..')],
|
||||
include: [join(sourcepath, '..')],
|
||||
babel,
|
||||
ruleId: `@flecks/${runtime}/runtime/compile[${root}]`,
|
||||
})(neutrino);
|
||||
|
|
|
@ -23,13 +23,7 @@ export default {
|
|||
if (-1 !== exclude.indexOf(target)) {
|
||||
return;
|
||||
}
|
||||
const baseConfig = R(
|
||||
flecks.localConfig(
|
||||
`${target}.eslint.defaults.js`,
|
||||
'@flecks/core',
|
||||
{general: '.eslint.defaults.js'},
|
||||
),
|
||||
);
|
||||
const baseConfig = R(flecks.buildConfig('.eslint.defaults.js', target));
|
||||
config.use.unshift(
|
||||
airbnb({
|
||||
eslint: {
|
||||
|
@ -43,6 +37,13 @@ export default {
|
|||
}),
|
||||
);
|
||||
},
|
||||
'@flecks/core.build.config': () => [
|
||||
'babel.config.js',
|
||||
['.eslint.defaults.js', {specifier: (specific) => `${specific}.eslint.defaults.js`}],
|
||||
['.eslintrc.js', {specifier: (specific) => `${specific}.eslintrc.js`}],
|
||||
['.neutrinorc.js', {specifier: (specific) => `${specific}.neutrinorc.js`}],
|
||||
'webpack.config.js',
|
||||
],
|
||||
'@flecks/core.commands': commands,
|
||||
},
|
||||
};
|
||||
|
|
|
@ -57,7 +57,7 @@ export default (program, flecks) => {
|
|||
services[key] = {image: config.image, environment: {}};
|
||||
});
|
||||
return [
|
||||
`FLECKS_ENV_${flecks.constructor.environmentalize(fleck).toUpperCase()}`,
|
||||
`FLECKS_ENV_${flecks.constructor.environmentalize(fleck)}`,
|
||||
config,
|
||||
];
|
||||
}),
|
||||
|
|
|
@ -30,7 +30,7 @@ module.exports = (async () => {
|
|||
config.use.unshift((neutrino) => {
|
||||
neutrino.config.plugins.delete('start-server');
|
||||
});
|
||||
const configFile = flecks.localConfig('babel.config.js', '@flecks/core');
|
||||
const configFile = flecks.buildConfig('babel.config.js');
|
||||
config.use.unshift(node({
|
||||
babel: {configFile},
|
||||
clean: {
|
||||
|
|
|
@ -5,15 +5,15 @@ module.exports = (async () => {
|
|||
// eslint-disable-next-line import/no-extraneous-dependencies, global-require
|
||||
const config = await require('@flecks/fleck/server/build/fleck.neutrinorc');
|
||||
config.use.push(({config}) => {
|
||||
config.entryPoints.delete('build/template');
|
||||
config.entryPoints.delete('server/build/template');
|
||||
});
|
||||
config.use.push(
|
||||
copy({
|
||||
copyUnmodified: true,
|
||||
patterns: [
|
||||
{
|
||||
from: 'src/build/template.ejs',
|
||||
to: 'build/template.ejs',
|
||||
from: 'src/server/build/template.ejs',
|
||||
to: 'server/build/template.ejs',
|
||||
},
|
||||
],
|
||||
}),
|
||||
|
|
|
@ -19,7 +19,6 @@
|
|||
},
|
||||
"files": [
|
||||
"build",
|
||||
"build/template.ejs",
|
||||
"client/tests.js",
|
||||
"client/tests.js.map",
|
||||
"entry.js",
|
||||
|
@ -30,6 +29,7 @@
|
|||
"runtime.js.map",
|
||||
"server.js",
|
||||
"server.js.map",
|
||||
"server/build/template.ejs",
|
||||
"server/build/http.neutrinorc.js",
|
||||
"server/build/http.neutrinorc.js.map",
|
||||
"src",
|
||||
|
|
|
@ -50,7 +50,7 @@ module.exports = (async () => {
|
|||
hot: false,
|
||||
html: {
|
||||
inject: false,
|
||||
template: flecks.localConfig('template.ejs', '@flecks/http'),
|
||||
template: flecks.buildConfig('template.ejs'),
|
||||
},
|
||||
style: {
|
||||
extract: {
|
||||
|
|
|
@ -22,7 +22,7 @@ export default {
|
|||
'npx', 'webpack-dev-server',
|
||||
'--mode', 'development',
|
||||
'--hot',
|
||||
'--config', flecks.localConfig('webpack.config.js', '@flecks/core'),
|
||||
'--config', flecks.buildConfig('webpack.config.js'),
|
||||
];
|
||||
spawnWith(
|
||||
cmd,
|
||||
|
@ -36,6 +36,9 @@ export default {
|
|||
// eslint-disable-next-line no-param-reassign
|
||||
delete neutrinoConfigs.http;
|
||||
},
|
||||
'@flecks/core.build.config': () => [
|
||||
'template.ejs',
|
||||
],
|
||||
'@flecks/core.config': () => ({
|
||||
devHost: 'localhost',
|
||||
devPort: undefined,
|
||||
|
|
|
@ -11,7 +11,7 @@ export default {
|
|||
hot: false,
|
||||
html: {
|
||||
inject: false,
|
||||
template: flecks.localConfig('template.ejs', '@flecks/http'),
|
||||
template: flecks.buildConfig('template.ejs'),
|
||||
},
|
||||
style: {
|
||||
extract: {
|
||||
|
|
|
@ -18,7 +18,7 @@ export default {
|
|||
},
|
||||
'@flecks/http.config': async (
|
||||
req,
|
||||
{config: {'@flecks/socket': {'packets.decorate': decorators}}},
|
||||
{config: {'@flecks/socket': {'packets.decorate': decorators = ['...']}}},
|
||||
) => ({
|
||||
'@flecks/socket': {
|
||||
'packets.decorate': decorators.filter(
|
||||
|
|
Loading…
Reference in New Issue
Block a user