fix: avoid FOUC on dev

This commit is contained in:
cha0s 2022-03-20 02:59:20 -05:00
parent 780fa433e1
commit 18e2bb9446
9 changed files with 87 additions and 92 deletions

View File

@ -5,6 +5,12 @@ import ReactDOMServer from '@hot-loader/react-dom/server';
import root from './root';
const {
NODE_ENV,
} = process.env;
console.log({NODE_ENV});
class Ssr extends Transform {
constructor(flecks, req) {
@ -24,7 +30,10 @@ class Ssr extends Transform {
this.push(
string.replace(
'<div id="root"></div>',
`<div id="root">${output}</div>`,
`<div id="root"${
// What FOUC? ;)
'production' !== NODE_ENV ? ' style="display: none"' : ''
}>${output}</div>`,
),
);
}

View File

@ -7,6 +7,7 @@ module.exports = async (flecks) => {
// eslint-disable-next-line import/no-extraneous-dependencies, global-require
const config = await require('@flecks/fleck/server/build/fleck.neutrinorc')(flecks);
config.use.push(({config}) => {
config.entryPoints.delete('server/build/entry');
config.entryPoints.delete('server/build/template');
config.entryPoints.delete('server/build/tests');
config.externals(nodeExternals({
@ -26,6 +27,10 @@ module.exports = async (flecks) => {
copy({
copyUnmodified: true,
patterns: [
{
from: 'src/server/build/entry.js',
to: 'server/build/entry.js',
},
{
from: 'src/server/build/template.ejs',
to: 'server/build/template.ejs',

View File

@ -21,12 +21,12 @@
"build",
"entry.js",
"entry.js.map",
"import-loader.js",
"import-loader.js.map",
"runtime.js",
"runtime.js.map",
"server.js",
"server.js.map",
"server/build/entry.js",
"server/build/entry.js.map",
"server/build/postcss.config.js",
"server/build/postcss.config.js.map",
"server/build/template.ejs",

View File

@ -1,34 +0,0 @@
import {D, Flecks} from '@flecks/core';
import Progress from './progress';
/* global __non_webpack_import__ */
const {version} = require('../package.json');
const progress = new Progress(window);
(async () => {
// eslint-disable-next-line no-console
console.log(`flecks client v${version} loading runtime...`);
const config = window[Symbol.for('@flecks/web.config')];
const debug = D(config['@flecks/core']?.id || 'flecks');
debug('loading runtime...');
const {default: loader} = await __non_webpack_import__(
/* @preserve webpackChunkName: "flecks-runtime" */
'@flecks/web/runtime',
);
const runtime = await loader(progress.update.bind(progress));
progress.finish();
debug('starting client...');
const flecks = new Flecks(runtime);
window.flecks = flecks;
try {
await flecks.up('@flecks/web/client.up');
debug('up!');
}
catch (error) {
// eslint-disable-next-line no-console
console.error(error);
}
})();

View File

@ -1,5 +0,0 @@
export default (source) => (
source
.replace('__non_webpack_import__', 'import')
.replace('@preserve ', '')
);

View File

@ -1,39 +0,0 @@
import {D} from '@flecks/core';
const debug = D('@flecks/web/progress');
export default class Progress {
constructor(window) {
this.finished = 0;
this.progress = window.document.createElement('div');
const {style} = this.progress;
style.backgroundColor = '#004488';
style.border = 0;
style.display = 'none';
style.height = '0.17em';
style.left = 0;
style.margin = 0;
style.padding = 0;
style.position = 'absolute';
style.top = 0;
style.transition = '1s width, 0.5s opacity';
setTimeout(() => {
style.display = 'block';
}, 600);
this.progress.style.width = '0%';
this.progress.value = 0;
window.document.body.prepend(this.progress);
}
update(total, path) {
this.finished += 1;
debug('loaded %s (%d/%d)', path, this.finished, total);
this.progress.style.width = `${100 * (this.finished / total)}%`;
}
finish() {
this.progress.style.opacity = 0;
}
}

View File

@ -0,0 +1,67 @@
import {D, Flecks} from '@flecks/core';
// eslint-disable-next-line import/no-extraneous-dependencies
const {version} = require('@flecks/web/package.json');
(async () => {
// eslint-disable-next-line no-console
console.log(`flecks client v${version} loading runtime...`);
const config = window[Symbol.for('@flecks/web.config')];
const debug = D((config['@flecks/core'] && config['@flecks/core'].id) || 'flecks');
class Progress {
constructor(window) {
this.finished = 0;
this.progress = window.document.createElement('div');
const {style} = this.progress;
style.backgroundColor = '#004488';
style.border = 0;
style.display = 'none';
style.height = '0.17em';
style.left = 0;
style.margin = 0;
style.padding = 0;
style.position = 'absolute';
style.top = 0;
style.transition = '1s width, 0.5s opacity';
setTimeout(() => {
style.display = 'block';
}, 600);
this.progress.style.width = '0%';
this.progress.value = 0;
window.document.body.prepend(this.progress);
}
update(total, path) {
this.finished += 1;
debug('loaded %s (%d/%d)', path, this.finished, total);
this.progress.style.width = `${100 * (this.finished / total)}%`;
}
finish() {
this.progress.style.opacity = 0;
}
}
const progress = new Progress(window);
debug('loading runtime...');
// eslint-disable-next-line import/no-extraneous-dependencies
const {default: loader} = await import(
/* webpackChunkName: "flecks-runtime" */
'@flecks/web/runtime'
);
const runtime = await loader(progress.update.bind(progress));
progress.finish();
debug('starting client...');
const flecks = new Flecks(runtime);
window.flecks = flecks;
try {
await flecks.up('@flecks/web/client.up');
window.document.querySelector('#root').style.display = 'block';
debug('up!');
}
catch (error) {
// eslint-disable-next-line no-console
console.error(error);
}
})();

View File

@ -20,7 +20,7 @@ module.exports = async (flecks) => {
// Build configuration.
const build = async () => {
const root = await realpath(
dirname(R.resolve(join(flecks.resolve('@flecks/web'), 'entry.js'))),
dirname(R.resolve(join(flecks.resolve('@flecks/web'), 'package.json'))),
);
return (neutrino) => {
const {config, options} = neutrino;
@ -33,7 +33,7 @@ module.exports = async (flecks) => {
}]);
// Entrypoints.
const {output: originalOutput} = options;
options.mains.index = join(root, 'entry');
options.mains.index = join(root, 'server', 'build', 'entry');
options.mains.tests = {
entry: join(root, 'server', 'build', 'tests'),
title: 'Testbed',

View File

@ -42,9 +42,6 @@ module.exports = async (flecks) => {
)
.filter((filename) => !!filename);
const runtime = await realpath(R.resolve(join(httpFlecks.resolve('@flecks/web'), 'runtime')));
const fullresolve = (fleck, path) => realpath(R.resolve(join(httpFlecks.resolve(fleck), path)));
const entry = await fullresolve('@flecks/web', 'entry');
const importLoader = await fullresolve('@flecks/web', 'import-loader');
const tests = await realpath(R.resolve(
join(httpFlecks.resolve('@flecks/web'), 'server', 'build', 'tests'),
));
@ -83,6 +80,7 @@ module.exports = async (flecks) => {
source.push('}');
source.push('');
// Create runtime.
console.log(source);
config.module
.rule(runtime)
.test(runtime)
@ -94,12 +92,6 @@ module.exports = async (flecks) => {
config.resolve.alias
.set('@flecks/web/runtime$', runtime);
flecks.runtimeCompiler(httpFlecks.resolver, 'http', neutrino);
// Handle runtime import.
config.module
.rule(entry)
.test(entry)
.use('entry/http')
.loader(importLoader);
// Aliases.
const aliases = httpFlecks.aliases();
if (Object.keys(aliases).length > 0) {