refactor: app structure

This commit is contained in:
cha0s 2021-03-23 11:59:22 -05:00
parent 9d56138104
commit fe4d29df16
19 changed files with 110 additions and 105 deletions

View File

@ -1,4 +1,4 @@
const {dirname} = require('path'); const {dirname, join} = require('path');
const react = require('@neutrinojs/react'); const react = require('@neutrinojs/react');

View File

@ -8,6 +8,7 @@ import {
import Latus from './latus'; import Latus from './latus';
import R from './require'; import R from './require';
import root from './root';
const { const {
LATUS_BABEL_CONFIG = require.resolve('@latus/build/build/.babelrc.js'), LATUS_BABEL_CONFIG = require.resolve('@latus/build/build/.babelrc.js'),
@ -98,9 +99,16 @@ export default (latus) => (neutrino) => {
.options({ .options({
source: source.join('\n'), source: source.join('\n'),
}); });
neutrino.config // const entries = Array.from(
.entry('index') // neutrino.config
.add('@latus/core/start'); // .entryPoints.store.get('index')
// .store
// );
// eslint-disable-next-line no-param-reassign
// neutrino.options.mains.index.entry = '@latus/core/start';
// neutrino.config
// .entry('index')
// .add('@latus/core/start');
const mocha = R('@neutrinojs/mocha'); const mocha = R('@neutrinojs/mocha');
mocha()(neutrino); mocha()(neutrino);
if (process.env.LATUS_LINTING) { if (process.env.LATUS_LINTING) {
@ -132,14 +140,13 @@ export default (latus) => (neutrino) => {
neutrino.config.externals(nodeExternals({ neutrino.config.externals(nodeExternals({
allowlist, allowlist,
})); }));
const entries = neutrino.config.entryPoints.store.get('index').store; const entries = neutrino.config.entry('index');
if (entries.has(`${R.resolve('webpack/hot/poll')}?1000`)) { if (entries.has(`${R.resolve('webpack/hot/poll')}?1000`)) {
entries.delete(`${R.resolve('webpack/hot/poll')}?1000`); entries.delete(`${R.resolve('webpack/hot/poll')}?1000`);
const entriesArray = Array.from(entries); entries.add('webpack/hot/signal');
entriesArray.unshift('webpack/hot/signal');
// eslint-disable-next-line no-param-reassign
neutrino.config.entryPoints.store.get('index').store = new Set(entriesArray);
} }
entries.delete(join(root, 'src', 'index'));
entries.add('@latus/core/start');
if (process.argv.find((arg) => '--start-server' === arg)) { if (process.argv.find((arg) => '--start-server' === arg)) {
neutrino.config neutrino.config
.plugin('start-server') .plugin('start-server')

View File

@ -12,6 +12,7 @@ export {decorateWithLatus, gatherWithLatus, default as gather} from './gather';
export {default as Middleware} from './middleware'; export {default as Middleware} from './middleware';
export {default as Latus} from './latus'; export {default as Latus} from './latus';
export {default as require} from './require'; export {default as require} from './require';
export {default as root} from './root';
export * from './string'; export * from './string';
export const Class = class {}; export const Class = class {};

View File

@ -1,14 +1,16 @@
import fs from 'fs';
import {join} from 'path'; import {join} from 'path';
import D from 'debug'; import D from 'debug';
import yaml from 'js-yaml';
import flatten from 'lodash.flatten'; import flatten from 'lodash.flatten';
import get from 'lodash.get'; import get from 'lodash.get';
import set from 'lodash.set'; import set from 'lodash.set';
import without from 'lodash.without'; import without from 'lodash.without';
import Middleware from './middleware'; import Middleware from './middleware';
import readConfig from './read-config';
import R from './require'; import R from './require';
import root from './root';
const debug = D('@latus/core/latus'); const debug = D('@latus/core/latus');
@ -56,7 +58,9 @@ export default class Latus {
debug('latus config: %O', this.config); debug('latus config: %O', this.config);
} }
static create(config = readConfig()) { static create() {
const path = join(root, 'latus.yml');
const config = yaml.safeLoad(fs.readFileSync(path, 'utf8'));
const paths = flatten( const paths = flatten(
Object.keys(config).map((path) => [ Object.keys(config).map((path) => [
this.runtimePath(path), this.runtimePath(path),
@ -221,18 +225,11 @@ export default class Latus {
static runtimePath(path) { static runtimePath(path) {
try { try {
const local = join(process.cwd(), 'src', path); R.resolve(path);
R.resolve(local); return path;
return local;
} }
catch (error) { catch (error) {
try { return '';
R.resolve(path);
return path;
}
catch (error) {
return '';
}
} }
} }

View File

@ -1,8 +0,0 @@
import fs from 'fs';
import yaml from 'js-yaml';
const readConfig = (path = `${process.cwd()}/latus.yml`) => (
yaml.safeLoad(fs.readFileSync(path, 'utf8'))
);
export default readConfig;

View File

@ -0,0 +1 @@
export default process.env.LATUS_ROOT || process.cwd();

View File

@ -1,5 +1,7 @@
import {spawn, spawnSync} from 'child_process'; import {spawn, spawnSync} from 'child_process';
import {join} from 'path';
import {root} from '@latus/core';
import mkdirp from 'mkdirp'; import mkdirp from 'mkdirp';
export default function createDockerContainer(latus) { export default function createDockerContainer(latus) {
@ -24,7 +26,7 @@ export default function createDockerContainer(latus) {
'-e', `MYSQL_ROOT_PASSWORD=${password}`, '-e', `MYSQL_ROOT_PASSWORD=${password}`,
]; ];
if ('cached' === docker) { if ('cached' === docker) {
const datadir = `${process.cwd()}/node_modules/.cache/@latus/db/docker`; const datadir = join(root, 'node_modules', '.cache', '@latus', 'db', 'docker');
mkdirp.sync(datadir); mkdirp.sync(datadir);
args.push( args.push(
'-v', '-v',

View File

@ -11,7 +11,7 @@ module.exports = (async () => {
const latus = Latus.create(); const latus = Latus.create();
const config = { const config = {
use: [ use: [
targets(), targets(latus),
web(), web(),
await virtual(latus), await virtual(latus),
], ],

View File

@ -1,42 +1,29 @@
/* eslint-disable no-param-reassign */ /* eslint-disable no-param-reassign */
const {isAbsolute, join} = require('path'); const {join} = require('path');
const fs = require('fs'); const fs = require('fs');
const {require: R} = require('@latus/core'); const {require: R, root} = require('@latus/core');
const {DefinePlugin} = require('webpack'); const {EnvironmentPlugin} = require('webpack');
module.exports = () => (neutrino) => { module.exports = (latus) => (neutrino) => {
const copy = R('@neutrinojs/copy');
copy({
patterns: [{
from: join(neutrino.options.root, 'src', 'assets'),
to: 'http',
}],
})(neutrino);
neutrino.config neutrino.config
.plugin('environment') .plugin('environment')
.use(DefinePlugin, [{ .use(EnvironmentPlugin, [{
'process.env.SIDE': JSON.stringify('client'), SIDE: 'client',
}]); }]);
neutrino.config.resolve.modules.merge([ neutrino.config.resolve.modules.merge([
join(process.cwd(), 'node_modules'), join(root, 'node_modules'),
'node_modules', 'node_modules',
]); ]);
neutrino.options.appRoot = neutrino.options.root; neutrino.options.appRoot = neutrino.options.root;
neutrino.options.appSource = join(neutrino.options.appRoot, 'src'); neutrino.options.appSource = join(neutrino.options.appRoot, 'src');
const root = join(__dirname, '..', '..'); neutrino.options.root = fs.realpathSync(join(__dirname, '..', '..'));
neutrino.options.root = fs.realpathSync(root);
neutrino.options.source = 'client'; neutrino.options.source = 'client';
neutrino.options.mains.index = 'entry'; neutrino.options.mains.index = 'entry';
neutrino.options.mains.tests = { neutrino.options.mains.tests = {
entry: './client/tests', entry: './client/tests',
title: 'Mocha tests', title: 'Mocha tests',
}; };
const output = 'build'; const {build} = latus.get('@latus/http/server');
neutrino.options.output = join( neutrino.options.output = join(root, build);
isAbsolute(output)
? output
: join(process.cwd(), output),
'http',
);
}; };

View File

@ -1,4 +1,5 @@
/* eslint-disable no-param-reassign */ const {join} = require('path');
const web = require('@neutrinojs/web'); const web = require('@neutrinojs/web');
const { const {
@ -18,7 +19,6 @@ module.exports = () => {
template: `${neutrino.options.root}/client/index.ejs`, template: `${neutrino.options.root}/client/index.ejs`,
}, },
})(neutrino); })(neutrino);
neutrino.config.module.rule('compile').include.add(`${process.cwd()}/src`);
}; };
middleware.isWebMiddleware = true; middleware.isWebMiddleware = true;
return middleware; return middleware;

View File

@ -2,7 +2,12 @@ import {createReadStream} from 'fs';
import {createServer, ServerResponse} from 'http'; import {createServer, ServerResponse} from 'http';
import {dirname, join} from 'path'; import {dirname, join} from 'path';
import {arrayFlatten, Latus, require as R} from '@latus/core'; import {
arrayFlatten,
Latus,
require as R,
root,
} from '@latus/core';
import express from 'express'; import express from 'express';
// eslint-disable-next-line import/no-extraneous-dependencies // eslint-disable-next-line import/no-extraneous-dependencies
import httpProxy from 'http-proxy'; import httpProxy from 'http-proxy';
@ -42,7 +47,7 @@ export const createHttpServer = async (latus) => {
routes.forEach(({method, path, handler}) => app[method](path, requestMiddleware, handler)); routes.forEach(({method, path, handler}) => app[method](path, requestMiddleware, handler));
// Serve latus. // Serve latus.
app.get('/latus.config.js', requestMiddleware, configMiddleware(latus)); app.get('/latus.config.js', requestMiddleware, configMiddleware(latus));
app.use(express.static(join(process.cwd(), build))); app.use(express.static(join(root, build)));
// eslint-disable-next-line no-eval // eslint-disable-next-line no-eval
if ('production' !== eval('process.env.NODE_ENV')) { if ('production' !== eval('process.env.NODE_ENV')) {
const middlewares = Object.keys(await clientPlugins(latus)) const middlewares = Object.keys(await clientPlugins(latus))
@ -89,7 +94,7 @@ export const createHttpServer = async (latus) => {
app.use(express.static(join(__dirname, 'client'))); app.use(express.static(join(__dirname, 'client')));
app.get('*', async (req, res) => { app.get('*', async (req, res) => {
res.setHeader('Content-Type', 'text/html; charset=UTF-8'); res.setHeader('Content-Type', 'text/html; charset=UTF-8');
const stream = createReadStream(join(process.cwd(), build, 'index.html')); const stream = createReadStream(join(root, build, 'index.html'));
stream.pipe(res); stream.pipe(res);
}); });
} }

View File

@ -1,14 +1,14 @@
import {spawn} from 'child_process'; import {spawn} from 'child_process';
import {join} from 'path'; import {join} from 'path';
import {require as R} from '@latus/core'; import {require as R, root} from '@latus/core';
import {createHttpServer} from './http'; import {createHttpServer} from './http';
const { const {
LATUS_EXCLUDE_BUILD = '', LATUS_ONLY_BUILD = '',
} = process.env; } = process.env;
const excludeBuilds = LATUS_EXCLUDE_BUILD.split(',').map((name) => name.trim()); const onlyBuilds = LATUS_ONLY_BUILD.split(',').map((name) => name.trim());
export default { export default {
hooks: { hooks: {
@ -29,8 +29,8 @@ export default {
// eslint-disable-next-line no-param-reassign // eslint-disable-next-line no-param-reassign
configs.http = R(join(__dirname, 'build/.neutrinorc.js')); configs.http = R(join(__dirname, 'build/.neutrinorc.js'));
} }
else if (-1 === excludeBuilds.indexOf('http')) { else if (-1 !== onlyBuilds.indexOf('http')) {
const binary = `$(npm --prefix ${process.cwd()} bin)/webpack-dev-server`; const binary = `$(npm --prefix ${root} bin)/webpack-dev-server`;
const config = `${__dirname}/build/webpack.config.js`; const config = `${__dirname}/build/webpack.config.js`;
const options = { const options = {
env: { env: {
@ -46,7 +46,7 @@ export default {
} }
}, },
'@latus/core/config': () => ({ '@latus/core/config': () => ({
build: 'build/http', build: join('build', 'http'),
devPort: 32341, devPort: 32341,
devPublic: undefined, devPublic: undefined,
host: '0.0.0.0', host: '0.0.0.0',

View File

@ -1,21 +1,8 @@
const react = require('./react'); const react = require('./react');
module.exports = (config, latus) => { module.exports = (config) => {
const webIndex = config.use.findIndex((m) => m.isWebMiddleware); const webIndex = config.use.findIndex((m) => m.isWebMiddleware);
if (-1 !== webIndex) { if (-1 !== webIndex) {
config.use.splice(webIndex, 1, react(latus)); config.use.splice(webIndex, 1, react());
} }
config.use.push((neutrino) => {
[
'components',
'context',
'fonts',
'hooks',
'images',
'scss',
].forEach((path) => {
neutrino.config.resolve.alias
.set(path, `${process.cwd()}/src/react/${path}`);
});
});
}; };

View File

@ -1,8 +1,4 @@
const { const {dirname} = require('path');
dirname,
isAbsolute,
join,
} = require('path');
const {require: R} = require('@latus/core'); const {require: R} = require('@latus/core');
const react = require('@neutrinojs/react'); const react = require('@neutrinojs/react');
@ -13,7 +9,7 @@ const {
LATUS_POSTCSS_CONFIG = resolve('@latus/build/build/postcss.config.js'), LATUS_POSTCSS_CONFIG = resolve('@latus/build/build/postcss.config.js'),
} = process.env; } = process.env;
module.exports = (latus) => (neutrino) => { module.exports = () => (neutrino) => {
react({ react({
babel: { babel: {
configFile: LATUS_BABEL_CONFIG, configFile: LATUS_BABEL_CONFIG,
@ -47,12 +43,4 @@ module.exports = (latus) => (neutrino) => {
], ],
}, },
})(neutrino); })(neutrino);
const {entry} = latus.get('@latus/react');
neutrino.config.module
.rule('compile').include
.add(
isAbsolute(entry)
? entry
: join(neutrino.options.appSource, entry),
);
}; };

View File

@ -12,7 +12,6 @@ export default {
hooks: { hooks: {
'@latus/core/config': () => ({ '@latus/core/config': () => ({
providers: [], providers: [],
entry: './react',
}), }),
}, },
}; };

View File

@ -2,13 +2,8 @@ const httpBuild = require('./build/http');
export default { export default {
hooks: { hooks: {
'@latus/http/build': (config, latus) => { '@latus/http/build': (config) => {
httpBuild(config, latus); httpBuild(config);
}, },
'@latus/http/plugins': (req, {
config: {'@latus/react': {entry}},
}) => ({
[entry]: {},
}),
}, },
}; };

View File

@ -22,6 +22,7 @@
"test.js.map" "test.js.map"
], ],
"dependencies": { "dependencies": {
"@latus/core": "^2.0.0",
"autoprefixer": "^9.8.6", "autoprefixer": "^9.8.6",
"connect-redis": "^5.0.0", "connect-redis": "^5.0.0",
"debug": "4.3.1", "debug": "4.3.1",

View File

@ -1,7 +1,8 @@
import D from 'debug';
import {spawn, spawnSync} from 'child_process'; import {spawn, spawnSync} from 'child_process';
import {join} from 'path';
import {root} from '@latus/core';
import D from 'debug';
import mkdirp from 'mkdirp'; import mkdirp from 'mkdirp';
import createClient from './create-client'; import createClient from './create-client';
@ -23,7 +24,7 @@ export default async function createDockerContainer(latus) {
'-p', `${port}:6379`, '-p', `${port}:6379`,
]; ];
if ('cached' === docker) { if ('cached' === docker) {
const datadir = `${process.cwd()}/node_modules/.cache/@latus/redis/docker`; const datadir = join(root, 'node_modules', '.cache', '@latus', 'redis', 'docker');
mkdirp.sync(datadir); mkdirp.sync(datadir);
args.push( args.push(
'-v', '-v',

View File

@ -300,6 +300,20 @@
webpack "^4" webpack "^4"
webpack-cli "^3" webpack-cli "^3"
"@latus/core@^2.0.0":
version "2.0.0"
resolved "http://npm.cha0sdev/@latus%2fcore/-/core-2.0.0.tgz#12a0f3c11c9832a60e6726ea74ce0ae9b45e9faf"
integrity sha512-JMxgl8Qsvby2OKtzXEs7cjamvsgVxEbJXbjebsmDl+J9Cq5513/4Xpq37EYYvT6FEZpoHFoIkQsaG+89JQzTwg==
dependencies:
autoprefixer "^9.8.6"
debug "4.3.1"
js-yaml "3.14.0"
lodash.flatten "^4.4.0"
lodash.get "^4.4.2"
lodash.set "^4.3.2"
mkdirp "^1.0.4"
webpack-virtual-modules "^0.4.1"
"@neutrinojs/airbnb@^9.4.0": "@neutrinojs/airbnb@^9.4.0":
version "9.5.0" version "9.5.0"
resolved "http://npm.cha0sdev/@neutrinojs%2fairbnb/-/airbnb-9.5.0.tgz#87cfc09c4237a2da632c80d7b91ad447a5e0b3f2" resolved "http://npm.cha0sdev/@neutrinojs%2fairbnb/-/airbnb-9.5.0.tgz#87cfc09c4237a2da632c80d7b91ad447a5e0b3f2"
@ -2794,6 +2808,14 @@ javascript-stringify@^2.0.1:
resolved "http://npm.cha0sdev/js-tokens/-/js-tokens-4.0.0.tgz#19203fb59991df98e3a287050d4647cdeaf32499" resolved "http://npm.cha0sdev/js-tokens/-/js-tokens-4.0.0.tgz#19203fb59991df98e3a287050d4647cdeaf32499"
integrity sha512-RdJUflcE3cUzKiMqQgsCu06FPu9UdIJO0beYbPhHN4k6apgJtifcoCtT9bcxOpYBtpD2kCM6Sbzg4CausW/PKQ== integrity sha512-RdJUflcE3cUzKiMqQgsCu06FPu9UdIJO0beYbPhHN4k6apgJtifcoCtT9bcxOpYBtpD2kCM6Sbzg4CausW/PKQ==
js-yaml@3.14.0:
version "3.14.0"
resolved "http://npm.cha0sdev/js-yaml/-/js-yaml-3.14.0.tgz#a7a34170f26a21bb162424d8adacb4113a69e482"
integrity sha512-/4IbIeHcD9VMHFqDR/gQ7EdZdLimOvW2DdcxFjdyyZ9NsbS+ccrXqVWDtab/lRl5AlUqmpBx8EhPaWR+OtY17A==
dependencies:
argparse "^1.0.7"
esprima "^4.0.0"
js-yaml@4.0.0: js-yaml@4.0.0:
version "4.0.0" version "4.0.0"
resolved "http://npm.cha0sdev/js-yaml/-/js-yaml-4.0.0.tgz#f426bc0ff4b4051926cd588c71113183409a121f" resolved "http://npm.cha0sdev/js-yaml/-/js-yaml-4.0.0.tgz#f426bc0ff4b4051926cd588c71113183409a121f"
@ -2975,11 +2997,26 @@ lodash.clonedeep@^4.5.0:
resolved "http://npm.cha0sdev/lodash.clonedeep/-/lodash.clonedeep-4.5.0.tgz#e23f3f9c4f8fbdde872529c1071857a086e5ccef" resolved "http://npm.cha0sdev/lodash.clonedeep/-/lodash.clonedeep-4.5.0.tgz#e23f3f9c4f8fbdde872529c1071857a086e5ccef"
integrity sha1-4j8/nE+Pvd6HJSnBBxhXoIblzO8= integrity sha1-4j8/nE+Pvd6HJSnBBxhXoIblzO8=
lodash.flatten@^4.4.0:
version "4.4.0"
resolved "http://npm.cha0sdev/lodash.flatten/-/lodash.flatten-4.4.0.tgz#f31c22225a9632d2bbf8e4addbef240aa765a61f"
integrity sha1-8xwiIlqWMtK7+OSt2+8kCqdlph8=
lodash.get@^4.4.2:
version "4.4.2"
resolved "http://npm.cha0sdev/lodash.get/-/lodash.get-4.4.2.tgz#2d177f652fa31e939b4438d5341499dfa3825e99"
integrity sha1-LRd/ZS+jHpObRDjVNBSZ36OCXpk=
lodash.omit@^4.5.0: lodash.omit@^4.5.0:
version "4.5.0" version "4.5.0"
resolved "http://npm.cha0sdev/lodash.omit/-/lodash.omit-4.5.0.tgz#6eb19ae5a1ee1dd9df0b969e66ce0b7fa30b5e60" resolved "http://npm.cha0sdev/lodash.omit/-/lodash.omit-4.5.0.tgz#6eb19ae5a1ee1dd9df0b969e66ce0b7fa30b5e60"
integrity sha1-brGa5aHuHdnfC5aeZs4Lf6MLXmA= integrity sha1-brGa5aHuHdnfC5aeZs4Lf6MLXmA=
lodash.set@^4.3.2:
version "4.3.2"
resolved "http://npm.cha0sdev/lodash.set/-/lodash.set-4.3.2.tgz#d8757b1da807dde24816b0d6a84bea1a76230b23"
integrity sha1-2HV7HagH3eJIFrDWqEvqGnYjCyM=
lodash@^4.17.15, lodash@^4.17.19, lodash@^4.17.20: lodash@^4.17.15, lodash@^4.17.19, lodash@^4.17.20:
version "4.17.20" version "4.17.20"
resolved "http://npm.cha0sdev/lodash/-/lodash-4.17.20.tgz#b44a9b6297bcb698f1c51a3545a2b3b368d59c52" resolved "http://npm.cha0sdev/lodash/-/lodash-4.17.20.tgz#b44a9b6297bcb698f1c51a3545a2b3b368d59c52"
@ -4837,6 +4874,11 @@ webpack-sources@^1.4.0, webpack-sources@^1.4.1:
source-list-map "^2.0.0" source-list-map "^2.0.0"
source-map "~0.6.1" source-map "~0.6.1"
webpack-virtual-modules@^0.4.1:
version "0.4.2"
resolved "http://npm.cha0sdev/webpack-virtual-modules/-/webpack-virtual-modules-0.4.2.tgz#68ce4479df7334a491b7a3f3bead47fe382947d9"
integrity sha512-OUsT1VZhArN8nY7g6mMlw91HWnXcNXsIQjsQ83WteF4ViZ6YXqF2sWKOTDIZ0H+PPiApQdszLdZIrD7NNlU0Yw==
webpack@^4: webpack@^4:
version "4.46.0" version "4.46.0"
resolved "http://npm.cha0sdev/webpack/-/webpack-4.46.0.tgz#bf9b4404ea20a073605e0a011d188d77cb6ad542" resolved "http://npm.cha0sdev/webpack/-/webpack-4.46.0.tgz#bf9b4404ea20a073605e0a011d188d77cb6ad542"