refactor: build + dll
This commit is contained in:
parent
fa092bd512
commit
0f8d6c0551
|
@ -1,5 +1,5 @@
|
|||
/* eslint-disable import/first */
|
||||
require('source-map-support/register');
|
||||
import 'source-map-support/register';
|
||||
|
||||
if ('production' !== process.env.NODE_ENV) {
|
||||
try {
|
||||
|
|
|
@ -8,6 +8,7 @@ module.exports = async (flecks) => {
|
|||
const config = await require('@flecks/fleck/server/build/fleck.neutrinorc')(flecks);
|
||||
config.use.push(({config}) => {
|
||||
config.entryPoints.delete('server/build/template');
|
||||
config.entryPoints.delete('server/build/tests');
|
||||
config.externals(nodeExternals({
|
||||
allowlist: ['mocha/mocha.css'],
|
||||
importType: 'umd',
|
||||
|
@ -29,6 +30,10 @@ module.exports = async (flecks) => {
|
|||
from: 'src/server/build/template.ejs',
|
||||
to: 'server/build/template.ejs',
|
||||
},
|
||||
{
|
||||
from: 'src/server/build/tests.js',
|
||||
to: 'server/build/tests.js',
|
||||
},
|
||||
],
|
||||
}),
|
||||
);
|
||||
|
|
|
@ -19,8 +19,6 @@
|
|||
},
|
||||
"files": [
|
||||
"build",
|
||||
"client/tests.js",
|
||||
"client/tests.js.map",
|
||||
"entry.js",
|
||||
"entry.js.map",
|
||||
"import-loader.js",
|
||||
|
@ -34,6 +32,10 @@
|
|||
"server/build/template.ejs",
|
||||
"server/build/http.neutrinorc.js",
|
||||
"server/build/http.neutrinorc.js.map",
|
||||
"server/build/http-vendor.neutrinorc.js",
|
||||
"server/build/http-vendor.neutrinorc.js.map",
|
||||
"server/build/tests.js",
|
||||
"server/build/tests.js.map",
|
||||
"src",
|
||||
"tests.js",
|
||||
"tests.js.map"
|
||||
|
@ -48,7 +50,9 @@
|
|||
"@neutrinojs/html-template": "^9.5.0",
|
||||
"@neutrinojs/image-loader": "^9.5.0",
|
||||
"@neutrinojs/style-loader": "^9.5.0",
|
||||
"add-asset-html-webpack-plugin": "^5.0.1",
|
||||
"autoprefixer": "^9.8.6",
|
||||
"before-build-webpack": "^0.2.12",
|
||||
"compression": "^1.7.4",
|
||||
"express": "^4.17.1",
|
||||
"glob": "^7.2.0",
|
||||
|
|
|
@ -1,13 +0,0 @@
|
|||
const mochaDiv = window.document.createElement('div');
|
||||
mochaDiv.id = 'mocha';
|
||||
window.document.body.appendChild(mochaDiv);
|
||||
|
||||
require('mocha/mocha.css').use();
|
||||
const mocha = require('mocha/mocha');
|
||||
|
||||
mocha.setup('bdd');
|
||||
|
||||
// eslint-disable-next-line import/no-unresolved
|
||||
__non_webpack_require__('@flecks/http/tests');
|
||||
|
||||
mocha.run();
|
76
packages/http/src/server/build/http-vendor.neutrinorc.js
Normal file
76
packages/http/src/server/build/http-vendor.neutrinorc.js
Normal file
|
@ -0,0 +1,76 @@
|
|||
const {join} = require('path');
|
||||
|
||||
const {require: R} = require('@flecks/core/server');
|
||||
|
||||
const {
|
||||
FLECKS_CORE_ROOT = process.cwd(),
|
||||
} = process.env;
|
||||
|
||||
module.exports = async (flecks) => {
|
||||
const config = {
|
||||
options: {
|
||||
output: join(
|
||||
FLECKS_CORE_ROOT,
|
||||
'node_modules',
|
||||
'.cache',
|
||||
'flecks',
|
||||
),
|
||||
root: FLECKS_CORE_ROOT,
|
||||
},
|
||||
use: [
|
||||
({config, options}) => {
|
||||
const dll = flecks.get('@flecks/http/server.dll');
|
||||
if (dll.length > 0) {
|
||||
const isProduction = 'production' === config.get('mode');
|
||||
// Build the library and manifest.
|
||||
config.context(options.root);
|
||||
const entries = config.entry('index').clear();
|
||||
dll.forEach((module) => {
|
||||
entries.add(module);
|
||||
});
|
||||
config
|
||||
.plugin('dll')
|
||||
.use(
|
||||
R.resolve('webpack/lib/DllPlugin'),
|
||||
[
|
||||
{
|
||||
context: options.root,
|
||||
path: join(options.output, 'http-vendor.manifest.json'),
|
||||
name: 'flecks_http_vendor',
|
||||
},
|
||||
],
|
||||
);
|
||||
// Output.
|
||||
config
|
||||
.devtool(isProduction ? 'source-map' : 'cheap-module-source-map');
|
||||
config.output
|
||||
.path(options.output)
|
||||
.library('flecks_http_vendor')
|
||||
.filename('http-vendor.js');
|
||||
config.node
|
||||
.set('fs', 'empty');
|
||||
|
||||
// Resolution.
|
||||
config.resolve.extensions
|
||||
.merge([
|
||||
'.wasm',
|
||||
...options.extensions.map((ext) => `.${ext}`),
|
||||
'.json',
|
||||
]);
|
||||
config.module
|
||||
.rule('mjs')
|
||||
.test(/\.mjs$/)
|
||||
.include
|
||||
.add(/node_modules/)
|
||||
.end()
|
||||
.type('javascript/auto');
|
||||
config.resolve.modules
|
||||
.merge([join(FLECKS_CORE_ROOT, 'node_modules')]);
|
||||
// Reporting.
|
||||
config.stats(flecks.get('@flecks/http/server.stats'));
|
||||
}
|
||||
},
|
||||
],
|
||||
};
|
||||
return config;
|
||||
};
|
|
@ -10,6 +10,7 @@ const {EnvironmentPlugin} = require('webpack');
|
|||
|
||||
const devServer = require('./dev-server');
|
||||
const runtime = require('./runtime');
|
||||
const WaitForManifestPlugin = require('./wait-for-manifest');
|
||||
|
||||
const {
|
||||
FLECKS_CORE_ROOT = process.cwd(),
|
||||
|
@ -34,7 +35,7 @@ module.exports = async (flecks) => {
|
|||
const {output: originalOutput} = options;
|
||||
options.mains.index = join(root, 'entry');
|
||||
options.mains.tests = {
|
||||
entry: join(root, 'client', 'tests'),
|
||||
entry: join(root, 'server', 'build', 'tests'),
|
||||
title: 'Testbed',
|
||||
};
|
||||
options.output = join(originalOutput, flecks.get('@flecks/http/server.output'));
|
||||
|
@ -111,7 +112,7 @@ module.exports = async (flecks) => {
|
|||
},
|
||||
})
|
||||
.runtimeChunk('single');
|
||||
// Outputs.
|
||||
// Output.
|
||||
config.output
|
||||
.chunkFilename(isProduction ? 'assets/[name].[contenthash:8].js' : 'assets/[name].js')
|
||||
.path(options.output)
|
||||
|
@ -141,6 +142,40 @@ module.exports = async (flecks) => {
|
|||
config
|
||||
.plugin('inline-chunks')
|
||||
.use(InlineChunkHtmlPlugin, [HtmlWebpackPlugin, [/^assets\/index(\.[^.]*)?\.js$/]]);
|
||||
const dll = flecks.get('@flecks/http/server.dll');
|
||||
if (!isProduction && dll.length > 0) {
|
||||
const manifest = join(
|
||||
FLECKS_CORE_ROOT,
|
||||
'node_modules',
|
||||
'.cache',
|
||||
'flecks',
|
||||
'http-vendor',
|
||||
);
|
||||
config
|
||||
.plugin('wait-for-manifest')
|
||||
.use(WaitForManifestPlugin, [`${manifest}.manifest.json`]);
|
||||
config
|
||||
.plugin('dll')
|
||||
.use(
|
||||
R.resolve('webpack/lib/DllReferencePlugin'),
|
||||
[
|
||||
{
|
||||
context: FLECKS_CORE_ROOT,
|
||||
manifest: `${manifest}.manifest.json`,
|
||||
},
|
||||
],
|
||||
);
|
||||
config
|
||||
.plugin('include-dll')
|
||||
.use(
|
||||
R.resolve('add-asset-html-webpack-plugin'),
|
||||
[
|
||||
{
|
||||
filepath: `${manifest}.js`,
|
||||
},
|
||||
],
|
||||
);
|
||||
}
|
||||
};
|
||||
};
|
||||
// Neutrino configuration.
|
||||
|
|
|
@ -1,4 +1,4 @@
|
|||
const {realpath, stat} = require('fs/promises');
|
||||
const {readFile, realpath, stat} = require('fs/promises');
|
||||
const {
|
||||
dirname,
|
||||
join,
|
||||
|
@ -45,10 +45,14 @@ module.exports = async (flecks) => {
|
|||
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(httpFlecks.resolve('@flecks/http'), 'tests')));
|
||||
const tests = await realpath(R.resolve(
|
||||
join(httpFlecks.resolve('@flecks/http'), 'server', 'build', 'tests'),
|
||||
));
|
||||
const testsSource = (await readFile(tests)).toString();
|
||||
return (neutrino) => {
|
||||
const {config} = neutrino;
|
||||
const {resolver} = httpFlecks;
|
||||
const isProduction = 'production' === config.get('mode');
|
||||
const paths = Object.entries(resolver);
|
||||
const source = [
|
||||
'module.exports = (update) => (async () => ({',
|
||||
|
@ -111,45 +115,55 @@ module.exports = async (flecks) => {
|
|||
entries.add(style);
|
||||
});
|
||||
// Tests.
|
||||
const testPaths = [];
|
||||
roots.forEach(([fleck, root]) => {
|
||||
testPaths.push(...(
|
||||
glob.sync(join(root, 'test/*.js'))
|
||||
.map((path) => [fleck, path])
|
||||
));
|
||||
for (let i = 0; i < httpFlecks.platforms.length; ++i) {
|
||||
testPaths.push(
|
||||
...(
|
||||
glob.sync(join(root, `test/platforms/${httpFlecks.platforms[i]}/*.js`))
|
||||
.map((path) => [fleck, path])
|
||||
),
|
||||
);
|
||||
}
|
||||
});
|
||||
// Test entrypoint.
|
||||
if (testPaths.length > 0) {
|
||||
const testEntry = config.entry('test').clear();
|
||||
testPaths.forEach(([, path]) => testEntry.add(path));
|
||||
}
|
||||
config.module
|
||||
.rule(tests)
|
||||
.test(tests)
|
||||
.use('runtime/test')
|
||||
.loader(runtime)
|
||||
.options({
|
||||
source: Object.entries(
|
||||
testPaths
|
||||
.reduce(
|
||||
(r, [fleck, path]) => ({
|
||||
...r,
|
||||
[fleck]: [...(r[fleck] || []), `require('${path}');`],
|
||||
}),
|
||||
{},
|
||||
if (!isProduction) {
|
||||
const testPaths = [];
|
||||
roots.forEach(([fleck, root]) => {
|
||||
testPaths.push(...(
|
||||
glob.sync(join(root, 'test/*.js'))
|
||||
.map((path) => [fleck, path])
|
||||
));
|
||||
for (let i = 0; i < httpFlecks.platforms.length; ++i) {
|
||||
testPaths.push(
|
||||
...(
|
||||
glob.sync(join(root, `test/platforms/${httpFlecks.platforms[i]}/*.js`))
|
||||
.map((path) => [fleck, path])
|
||||
),
|
||||
)
|
||||
.map(
|
||||
([original, paths]) => `describe('${original}', () => { ${paths.join(' ')} });`,
|
||||
).join(''),
|
||||
);
|
||||
}
|
||||
});
|
||||
config.module
|
||||
.rule(tests)
|
||||
.test(tests)
|
||||
.use('runtime/test')
|
||||
.loader(runtime)
|
||||
.options({
|
||||
source: testsSource.replace(
|
||||
"await import('@flecks/http/tests');",
|
||||
[
|
||||
'const tests = {};',
|
||||
Object.entries(
|
||||
testPaths
|
||||
.reduce(
|
||||
(r, [fleck, path]) => ({
|
||||
...r,
|
||||
[fleck]: [...(r[fleck] || []), `require('${path}');`],
|
||||
}),
|
||||
{},
|
||||
),
|
||||
)
|
||||
.map(
|
||||
([original, paths]) => (
|
||||
[
|
||||
`describe('${original}', () => {`,
|
||||
` ${paths.join('\n ')}`,
|
||||
'});',
|
||||
].join('\n')
|
||||
),
|
||||
).join('\n'),
|
||||
'await Promise.all(Object.values(tests));',
|
||||
].join('\n'),
|
||||
),
|
||||
});
|
||||
}
|
||||
};
|
||||
};
|
||||
|
|
16
packages/http/src/server/build/tests.js
Normal file
16
packages/http/src/server/build/tests.js
Normal file
|
@ -0,0 +1,16 @@
|
|||
const mochaDiv = window.document.createElement('div');
|
||||
mochaDiv.id = 'mocha';
|
||||
window.document.body.appendChild(mochaDiv);
|
||||
|
||||
(async () => {
|
||||
await import('mocha/mocha.css');
|
||||
const mocha = await import('mocha/mocha');
|
||||
|
||||
mocha.setup('bdd');
|
||||
|
||||
// eslint-disable-next-line import/no-extraneous-dependencies, import/no-unresolved
|
||||
await import('@flecks/http/tests');
|
||||
|
||||
mocha.run();
|
||||
|
||||
})();
|
31
packages/http/src/server/build/wait-for-manifest.js
Normal file
31
packages/http/src/server/build/wait-for-manifest.js
Normal file
|
@ -0,0 +1,31 @@
|
|||
const {stat} = require('fs/promises');
|
||||
|
||||
const WebpackBeforeBuildPlugin = require('before-build-webpack');
|
||||
|
||||
class WaitForManifestPlugin extends WebpackBeforeBuildPlugin {
|
||||
|
||||
constructor(manifest) {
|
||||
|
||||
super(async (stats, callback) => {
|
||||
// eslint-disable-next-line no-constant-condition
|
||||
while (true) {
|
||||
try {
|
||||
// eslint-disable-next-line no-await-in-loop
|
||||
await stat(manifest);
|
||||
// eslint-disable-next-line no-await-in-loop
|
||||
await new Promise((resolve) => setTimeout(resolve, 100));
|
||||
callback();
|
||||
break;
|
||||
}
|
||||
catch (error) {
|
||||
// eslint-disable-next-line no-await-in-loop
|
||||
await new Promise((resolve) => setTimeout(resolve, 1000));
|
||||
}
|
||||
}
|
||||
}, ['beforeCompile']);
|
||||
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
module.exports = WaitForManifestPlugin;
|
|
@ -68,6 +68,13 @@ export default {
|
|||
delete neutrinoConfigs.http;
|
||||
return;
|
||||
}
|
||||
// Only build vendor in dev.
|
||||
if (neutrinoConfigs['http-vendor']) {
|
||||
if (process.argv.find((arg) => 'production' === arg)) {
|
||||
// eslint-disable-next-line no-param-reassign
|
||||
delete neutrinoConfigs['http-vendor'];
|
||||
}
|
||||
}
|
||||
// Bail if there's no http build.
|
||||
if (!neutrinoConfigs.http) {
|
||||
return;
|
||||
|
@ -130,6 +137,10 @@ export default {
|
|||
colors: true,
|
||||
modules: false,
|
||||
},
|
||||
/**
|
||||
* Modules to externalize using `webpack.DllPlugin`.
|
||||
*/
|
||||
dll: [],
|
||||
/**
|
||||
* Force building http target even if there's a fleck target.
|
||||
*/
|
||||
|
@ -171,7 +182,10 @@ export default {
|
|||
debug('bootstrapped');
|
||||
flecks.set('$flecks/http.flecks', httpFlecks);
|
||||
},
|
||||
'@flecks/core.targets': () => ['http'],
|
||||
'@flecks/core.targets': (flecks) => [
|
||||
'http',
|
||||
...(flecks.get('@flecks/http/server.dll').length > 0 ? ['http-vendor'] : []),
|
||||
],
|
||||
'@flecks/http.routes': (flecks) => [
|
||||
{
|
||||
method: 'get',
|
||||
|
|
|
@ -143,10 +143,7 @@ module.exports = async (flecks) => {
|
|||
|
||||
// Give the resolver a helping hand.
|
||||
config.use.push(({config}) => {
|
||||
config.resolve.modules.merge([
|
||||
join(FLECKS_CORE_ROOT, 'node_modules'),
|
||||
'node_modules',
|
||||
]);
|
||||
config.resolve.modules.merge([join(FLECKS_CORE_ROOT, 'node_modules')]);
|
||||
});
|
||||
|
||||
return config;
|
||||
|
|
Loading…
Reference in New Issue
Block a user