From e2d974a7a5f37e3d7d15f83644a974e028bc3fc1 Mon Sep 17 00:00:00 2001 From: cha0s Date: Thu, 17 Mar 2022 15:15:39 -0500 Subject: [PATCH] refactor: styles++ --- packages/core/src/server/flecks.js | 17 ++++--- packages/http/package.json | 2 - packages/http/src/server/build/runtime.js | 51 +++++++++++++++------ packages/http/src/server/index.js | 38 +++++++-------- packages/http/src/server/style-loader.js | 22 --------- packages/server/src/server/build/runtime.js | 2 +- 6 files changed, 68 insertions(+), 64 deletions(-) delete mode 100644 packages/http/src/server/style-loader.js diff --git a/packages/core/src/server/flecks.js b/packages/core/src/server/flecks.js index 3b9d112..a8d8b98 100644 --- a/packages/core/src/server/flecks.js +++ b/packages/core/src/server/flecks.js @@ -522,24 +522,27 @@ export default class ServerFlecks extends Flecks { return undefined; } - runtimeCompiler(runtime, neutrino, {additionalModuleDirs = [], allowlist = []} = {}) { + runtimeCompiler(resolver, runtime, neutrino, {additionalModuleDirs = [], allowlist = []} = {}) { const {config} = neutrino; // Pull the default compiler. if (config.module.rules.has('compile')) { config.module.rules.delete('compile'); } // Flecks that are aliased or symlinked need compilation. - const needCompilation = Object.entries(this.resolver) - .filter(([fleck]) => this.fleckIsAliased(fleck) || this.fleckIsSymlinked(fleck)); + const needCompilation = Object.entries(resolver) + .filter(([fleck]) => ( + this.constructor.fleckIsAliased(resolver, fleck) + || this.constructor.fleckIsSymlinked(resolver, fleck) + )); if (needCompilation.length > 0) { const rcBabel = this.babel(); debug('.flecksrc: babel: %O', rcBabel); // Alias and de-externalize. needCompilation .forEach(([fleck, resolved]) => { - const alias = this.fleckIsAliased(fleck) + const alias = this.constructor.fleckIsAliased(resolver, fleck) ? resolved - : this.sourcepath(R.resolve(this.resolve(fleck))); + : this.constructor.sourcepath(R.resolve(this.constructor.resolve(resolver, fleck))); allowlist.push(fleck); config.resolve.alias .set(`${fleck}$`, alias); @@ -549,11 +552,11 @@ export default class ServerFlecks extends Flecks { Array.from(new Set( needCompilation .map(([fleck]) => fleck) - .map((fleck) => this.root(fleck)), + .map((fleck) => this.constructor.root(resolver, fleck)), )) .forEach((root) => { const resolved = dirname(R.resolve(join(root, 'package.json'))); - const sourcepath = this.sourcepath(resolved); + const sourcepath = this.constructor.sourcepath(resolved); const sourceroot = join(sourcepath, '..'); additionalModuleDirs.push(join(sourceroot, 'node_modules')); const configFile = this.buildConfig('babel.config.js'); diff --git a/packages/http/package.json b/packages/http/package.json index 3038f54..9d7e75e 100644 --- a/packages/http/package.json +++ b/packages/http/package.json @@ -34,8 +34,6 @@ "server/build/template.ejs", "server/build/http.neutrinorc.js", "server/build/http.neutrinorc.js.map", - "server/style-loader.js", - "server/style-loader.js.map", "src", "tests.js", "tests.js.map" diff --git a/packages/http/src/server/build/runtime.js b/packages/http/src/server/build/runtime.js index 105eb45..e9bdcec 100644 --- a/packages/http/src/server/build/runtime.js +++ b/packages/http/src/server/build/runtime.js @@ -1,4 +1,4 @@ -const {realpath} = require('fs/promises'); +const {realpath, stat} = require('fs/promises'); const { dirname, join, @@ -16,11 +16,36 @@ module.exports = async (flecks) => { platforms: ['client', '!server'], }); debug('bootstrapped'); - const runtime = await realpath(R.resolve(join(flecks.resolve('@flecks/http'), 'runtime'))); - const fullresolve = (fleck, path) => realpath(R.resolve(join(flecks.resolve(fleck), path))); + const rootMap = {}; + 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 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) => { const {config} = neutrino; const {resolver} = httpFlecks; @@ -64,7 +89,7 @@ module.exports = async (flecks) => { }); config.resolve.alias .set('@flecks/http/runtime$', runtime); - flecks.runtimeCompiler('http', neutrino); + flecks.runtimeCompiler(httpFlecks.resolver, 'http', neutrino); // Handle runtime import. config.module .rule(entry) @@ -72,7 +97,7 @@ module.exports = async (flecks) => { .use('entry/http') .loader(importLoader); // Aliases. - const aliases = flecks.aliases(); + const aliases = httpFlecks.aliases(); if (Object.keys(aliases).length > 0) { Object.entries(aliases) .forEach(([from, to]) => { @@ -80,16 +105,14 @@ module.exports = async (flecks) => { .set(from, to); }); } + // Styles. + const entries = config.entry('index'); + styles.forEach((style) => { + entries.add(style); + }); // 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 = []; - testRoots.forEach(([fleck, root]) => { + roots.forEach(([fleck, root]) => { testPaths.push(...( glob.sync(join(root, 'test/*.js')) .map((path) => [fleck, path]) diff --git a/packages/http/src/server/index.js b/packages/http/src/server/index.js index 70f377a..34f3ea7 100644 --- a/packages/http/src/server/index.js +++ b/packages/http/src/server/index.js @@ -1,5 +1,5 @@ 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 imageLoader from '@neutrinojs/image-loader'; import styleLoader from '@neutrinojs/style-loader'; @@ -14,17 +14,27 @@ export default { '@flecks/core.build': (target, config, flecks) => { config.use.push((neutrino) => { 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( styleLoader({ - extract: { - enabled: isProduction && 'http' === target, - }, - modules: { - localIdentName: isProduction ? '[hash]' : '[path][name]__[local]', - }, - style: { - injectType: 'http' === target ? 'styleTag' : 'lazyStyleTag', - }, + extract, + style, test: /\.(c|s[ac])ss$/, modulesTest: /\.module\.(c|s[ac])ss$/, 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(imageLoader()); }, diff --git a/packages/http/src/server/style-loader.js b/packages/http/src/server/style-loader.js deleted file mode 100644 index 7fd1462..0000000 --- a/packages/http/src/server/style-loader.js +++ /dev/null @@ -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 */ - }, -}); diff --git a/packages/server/src/server/build/runtime.js b/packages/server/src/server/build/runtime.js index 7194e38..243a320 100644 --- a/packages/server/src/server/build/runtime.js +++ b/packages/server/src/server/build/runtime.js @@ -69,7 +69,7 @@ module.exports = async (flecks) => { additionalModuleDirs: [], allowlist, }; - flecks.runtimeCompiler('server', neutrino, nodeExternalsConfig); + flecks.runtimeCompiler(flecks.resolver, 'server', neutrino, nodeExternalsConfig); // Rewrite to signals for HMR. if ('production' !== config.get('mode')) { allowlist.push(/^webpack/);