2024-02-03 20:31:35 -06:00
|
|
|
const {externals} = require('@flecks/build/src/server');
|
2022-02-25 04:58:08 -06:00
|
|
|
|
2024-01-25 06:42:31 -06:00
|
|
|
const D = require('@flecks/core/build/debug');
|
|
|
|
|
|
|
|
const debug = D('@flecks/server/build/runtime');
|
|
|
|
|
2023-11-30 21:41:42 -06:00
|
|
|
module.exports = async (config, env, argv, flecks) => {
|
2024-01-22 09:16:07 -06:00
|
|
|
const runtimePath = await flecks.resolver.resolve('@flecks/server/runtime');
|
2023-11-30 21:41:42 -06:00
|
|
|
// Inject flecks configuration.
|
2024-01-16 00:28:20 -06:00
|
|
|
const paths = Object.keys(flecks.flecks);
|
|
|
|
const resolvedPaths = (await Promise.all(
|
|
|
|
paths.map(async (path) => [path, await flecks.resolver.resolve(path)]),
|
|
|
|
))
|
|
|
|
.filter(([, resolved]) => resolved)
|
|
|
|
.map(([path]) => path);
|
2024-01-22 09:16:07 -06:00
|
|
|
const runtime = {
|
|
|
|
config: JSON.stringify(flecks.config),
|
|
|
|
loadFlecks: [
|
|
|
|
'async () => (',
|
|
|
|
' Object.fromEntries(',
|
|
|
|
' (await Promise.all(',
|
|
|
|
' [',
|
|
|
|
...resolvedPaths.map((path) => [
|
|
|
|
' (async () => {',
|
|
|
|
' try {',
|
|
|
|
` return ['${path}', await import('${path}')];`,
|
|
|
|
' }',
|
|
|
|
' catch (error) {',
|
|
|
|
' if (!error.message.startsWith("Cannot find module")) {',
|
|
|
|
' throw error;',
|
|
|
|
' }',
|
|
|
|
' }',
|
|
|
|
' })(),',
|
|
|
|
]).flat(),
|
|
|
|
' ],',
|
|
|
|
' ))',
|
|
|
|
' .filter((entry) => entry),',
|
|
|
|
' )',
|
|
|
|
')',
|
|
|
|
].join('\n'),
|
|
|
|
...await flecks.invokeAsync('@flecks/server.runtime'),
|
|
|
|
};
|
|
|
|
const runtimeString = `{${
|
|
|
|
Object.entries(runtime)
|
|
|
|
.map(([key, value]) => `"${key}": ${value}`).join(', ')
|
|
|
|
}}`;
|
2023-11-30 21:41:42 -06:00
|
|
|
const source = [
|
|
|
|
"process.env.FLECKS_CORE_BUILD_TARGET = 'server';",
|
2024-01-22 09:16:07 -06:00
|
|
|
`module.exports = (async () => (${runtimeString}))();`,
|
2023-11-30 21:41:42 -06:00
|
|
|
];
|
|
|
|
// HMR.
|
|
|
|
source.push('if (module.hot) {');
|
|
|
|
// Keep HMR junk out of our output path.
|
2024-01-27 04:01:31 -06:00
|
|
|
source.push(' const {glob} = require("glob");');
|
2023-11-30 21:41:42 -06:00
|
|
|
source.push(' const {join} = require("path");');
|
2024-01-27 04:01:31 -06:00
|
|
|
source.push(' const {unlink} = require("fs/promises");');
|
2023-11-30 21:41:42 -06:00
|
|
|
source.push(' let previousHash = __webpack_hash__;');
|
2024-01-27 04:01:31 -06:00
|
|
|
source.push(' module.hot.addStatusHandler(async (status) => {');
|
2023-11-30 21:41:42 -06:00
|
|
|
source.push(' if ("idle" === status) {');
|
2024-01-27 04:01:31 -06:00
|
|
|
source.push(' const disposing = await glob(');
|
2023-11-30 21:41:42 -06:00
|
|
|
source.push(` join('${config.output.path}', \`*\${previousHash}.hot-update.*\`),`);
|
|
|
|
source.push(' );');
|
2024-01-27 04:01:31 -06:00
|
|
|
source.push(' await Promise.all(disposing.map((filename) => unlink(filename)));');
|
2023-11-30 21:41:42 -06:00
|
|
|
source.push(' previousHash = __webpack_hash__;');
|
|
|
|
source.push(' }');
|
|
|
|
source.push(' });');
|
|
|
|
// Hooks for each fleck.
|
2024-01-16 00:28:20 -06:00
|
|
|
resolvedPaths.forEach((path) => {
|
2023-11-30 21:41:42 -06:00
|
|
|
source.push(` module.hot.accept('${path}', async () => {`);
|
|
|
|
source.push(` global.flecks.refresh('${path}', require('${path}'));`);
|
|
|
|
source.push(` global.flecks.invoke('@flecks/core.hmr', '${path}');`);
|
2022-02-25 04:58:08 -06:00
|
|
|
source.push(' });');
|
2023-11-30 21:41:42 -06:00
|
|
|
});
|
|
|
|
source.push('}');
|
|
|
|
// Create runtime.
|
|
|
|
config.module.rules.push(
|
|
|
|
{
|
2024-01-22 09:16:07 -06:00
|
|
|
test: runtimePath,
|
2023-11-30 21:41:42 -06:00
|
|
|
use: [
|
|
|
|
{
|
2024-01-22 09:16:07 -06:00
|
|
|
loader: runtimePath,
|
2023-11-30 21:41:42 -06:00
|
|
|
options: {
|
|
|
|
source: source.join('\n'),
|
|
|
|
},
|
|
|
|
},
|
|
|
|
],
|
|
|
|
},
|
|
|
|
);
|
|
|
|
const allowlist = [
|
|
|
|
'@flecks/server/entry',
|
|
|
|
'@flecks/server/runtime',
|
|
|
|
/^@babel\/runtime\/helpers\/esm/,
|
|
|
|
];
|
2024-01-22 09:16:07 -06:00
|
|
|
config.resolve.alias['@flecks/server/runtime$'] = runtimePath;
|
2024-01-25 06:42:31 -06:00
|
|
|
Object.entries(flecks.resolver.aliases).forEach(([path, request]) => {
|
|
|
|
debug('server runtime de-externalized %s, alias: %s', path, request);
|
|
|
|
allowlist.push(new RegExp(`^${path}`));
|
|
|
|
});
|
|
|
|
// Stubs.
|
|
|
|
flecks.stubs.forEach((stub) => {
|
|
|
|
config.resolve.alias[stub] = false;
|
|
|
|
});
|
|
|
|
await flecks.runtimeCompiler('server', config);
|
2023-11-30 21:41:42 -06:00
|
|
|
// Rewrite to signals for HMR.
|
|
|
|
if ('production' !== argv.mode) {
|
2024-01-22 09:16:07 -06:00
|
|
|
allowlist.push(/^webpack\/hot\/signal/);
|
2023-11-30 21:41:42 -06:00
|
|
|
}
|
|
|
|
// Externalize the rest.
|
2024-02-03 20:31:35 -06:00
|
|
|
config.externals = await externals({
|
|
|
|
additionalModuleDirs: flecks.resolver.modules,
|
|
|
|
allowlist,
|
|
|
|
importType: 'commonjs',
|
|
|
|
});
|
2022-02-25 04:58:08 -06:00
|
|
|
};
|