refactor: styles++

This commit is contained in:
cha0s 2022-03-17 15:15:39 -05:00
parent 36a633f460
commit e2d974a7a5
6 changed files with 68 additions and 64 deletions

View File

@ -522,24 +522,27 @@ export default class ServerFlecks extends Flecks {
return undefined; return undefined;
} }
runtimeCompiler(runtime, neutrino, {additionalModuleDirs = [], allowlist = []} = {}) { runtimeCompiler(resolver, runtime, neutrino, {additionalModuleDirs = [], allowlist = []} = {}) {
const {config} = neutrino; const {config} = neutrino;
// Pull the default compiler. // Pull the default compiler.
if (config.module.rules.has('compile')) { if (config.module.rules.has('compile')) {
config.module.rules.delete('compile'); config.module.rules.delete('compile');
} }
// Flecks that are aliased or symlinked need compilation. // Flecks that are aliased or symlinked need compilation.
const needCompilation = Object.entries(this.resolver) const needCompilation = Object.entries(resolver)
.filter(([fleck]) => this.fleckIsAliased(fleck) || this.fleckIsSymlinked(fleck)); .filter(([fleck]) => (
this.constructor.fleckIsAliased(resolver, fleck)
|| this.constructor.fleckIsSymlinked(resolver, fleck)
));
if (needCompilation.length > 0) { if (needCompilation.length > 0) {
const rcBabel = this.babel(); const rcBabel = this.babel();
debug('.flecksrc: babel: %O', rcBabel); debug('.flecksrc: babel: %O', rcBabel);
// Alias and de-externalize. // Alias and de-externalize.
needCompilation needCompilation
.forEach(([fleck, resolved]) => { .forEach(([fleck, resolved]) => {
const alias = this.fleckIsAliased(fleck) const alias = this.constructor.fleckIsAliased(resolver, fleck)
? resolved ? resolved
: this.sourcepath(R.resolve(this.resolve(fleck))); : this.constructor.sourcepath(R.resolve(this.constructor.resolve(resolver, fleck)));
allowlist.push(fleck); allowlist.push(fleck);
config.resolve.alias config.resolve.alias
.set(`${fleck}$`, alias); .set(`${fleck}$`, alias);
@ -549,11 +552,11 @@ export default class ServerFlecks extends Flecks {
Array.from(new Set( Array.from(new Set(
needCompilation needCompilation
.map(([fleck]) => fleck) .map(([fleck]) => fleck)
.map((fleck) => this.root(fleck)), .map((fleck) => this.constructor.root(resolver, fleck)),
)) ))
.forEach((root) => { .forEach((root) => {
const resolved = dirname(R.resolve(join(root, 'package.json'))); const resolved = dirname(R.resolve(join(root, 'package.json')));
const sourcepath = this.sourcepath(resolved); const sourcepath = this.constructor.sourcepath(resolved);
const sourceroot = join(sourcepath, '..'); const sourceroot = join(sourcepath, '..');
additionalModuleDirs.push(join(sourceroot, 'node_modules')); additionalModuleDirs.push(join(sourceroot, 'node_modules'));
const configFile = this.buildConfig('babel.config.js'); const configFile = this.buildConfig('babel.config.js');

View File

@ -34,8 +34,6 @@
"server/build/template.ejs", "server/build/template.ejs",
"server/build/http.neutrinorc.js", "server/build/http.neutrinorc.js",
"server/build/http.neutrinorc.js.map", "server/build/http.neutrinorc.js.map",
"server/style-loader.js",
"server/style-loader.js.map",
"src", "src",
"tests.js", "tests.js",
"tests.js.map" "tests.js.map"

View File

@ -1,4 +1,4 @@
const {realpath} = require('fs/promises'); const {realpath, stat} = require('fs/promises');
const { const {
dirname, dirname,
join, join,
@ -16,11 +16,36 @@ module.exports = async (flecks) => {
platforms: ['client', '!server'], platforms: ['client', '!server'],
}); });
debug('bootstrapped'); debug('bootstrapped');
const runtime = await realpath(R.resolve(join(flecks.resolve('@flecks/http'), 'runtime'))); const rootMap = {};
const fullresolve = (fleck, path) => realpath(R.resolve(join(flecks.resolve(fleck), path))); Object.keys(httpFlecks.resolver)
.forEach((fleck) => {
rootMap[httpFlecks.root(fleck)] = fleck;
});
const roots = Object.entries(rootMap)
.map(([root, fleck]) => (
[fleck, dirname(R.resolve(join(root, 'package.json')))]
));
const styles = (
await Promise.all(
roots
.map(async ([, path]) => {
try {
const filename = join(path, 'index.css');
await stat(filename);
return filename;
}
catch (error) {
return undefined;
}
}),
)
)
.filter((filename) => !!filename);
const runtime = await realpath(R.resolve(join(httpFlecks.resolve('@flecks/http'), 'runtime')));
const fullresolve = (fleck, path) => realpath(R.resolve(join(httpFlecks.resolve(fleck), path)));
const entry = await fullresolve('@flecks/http', 'entry'); const entry = await fullresolve('@flecks/http', 'entry');
const importLoader = await fullresolve('@flecks/http', 'import-loader'); const importLoader = await fullresolve('@flecks/http', 'import-loader');
const tests = await realpath(R.resolve(join(flecks.resolve('@flecks/http'), 'tests'))); const tests = await realpath(R.resolve(join(httpFlecks.resolve('@flecks/http'), 'tests')));
return (neutrino) => { return (neutrino) => {
const {config} = neutrino; const {config} = neutrino;
const {resolver} = httpFlecks; const {resolver} = httpFlecks;
@ -64,7 +89,7 @@ module.exports = async (flecks) => {
}); });
config.resolve.alias config.resolve.alias
.set('@flecks/http/runtime$', runtime); .set('@flecks/http/runtime$', runtime);
flecks.runtimeCompiler('http', neutrino); flecks.runtimeCompiler(httpFlecks.resolver, 'http', neutrino);
// Handle runtime import. // Handle runtime import.
config.module config.module
.rule(entry) .rule(entry)
@ -72,7 +97,7 @@ module.exports = async (flecks) => {
.use('entry/http') .use('entry/http')
.loader(importLoader); .loader(importLoader);
// Aliases. // Aliases.
const aliases = flecks.aliases(); const aliases = httpFlecks.aliases();
if (Object.keys(aliases).length > 0) { if (Object.keys(aliases).length > 0) {
Object.entries(aliases) Object.entries(aliases)
.forEach(([from, to]) => { .forEach(([from, to]) => {
@ -80,16 +105,14 @@ module.exports = async (flecks) => {
.set(from, to); .set(from, to);
}); });
} }
// Styles.
const entries = config.entry('index');
styles.forEach((style) => {
entries.add(style);
});
// Tests. // Tests.
const testRoots = Array.from(new Set(
Object.keys(httpFlecks.resolver)
.map((fleck) => [fleck, httpFlecks.root(fleck)]),
))
.map(([fleck, root]) => (
[fleck, dirname(R.resolve(join(root, 'package.json')))]
));
const testPaths = []; const testPaths = [];
testRoots.forEach(([fleck, root]) => { roots.forEach(([fleck, root]) => {
testPaths.push(...( testPaths.push(...(
glob.sync(join(root, 'test/*.js')) glob.sync(join(root, 'test/*.js'))
.map((path) => [fleck, path]) .map((path) => [fleck, path])

View File

@ -1,5 +1,5 @@
import {D, Hooks} from '@flecks/core'; import {D, Hooks} from '@flecks/core';
import {Flecks, require as R, spawnWith} from '@flecks/core/server'; import {Flecks, spawnWith} from '@flecks/core/server';
import fontLoader from '@neutrinojs/font-loader'; import fontLoader from '@neutrinojs/font-loader';
import imageLoader from '@neutrinojs/image-loader'; import imageLoader from '@neutrinojs/image-loader';
import styleLoader from '@neutrinojs/style-loader'; import styleLoader from '@neutrinojs/style-loader';
@ -14,17 +14,27 @@ export default {
'@flecks/core.build': (target, config, flecks) => { '@flecks/core.build': (target, config, flecks) => {
config.use.push((neutrino) => { config.use.push((neutrino) => {
const isProduction = 'production' === neutrino.config.get('mode'); const isProduction = 'production' === neutrino.config.get('mode');
const extract = {};
const style = {};
if ('server' === target) {
extract.enabled = false;
style.injectType = 'lazyStyleTag';
}
if ('http' === target) {
extract.enabled = isProduction;
style.injectType = 'styleTag';
}
if ('fleck' === target) {
extract.enabled = true;
extract.plugin = {
filename: 'index.css',
};
style.injectType = 'lazyStyleTag';
}
neutrino.use( neutrino.use(
styleLoader({ styleLoader({
extract: { extract,
enabled: isProduction && 'http' === target, style,
},
modules: {
localIdentName: isProduction ? '[hash]' : '[path][name]__[local]',
},
style: {
injectType: 'http' === target ? 'styleTag' : 'lazyStyleTag',
},
test: /\.(c|s[ac])ss$/, test: /\.(c|s[ac])ss$/,
modulesTest: /\.module\.(c|s[ac])ss$/, modulesTest: /\.module\.(c|s[ac])ss$/,
loaders: [ loaders: [
@ -45,14 +55,6 @@ export default {
}), }),
); );
}); });
if ('fleck' === target) {
config.use.push((neutrino) => {
neutrino.config.module.rule('compile').use('babel').tap((options) => ({
...options,
plugins: [...options.plugins, R.resolve('@flecks/http/server/style-loader')],
}));
});
}
config.use.push(fontLoader()); config.use.push(fontLoader());
config.use.push(imageLoader()); config.use.push(imageLoader());
}, },

View File

@ -1,22 +0,0 @@
const parser = require('@babel/parser');
const types = require('@babel/types');
let id = 0;
module.exports = () => ({
visitor: {
/* eslint-disable no-param-reassign */
ImportDeclaration(path) {
if (path.node.source.value.match(/\.(c|s[ac])ss$/)) {
let defaultSpecifier = path.node.specifiers.find(types.isImportDefaultSpecifier);
if (!defaultSpecifier) {
defaultSpecifier = types.importDefaultSpecifier(types.identifier(`FLECKS_STYLES_${id++}`));
path.node.specifiers.unshift(defaultSpecifier);
}
const {name} = defaultSpecifier.local;
path.insertAfter(parser.parse(`if ('undefined' !== typeof document) ${name}.use();`));
}
},
/* eslint-enable no-param-reassign */
},
});

View File

@ -69,7 +69,7 @@ module.exports = async (flecks) => {
additionalModuleDirs: [], additionalModuleDirs: [],
allowlist, allowlist,
}; };
flecks.runtimeCompiler('server', neutrino, nodeExternalsConfig); flecks.runtimeCompiler(flecks.resolver, 'server', neutrino, nodeExternalsConfig);
// Rewrite to signals for HMR. // Rewrite to signals for HMR.
if ('production' !== config.get('mode')) { if ('production' !== config.get('mode')) {
allowlist.push(/^webpack/); allowlist.push(/^webpack/);