refactor: build
This commit is contained in:
parent
668304408d
commit
9f08899cb5
|
@ -4,19 +4,20 @@ const {join} = require('path');
|
||||||
const airbnb = require('@neutrinojs/airbnb');
|
const airbnb = require('@neutrinojs/airbnb');
|
||||||
const banner = require('@neutrinojs/banner');
|
const banner = require('@neutrinojs/banner');
|
||||||
const copy = require('@neutrinojs/copy');
|
const copy = require('@neutrinojs/copy');
|
||||||
const node = require('@neutrinojs/node');
|
|
||||||
const glob = require('glob');
|
const glob = require('glob');
|
||||||
|
|
||||||
|
const fleck = require('../src/bootstrap/fleck');
|
||||||
|
|
||||||
const {
|
const {
|
||||||
FLECKS_CORE_ROOT = process.cwd(),
|
FLECKS_CORE_ROOT = process.cwd(),
|
||||||
} = process.env;
|
} = process.env;
|
||||||
|
|
||||||
module.exports = require('../src/bootstrap/fleck.neutrinorc');
|
const config = require('../src/bootstrap/fleck.neutrinorc');
|
||||||
|
|
||||||
// Dotfiles.
|
// Dotfiles.
|
||||||
module.exports.use.push((neutrino) => {
|
config.use.push(({config}) => {
|
||||||
['eslintrc', 'eslint.defaults'].forEach((filename) => {
|
['eslintrc', 'eslint.defaults'].forEach((filename) => {
|
||||||
neutrino.config
|
config
|
||||||
.entry(`server/build/.${filename}`)
|
.entry(`server/build/.${filename}`)
|
||||||
.clear()
|
.clear()
|
||||||
.add(`./src/server/build/${filename}`);
|
.add(`./src/server/build/${filename}`);
|
||||||
|
@ -24,23 +25,19 @@ module.exports.use.push((neutrino) => {
|
||||||
});
|
});
|
||||||
|
|
||||||
// Tests.
|
// Tests.
|
||||||
module.exports.use.push((neutrino) => {
|
config.use.push(({config}) => {
|
||||||
// Test entrypoint.
|
// Test entrypoint.
|
||||||
const testPaths = glob.sync(join(FLECKS_CORE_ROOT, 'test/*.js'));
|
const testPaths = glob.sync(join(FLECKS_CORE_ROOT, 'test/*.js'));
|
||||||
testPaths.push(...glob.sync(join(FLECKS_CORE_ROOT, `test/platforms/server/*.js`)));
|
testPaths.push(...glob.sync(join(FLECKS_CORE_ROOT, `test/platforms/server/*.js`)));
|
||||||
if (testPaths.length > 0) {
|
if (testPaths.length > 0) {
|
||||||
const testEntry = neutrino.config.entry('test').clear();
|
const testEntry = config.entry('test').clear();
|
||||||
testPaths.forEach((path) => testEntry.add(path));
|
testPaths.forEach((path) => testEntry.add(path));
|
||||||
}
|
}
|
||||||
});
|
});
|
||||||
|
|
||||||
module.exports.use.unshift((neutrino) => {
|
config.use.unshift(fleck());
|
||||||
neutrino.config.plugins.delete('start-server');
|
|
||||||
});
|
|
||||||
|
|
||||||
module.exports.use.unshift(node({clean: {cleanStaleWebpackAssets: false}}));
|
config.use.unshift(
|
||||||
|
|
||||||
module.exports.use.unshift(
|
|
||||||
airbnb({
|
airbnb({
|
||||||
eslint: {
|
eslint: {
|
||||||
baseConfig: {
|
baseConfig: {
|
||||||
|
@ -53,14 +50,14 @@ module.exports.use.unshift(
|
||||||
}),
|
}),
|
||||||
);
|
);
|
||||||
|
|
||||||
module.exports.use.push(banner({
|
config.use.push(banner({
|
||||||
banner: '#!/usr/bin/env node',
|
banner: '#!/usr/bin/env node',
|
||||||
include: /^cli\.js$/,
|
include: /^cli\.js$/,
|
||||||
pluginId: 'shebang',
|
pluginId: 'shebang',
|
||||||
raw: true,
|
raw: true,
|
||||||
}))
|
}))
|
||||||
|
|
||||||
module.exports.use.push(({config}) => {
|
config.use.push(({config}) => {
|
||||||
config
|
config
|
||||||
.plugin('executable')
|
.plugin('executable')
|
||||||
.use(class Executable {
|
.use(class Executable {
|
||||||
|
@ -76,3 +73,5 @@ module.exports.use.push(({config}) => {
|
||||||
|
|
||||||
});
|
});
|
||||||
});
|
});
|
||||||
|
|
||||||
|
module.exports = config;
|
||||||
|
|
|
@ -54,9 +54,10 @@
|
||||||
"@babel/preset-env": "^7.12.11",
|
"@babel/preset-env": "^7.12.11",
|
||||||
"@babel/register": "^7.12.10",
|
"@babel/register": "^7.12.10",
|
||||||
"@neutrinojs/airbnb": "^9.4.0",
|
"@neutrinojs/airbnb": "^9.4.0",
|
||||||
|
"@neutrinojs/banner": "^9.4.0",
|
||||||
|
"@neutrinojs/clean": "^9.5.0",
|
||||||
"@neutrinojs/compile-loader": "^9.5.0",
|
"@neutrinojs/compile-loader": "^9.5.0",
|
||||||
"@neutrinojs/copy": "^9.4.0",
|
"@neutrinojs/copy": "^9.4.0",
|
||||||
"@neutrinojs/node": "^9.1.0",
|
|
||||||
"babel-merge": "^3.0.0",
|
"babel-merge": "^3.0.0",
|
||||||
"babel-plugin-prepend": "^1.0.2",
|
"babel-plugin-prepend": "^1.0.2",
|
||||||
"chai": "4.2.0",
|
"chai": "4.2.0",
|
||||||
|
@ -80,7 +81,6 @@
|
||||||
"webpack-node-externals": "2.5.2"
|
"webpack-node-externals": "2.5.2"
|
||||||
},
|
},
|
||||||
"devDependencies": {
|
"devDependencies": {
|
||||||
"@neutrinojs/banner": "^9.4.0",
|
|
||||||
"glob": "^7.2.0",
|
"glob": "^7.2.0",
|
||||||
"mocha": "^8.3.2"
|
"mocha": "^8.3.2"
|
||||||
}
|
}
|
||||||
|
|
|
@ -30,19 +30,19 @@ const resolver = (source) => (path) => {
|
||||||
}
|
}
|
||||||
};
|
};
|
||||||
|
|
||||||
module.exports = () => (neutrino) => {
|
module.exports = () => ({config, options}) => {
|
||||||
const {packageJson: {name, files = []}, source} = neutrino.options;
|
const {packageJson: {name, files = []}, source} = options;
|
||||||
// index is not taken for granted.
|
// index is not taken for granted.
|
||||||
neutrino.config.entryPoints.delete('index');
|
config.entryPoints.delete('index');
|
||||||
// Alias this package.
|
// Alias this package.
|
||||||
neutrino.config.resolve.alias
|
config.resolve.alias
|
||||||
.set(name, join(FLECKS_CORE_ROOT, 'src'));
|
.set(name, join(FLECKS_CORE_ROOT, 'src'));
|
||||||
// Calculate entry points from `files`.
|
// Calculate entry points from `files`.
|
||||||
files
|
files
|
||||||
.filter(resolver(source))
|
.filter(resolver(source))
|
||||||
.forEach((file) => {
|
.forEach((file) => {
|
||||||
const trimmed = join(dirname(file), basename(file, extname(file)));
|
const trimmed = join(dirname(file), basename(file, extname(file)));
|
||||||
neutrino.config
|
config
|
||||||
.entry(trimmed)
|
.entry(trimmed)
|
||||||
.clear()
|
.clear()
|
||||||
.add(`./src/${trimmed}`);
|
.add(`./src/${trimmed}`);
|
||||||
|
|
|
@ -1,11 +1,63 @@
|
||||||
|
const banner = require('@neutrinojs/banner');
|
||||||
|
const clean = require('@neutrinojs/clean');
|
||||||
|
const compileLoader = require('@neutrinojs/compile-loader');
|
||||||
|
const babelMerge = require('babel-merge');
|
||||||
const nodeExternals = require('webpack-node-externals');
|
const nodeExternals = require('webpack-node-externals');
|
||||||
|
|
||||||
module.exports = () => (neutrino) => {
|
const R = require('./require');
|
||||||
const {name} = neutrino.options.packageJson;
|
|
||||||
|
module.exports = ({
|
||||||
|
babel = {},
|
||||||
|
targets = {
|
||||||
|
esmodules: true,
|
||||||
|
node: 'current',
|
||||||
|
},
|
||||||
|
} = {}) => (neutrino) => {
|
||||||
|
const {config, options} = neutrino;
|
||||||
|
const {name} = options.packageJson;
|
||||||
|
neutrino.use(
|
||||||
|
compileLoader({
|
||||||
|
include: [options.source, options.tests],
|
||||||
|
babel: babelMerge(
|
||||||
|
{
|
||||||
|
plugins: [R.resolve('@babel/plugin-syntax-dynamic-import')],
|
||||||
|
presets: [
|
||||||
|
[
|
||||||
|
R.resolve('@babel/preset-env'),
|
||||||
|
{
|
||||||
|
shippedProposals: true,
|
||||||
|
targets,
|
||||||
|
},
|
||||||
|
],
|
||||||
|
],
|
||||||
|
},
|
||||||
|
babel,
|
||||||
|
),
|
||||||
|
}),
|
||||||
|
);
|
||||||
|
neutrino.use(banner());
|
||||||
|
neutrino.use(clean({cleanStaleWebpackAssets: false}));
|
||||||
/* eslint-disable indent */
|
/* eslint-disable indent */
|
||||||
neutrino.config
|
config
|
||||||
|
.context(options.root)
|
||||||
.devtool('source-map')
|
.devtool('source-map')
|
||||||
|
.externals(nodeExternals({importType: 'umd'}))
|
||||||
.target('node')
|
.target('node')
|
||||||
|
.resolve
|
||||||
|
.extensions
|
||||||
|
.merge([
|
||||||
|
'.wasm',
|
||||||
|
...options.extensions.map((ext) => `.${ext}`),
|
||||||
|
'.json',
|
||||||
|
])
|
||||||
|
.end()
|
||||||
|
.end()
|
||||||
|
.stats({
|
||||||
|
children: false,
|
||||||
|
colors: true,
|
||||||
|
entrypoints: false,
|
||||||
|
modules: false,
|
||||||
|
})
|
||||||
.optimization
|
.optimization
|
||||||
.splitChunks(false)
|
.splitChunks(false)
|
||||||
.runtimeChunk(false)
|
.runtimeChunk(false)
|
||||||
|
@ -14,16 +66,11 @@ module.exports = () => (neutrino) => {
|
||||||
.filename('[name].js')
|
.filename('[name].js')
|
||||||
.library(name)
|
.library(name)
|
||||||
.libraryTarget('umd')
|
.libraryTarget('umd')
|
||||||
|
.path(options.output)
|
||||||
.umdNamedDefine(true)
|
.umdNamedDefine(true)
|
||||||
.end()
|
.end()
|
||||||
.node
|
.node
|
||||||
.set('__dirname', false)
|
.set('__dirname', false)
|
||||||
.set('__filename', false);
|
.set('__filename', false);
|
||||||
/* eslint-enable indent */
|
/* eslint-enable indent */
|
||||||
const options = neutrino.config.module
|
|
||||||
.rule('compile')
|
|
||||||
.use('babel')
|
|
||||||
.get('options');
|
|
||||||
options.presets[0][1].targets = {esmodules: true};
|
|
||||||
neutrino.config.externals(nodeExternals({importType: 'umd'}));
|
|
||||||
};
|
};
|
||||||
|
|
|
@ -1,7 +1,6 @@
|
||||||
const copy = require('@neutrinojs/copy');
|
const copy = require('@neutrinojs/copy');
|
||||||
|
|
||||||
const autoentry = require('./autoentry');
|
const autoentry = require('./autoentry');
|
||||||
const fleck = require('./fleck');
|
|
||||||
|
|
||||||
const {
|
const {
|
||||||
FLECKS_CORE_ROOT = process.cwd(),
|
FLECKS_CORE_ROOT = process.cwd(),
|
||||||
|
@ -32,6 +31,5 @@ module.exports = {
|
||||||
pluginId: '@flecks/core.copy',
|
pluginId: '@flecks/core.copy',
|
||||||
}),
|
}),
|
||||||
autoentry(),
|
autoentry(),
|
||||||
fleck(),
|
|
||||||
],
|
],
|
||||||
};
|
};
|
||||||
|
|
|
@ -1,7 +1,5 @@
|
||||||
import {Hooks} from './flecks';
|
import {Hooks} from './flecks';
|
||||||
|
|
||||||
export {default as autoentry} from './bootstrap/autoentry';
|
|
||||||
export {default as fleck} from './bootstrap/fleck';
|
|
||||||
export {default as compose} from './compose';
|
export {default as compose} from './compose';
|
||||||
export {default as D} from './debug';
|
export {default as D} from './debug';
|
||||||
export {default as ensureUniqueReduction} from './ensure-unique-reduction';
|
export {default as ensureUniqueReduction} from './ensure-unique-reduction';
|
||||||
|
|
|
@ -101,7 +101,6 @@ export default (program, flecks) => {
|
||||||
['-d, --no-production', 'dev build'],
|
['-d, --no-production', 'dev build'],
|
||||||
['-h, --hot', 'build with hot module reloading'],
|
['-h, --hot', 'build with hot module reloading'],
|
||||||
['-w, --watch', 'watch for changes'],
|
['-w, --watch', 'watch for changes'],
|
||||||
['-v, --verbose', 'verbose output'],
|
|
||||||
],
|
],
|
||||||
description: 'build',
|
description: 'build',
|
||||||
action: (target, opts) => {
|
action: (target, opts) => {
|
||||||
|
@ -109,7 +108,6 @@ export default (program, flecks) => {
|
||||||
hot,
|
hot,
|
||||||
production,
|
production,
|
||||||
watch,
|
watch,
|
||||||
verbose,
|
|
||||||
} = opts;
|
} = opts;
|
||||||
debug('Building...', opts);
|
debug('Building...', opts);
|
||||||
const webpackConfig = flecks.buildConfig('webpack.config.js');
|
const webpackConfig = flecks.buildConfig('webpack.config.js');
|
||||||
|
@ -118,7 +116,6 @@ export default (program, flecks) => {
|
||||||
'--colors',
|
'--colors',
|
||||||
'--config', webpackConfig,
|
'--config', webpackConfig,
|
||||||
'--mode', (production && !hot) ? 'production' : 'development',
|
'--mode', (production && !hot) ? 'production' : 'development',
|
||||||
...(verbose ? ['--stats', 'verbose'] : []),
|
|
||||||
...((watch || hot) ? ['--watch'] : []),
|
...((watch || hot) ? ['--watch'] : []),
|
||||||
];
|
];
|
||||||
return spawnWith(
|
return spawnWith(
|
||||||
|
|
|
@ -14,6 +14,7 @@ export {
|
||||||
targetNeutrinos,
|
targetNeutrinos,
|
||||||
} from './commands';
|
} from './commands';
|
||||||
export {default as Flecks} from './flecks';
|
export {default as Flecks} from './flecks';
|
||||||
|
export {default as fleck} from '../bootstrap/fleck';
|
||||||
export {default as require} from '../bootstrap/require';
|
export {default as require} from '../bootstrap/require';
|
||||||
export {JsonStream, transform} from './stream';
|
export {JsonStream, transform} from './stream';
|
||||||
|
|
||||||
|
|
|
@ -32,7 +32,6 @@
|
||||||
],
|
],
|
||||||
"dependencies": {
|
"dependencies": {
|
||||||
"@flecks/core": "^1.3.0",
|
"@flecks/core": "^1.3.0",
|
||||||
"@neutrinojs/node": "^9.4.0",
|
|
||||||
"babel-merge": "^3.0.0",
|
"babel-merge": "^3.0.0",
|
||||||
"chokidar": "^3.5.3",
|
"chokidar": "^3.5.3",
|
||||||
"debug": "^4.3.3",
|
"debug": "^4.3.3",
|
||||||
|
|
|
@ -1,8 +1,7 @@
|
||||||
const {join} = require('path');
|
const {join} = require('path');
|
||||||
|
|
||||||
const {D} = require('@flecks/core');
|
const {D} = require('@flecks/core');
|
||||||
const {Flecks} = require('@flecks/core/server');
|
const {fleck, Flecks} = require('@flecks/core/server');
|
||||||
const node = require('@neutrinojs/node');
|
|
||||||
const babelmerge = require('babel-merge');
|
const babelmerge = require('babel-merge');
|
||||||
const glob = require('glob');
|
const glob = require('glob');
|
||||||
|
|
||||||
|
@ -19,44 +18,28 @@ module.exports = (async () => {
|
||||||
const flecks = Flecks.bootstrap();
|
const flecks = Flecks.bootstrap();
|
||||||
debug('bootstrapped');
|
debug('bootstrapped');
|
||||||
|
|
||||||
const compiler = flecks.invokeFleck(
|
// Compile.
|
||||||
'@flecks/fleck.compiler',
|
const rcBabel = flecks.babel();
|
||||||
flecks.get('@flecks/fleck.compiler'),
|
debug('.flecksrc: babel: %O', rcBabel);
|
||||||
);
|
config.use.push(fleck({
|
||||||
if (compiler) {
|
babel: babelmerge(
|
||||||
config.use.unshift(compiler);
|
{configFile: flecks.buildConfig('babel.config.js')},
|
||||||
}
|
...rcBabel.map(([, babel]) => babel),
|
||||||
else {
|
),
|
||||||
config.use.unshift((neutrino) => {
|
}));
|
||||||
neutrino.config.plugins.delete('start-server');
|
|
||||||
});
|
|
||||||
const configFile = flecks.buildConfig('babel.config.js');
|
|
||||||
config.use.unshift(node({
|
|
||||||
babel: {configFile},
|
|
||||||
clean: {
|
|
||||||
cleanStaleWebpackAssets: false,
|
|
||||||
},
|
|
||||||
}));
|
|
||||||
}
|
|
||||||
|
|
||||||
// Augment the compiler with babel config from flecksrc.
|
config.use.push(({config}) => {
|
||||||
config.use.push((neutrino) => {
|
config.stats(flecks.get('@flecks/flecks/server.stats'));
|
||||||
const rcBabel = flecks.babel();
|
|
||||||
debug('.flecksrc: babel: %O', rcBabel);
|
|
||||||
neutrino.config.module
|
|
||||||
.rule('compile')
|
|
||||||
.use('babel')
|
|
||||||
.tap((options) => babelmerge(options, ...rcBabel.map(([, babel]) => babel)));
|
|
||||||
});
|
});
|
||||||
|
|
||||||
config.use.push((neutrino) => {
|
config.use.push(({config}) => {
|
||||||
// Test entrypoint.
|
// Test entrypoint.
|
||||||
const testPaths = glob.sync(join(FLECKS_CORE_ROOT, 'test/*.js'));
|
const testPaths = glob.sync(join(FLECKS_CORE_ROOT, 'test/*.js'));
|
||||||
for (let i = 0; i < flecks.platforms.length; ++i) {
|
for (let i = 0; i < flecks.platforms.length; ++i) {
|
||||||
testPaths.push(...glob.sync(join(FLECKS_CORE_ROOT, `test/platforms/${flecks.platforms[i]}/*.js`)));
|
testPaths.push(...glob.sync(join(FLECKS_CORE_ROOT, `test/platforms/${flecks.platforms[i]}/*.js`)));
|
||||||
}
|
}
|
||||||
if (testPaths.length > 0) {
|
if (testPaths.length > 0) {
|
||||||
const testEntry = neutrino.config.entry('test').clear();
|
const testEntry = config.entry('test').clear();
|
||||||
testPaths.forEach((path) => testEntry.add(path));
|
testPaths.forEach((path) => testEntry.add(path));
|
||||||
}
|
}
|
||||||
});
|
});
|
||||||
|
|
|
@ -5,6 +5,16 @@ import commands from './commands';
|
||||||
export default {
|
export default {
|
||||||
[Hooks]: {
|
[Hooks]: {
|
||||||
'@flecks/core.commands': commands,
|
'@flecks/core.commands': commands,
|
||||||
|
'@flecks/core.config': () => ({
|
||||||
|
/**
|
||||||
|
* Webpack stats configuration when building fleck target.
|
||||||
|
*/
|
||||||
|
stats: {
|
||||||
|
chunks: false,
|
||||||
|
colors: true,
|
||||||
|
modules: false,
|
||||||
|
},
|
||||||
|
}),
|
||||||
'@flecks/core.targets': () => ['fleck'],
|
'@flecks/core.targets': () => ['fleck'],
|
||||||
},
|
},
|
||||||
};
|
};
|
||||||
|
|
|
@ -30,12 +30,6 @@ export default {
|
||||||
},
|
},
|
||||||
},
|
},
|
||||||
],
|
],
|
||||||
/**
|
|
||||||
* Define neutrino compilation middleware (e.g. @neutrinojs/react).
|
|
||||||
*/
|
|
||||||
'@flecks/http/server.compiler': () => {
|
|
||||||
return require('@neutrinojs/node');
|
|
||||||
},
|
|
||||||
/**
|
/**
|
||||||
* Define middleware to run when a route is matched.
|
* Define middleware to run when a route is matched.
|
||||||
*/
|
*/
|
||||||
|
@ -66,4 +60,3 @@ export default {
|
||||||
},
|
},
|
||||||
},
|
},
|
||||||
};
|
};
|
||||||
|
|
||||||
|
|
|
@ -1,12 +1,26 @@
|
||||||
// eslint-disable-next-line import/no-extraneous-dependencies
|
// eslint-disable-next-line import/no-extraneous-dependencies
|
||||||
const copy = require('@neutrinojs/copy');
|
const copy = require('@neutrinojs/copy');
|
||||||
|
const styleLoader = require('@neutrinojs/style-loader');
|
||||||
|
const nodeExternals = require('webpack-node-externals');
|
||||||
|
|
||||||
module.exports = (async () => {
|
module.exports = (async () => {
|
||||||
// eslint-disable-next-line import/no-extraneous-dependencies, global-require
|
// eslint-disable-next-line import/no-extraneous-dependencies, global-require
|
||||||
const config = await require('@flecks/fleck/server/build/fleck.neutrinorc');
|
const config = await require('@flecks/fleck/server/build/fleck.neutrinorc');
|
||||||
config.use.push(({config}) => {
|
config.use.push(({config}) => {
|
||||||
config.entryPoints.delete('server/build/template');
|
config.entryPoints.delete('server/build/template');
|
||||||
|
config.externals(nodeExternals({
|
||||||
|
allowlist: ['mocha/mocha.css'],
|
||||||
|
importType: 'umd',
|
||||||
|
}));
|
||||||
});
|
});
|
||||||
|
config.use.push(styleLoader({
|
||||||
|
extract: {
|
||||||
|
enabled: false,
|
||||||
|
},
|
||||||
|
style: {
|
||||||
|
injectType: 'lazyStyleTag',
|
||||||
|
},
|
||||||
|
}));
|
||||||
config.use.push(
|
config.use.push(
|
||||||
copy({
|
copy({
|
||||||
copyUnmodified: true,
|
copyUnmodified: true,
|
||||||
|
|
|
@ -38,7 +38,12 @@
|
||||||
],
|
],
|
||||||
"dependencies": {
|
"dependencies": {
|
||||||
"@flecks/core": "^1.3.0",
|
"@flecks/core": "^1.3.0",
|
||||||
"@neutrinojs/web": "^9.1.0",
|
"@neutrinojs/dev-server": "^9.5.0",
|
||||||
|
"@neutrinojs/font-loader": "^9.5.0",
|
||||||
|
"@neutrinojs/html-loader": "^9.5.0",
|
||||||
|
"@neutrinojs/html-template": "^9.5.0",
|
||||||
|
"@neutrinojs/image-loader": "^9.5.0",
|
||||||
|
"@neutrinojs/style-loader": "^9.5.0",
|
||||||
"compression": "^1.7.4",
|
"compression": "^1.7.4",
|
||||||
"express": "^4.17.1",
|
"express": "^4.17.1",
|
||||||
"glob": "^7.2.0",
|
"glob": "^7.2.0",
|
||||||
|
@ -50,7 +55,8 @@
|
||||||
"react-dev-utils": "12.0.0",
|
"react-dev-utils": "12.0.0",
|
||||||
"source-map-loader": "^1.1.3",
|
"source-map-loader": "^1.1.3",
|
||||||
"webpack": "^4",
|
"webpack": "^4",
|
||||||
"webpack-dev-server": "^3.11.0"
|
"webpack-dev-server": "^3.11.0",
|
||||||
|
"webpack-node-externals": "2.5.2"
|
||||||
},
|
},
|
||||||
"devDependencies": {
|
"devDependencies": {
|
||||||
"@flecks/fleck": "^1.3.0",
|
"@flecks/fleck": "^1.3.0",
|
||||||
|
|
|
@ -1,7 +1,6 @@
|
||||||
|
const devServer = require('@neutrinojs/dev-server');
|
||||||
|
|
||||||
module.exports = (flecks) => (neutrino) => {
|
module.exports = (flecks) => (neutrino) => {
|
||||||
if ('production' === neutrino.config.get('mode')) {
|
|
||||||
return;
|
|
||||||
}
|
|
||||||
const {
|
const {
|
||||||
devHost,
|
devHost,
|
||||||
devPort,
|
devPort,
|
||||||
|
@ -9,10 +8,11 @@ module.exports = (flecks) => (neutrino) => {
|
||||||
devStats,
|
devStats,
|
||||||
port,
|
port,
|
||||||
} = flecks.get('@flecks/http/server');
|
} = flecks.get('@flecks/http/server');
|
||||||
neutrino.config.devServer
|
neutrino.use(devServer({
|
||||||
.hot(false)
|
hot: false,
|
||||||
.host(devHost)
|
host: devHost,
|
||||||
.port(devPort || (port + 1))
|
port: devPort || (port + 1),
|
||||||
.public(devPublic)
|
public: devPublic,
|
||||||
.stats(devStats);
|
stats: devStats,
|
||||||
|
}));
|
||||||
};
|
};
|
||||||
|
|
|
@ -1,12 +1,16 @@
|
||||||
|
const {dirname, join} = require('path');
|
||||||
|
const {realpath} = require('fs/promises');
|
||||||
|
|
||||||
const {D} = require('@flecks/core');
|
const {D} = require('@flecks/core');
|
||||||
const {Flecks} = require('@flecks/core/server');
|
const {Flecks, require: R} = require('@flecks/core/server');
|
||||||
const web = require('@neutrinojs/web');
|
const htmlLoader = require('@neutrinojs/html-loader');
|
||||||
|
const htmlTemplate = require('@neutrinojs/html-template');
|
||||||
|
const HtmlWebpackPlugin = require('html-webpack-plugin');
|
||||||
|
const InlineChunkHtmlPlugin = require('react-dev-utils/InlineChunkHtmlPlugin');
|
||||||
const {EnvironmentPlugin} = require('webpack');
|
const {EnvironmentPlugin} = require('webpack');
|
||||||
|
|
||||||
const devServer = require('./dev-server');
|
const devServer = require('./dev-server');
|
||||||
const outputs = require('./outputs');
|
|
||||||
const runtime = require('./runtime');
|
const runtime = require('./runtime');
|
||||||
const targets = require('./targets');
|
|
||||||
|
|
||||||
const {
|
const {
|
||||||
FLECKS_CORE_ROOT = process.cwd(),
|
FLECKS_CORE_ROOT = process.cwd(),
|
||||||
|
@ -18,6 +22,96 @@ module.exports = (async () => {
|
||||||
debug('bootstrapping flecks...');
|
debug('bootstrapping flecks...');
|
||||||
const flecks = Flecks.bootstrap();
|
const flecks = Flecks.bootstrap();
|
||||||
debug('bootstrapped');
|
debug('bootstrapped');
|
||||||
|
// Build configuration.
|
||||||
|
const build = async () => {
|
||||||
|
const root = await realpath(
|
||||||
|
dirname(R.resolve(join(flecks.resolve('@flecks/http'), 'entry.js'))),
|
||||||
|
);
|
||||||
|
return (neutrino) => {
|
||||||
|
const {config, options} = neutrino;
|
||||||
|
const isProduction = 'production' === config.get('mode');
|
||||||
|
// Environment.
|
||||||
|
config
|
||||||
|
.plugin('environment')
|
||||||
|
.use(EnvironmentPlugin, [{
|
||||||
|
FLECKS_CORE_BUILD_TARGET: 'client',
|
||||||
|
}]);
|
||||||
|
// Entrypoints.
|
||||||
|
const {output: originalOutput} = options;
|
||||||
|
options.root = root;
|
||||||
|
config.context(options.root);
|
||||||
|
options.source = '.';
|
||||||
|
options.mains.index = 'entry';
|
||||||
|
options.mains.tests = {
|
||||||
|
entry: './client/tests',
|
||||||
|
title: 'Testbed',
|
||||||
|
};
|
||||||
|
options.output = join(originalOutput, flecks.get('@flecks/http/server.output'));
|
||||||
|
neutrino.use(htmlLoader());
|
||||||
|
Object.entries(options.mains).forEach(([name, mainsConfig]) => {
|
||||||
|
const {entry, ...htmlTemplateConfig} = mainsConfig;
|
||||||
|
config.entry(name).add(entry);
|
||||||
|
neutrino.use(
|
||||||
|
htmlTemplate({
|
||||||
|
pluginId: `html-${name}`,
|
||||||
|
filename: `${name}.html`,
|
||||||
|
chunks: [name],
|
||||||
|
inject: false,
|
||||||
|
template: flecks.buildConfig('template.ejs'),
|
||||||
|
...htmlTemplateConfig,
|
||||||
|
}),
|
||||||
|
);
|
||||||
|
});
|
||||||
|
// Fold in existing source maps.
|
||||||
|
config.module
|
||||||
|
.rule('maps')
|
||||||
|
.test(/\.js$/)
|
||||||
|
.enforce('pre')
|
||||||
|
.use('source-map-loader')
|
||||||
|
.loader('source-map-loader');
|
||||||
|
// Optimization.
|
||||||
|
config.optimization
|
||||||
|
.minimize(isProduction)
|
||||||
|
.splitChunks({
|
||||||
|
chunks: 'all',
|
||||||
|
name: !isProduction,
|
||||||
|
})
|
||||||
|
.runtimeChunk('single');
|
||||||
|
// Outputs.
|
||||||
|
config.output
|
||||||
|
.chunkFilename(isProduction ? 'assets/[name].[contenthash:8].js' : 'assets/[name].js')
|
||||||
|
.path(options.output)
|
||||||
|
.publicPath('/')
|
||||||
|
.filename(isProduction ? 'assets/[name].[contenthash:8].js' : 'assets/[name].js');
|
||||||
|
config
|
||||||
|
.devtool(isProduction ? 'source-map' : 'eval-source-map')
|
||||||
|
.target('web');
|
||||||
|
config.node
|
||||||
|
.set('Buffer', true)
|
||||||
|
.set('fs', 'empty')
|
||||||
|
.set('tls', 'empty')
|
||||||
|
.set('__dirname', false)
|
||||||
|
.set('__filename', false);
|
||||||
|
// Resolution.
|
||||||
|
config.resolve.extensions
|
||||||
|
.merge([
|
||||||
|
'.wasm',
|
||||||
|
...options.extensions.map((ext) => `.${ext}`),
|
||||||
|
'.json',
|
||||||
|
]);
|
||||||
|
config.resolve.modules
|
||||||
|
.merge([
|
||||||
|
join(FLECKS_CORE_ROOT, 'node_modules'),
|
||||||
|
'node_modules',
|
||||||
|
]);
|
||||||
|
// Reporting.
|
||||||
|
config.stats(flecks.get('@flecks/http/server.stats'));
|
||||||
|
// Inline the main entrypoint (nice for FCP).
|
||||||
|
config
|
||||||
|
.plugin('inline-chunks')
|
||||||
|
.use(InlineChunkHtmlPlugin, [HtmlWebpackPlugin, [/^assets\/index(\.[^.]*)?\.js$/]]);
|
||||||
|
};
|
||||||
|
};
|
||||||
// Neutrino configuration.
|
// Neutrino configuration.
|
||||||
const config = {
|
const config = {
|
||||||
options: {
|
options: {
|
||||||
|
@ -25,48 +119,12 @@ module.exports = (async () => {
|
||||||
root: FLECKS_CORE_ROOT,
|
root: FLECKS_CORE_ROOT,
|
||||||
},
|
},
|
||||||
use: [
|
use: [
|
||||||
({config}) => {
|
await build(),
|
||||||
config
|
|
||||||
.plugin('environment')
|
|
||||||
.use(EnvironmentPlugin, [{
|
|
||||||
FLECKS_CORE_BUILD_TARGET: 'client',
|
|
||||||
}]);
|
|
||||||
},
|
|
||||||
await targets(flecks),
|
|
||||||
],
|
],
|
||||||
};
|
};
|
||||||
// Compile code.
|
|
||||||
const compiler = flecks.invokeFleck(
|
|
||||||
'@flecks/http/server.compiler',
|
|
||||||
flecks.get('@flecks/http/server.compiler'),
|
|
||||||
);
|
|
||||||
if (compiler) {
|
|
||||||
config.use.push(compiler);
|
|
||||||
}
|
|
||||||
else {
|
|
||||||
// Use neutrino's web middleware by default.
|
|
||||||
config.use.push(web({
|
|
||||||
clean: false,
|
|
||||||
hot: false,
|
|
||||||
html: {
|
|
||||||
inject: false,
|
|
||||||
template: flecks.buildConfig('template.ejs'),
|
|
||||||
},
|
|
||||||
style: {
|
|
||||||
extract: {
|
|
||||||
enabled: false,
|
|
||||||
},
|
|
||||||
style: {
|
|
||||||
injectType: 'lazyStyleTag',
|
|
||||||
},
|
|
||||||
},
|
|
||||||
}));
|
|
||||||
}
|
|
||||||
// Configure dev server.
|
// Configure dev server.
|
||||||
config.use.push(devServer(flecks));
|
config.use.push(devServer(flecks));
|
||||||
// Build the client runtime.
|
// Build the client runtime.
|
||||||
config.use.push(await runtime(flecks));
|
config.use.push(await runtime(flecks));
|
||||||
// Output configuration.
|
|
||||||
config.use.push(outputs());
|
|
||||||
return config;
|
return config;
|
||||||
})();
|
})();
|
||||||
|
|
|
@ -1,23 +0,0 @@
|
||||||
const HtmlWebpackPlugin = require('html-webpack-plugin');
|
|
||||||
const InlineChunkHtmlPlugin = require('react-dev-utils/InlineChunkHtmlPlugin');
|
|
||||||
|
|
||||||
module.exports = () => ({config}) => {
|
|
||||||
const isProduction = 'production' === config.get('mode');
|
|
||||||
// Emit node buffer builtin.
|
|
||||||
config.node
|
|
||||||
.set('Buffer', true);
|
|
||||||
// Source maps.
|
|
||||||
config.module
|
|
||||||
.rule('maps')
|
|
||||||
.test(/\.js$/)
|
|
||||||
.enforce('pre')
|
|
||||||
.use('source-map-loader')
|
|
||||||
.loader('source-map-loader');
|
|
||||||
config.devtool(isProduction ? 'source-map' : 'eval-source-map');
|
|
||||||
// Asset naming.
|
|
||||||
config.output
|
|
||||||
.chunkFilename(isProduction ? 'assets/[name].[contenthash:8].js' : 'assets/[name].js');
|
|
||||||
config
|
|
||||||
.plugin('inline-chunks')
|
|
||||||
.use(InlineChunkHtmlPlugin, [HtmlWebpackPlugin, [/^assets\/index(\.[^.]*)?\.js$/]]);
|
|
||||||
};
|
|
|
@ -22,6 +22,7 @@ module.exports = async (flecks) => {
|
||||||
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(flecks.resolve('@flecks/http'), 'tests')));
|
||||||
return (neutrino) => {
|
return (neutrino) => {
|
||||||
|
const {config} = neutrino;
|
||||||
const {resolver} = httpFlecks;
|
const {resolver} = httpFlecks;
|
||||||
const paths = Object.entries(resolver);
|
const paths = Object.entries(resolver);
|
||||||
const source = [
|
const source = [
|
||||||
|
@ -53,7 +54,7 @@ module.exports = async (flecks) => {
|
||||||
source.push('}');
|
source.push('}');
|
||||||
source.push('');
|
source.push('');
|
||||||
// Create runtime.
|
// Create runtime.
|
||||||
neutrino.config.module
|
config.module
|
||||||
.rule(runtime)
|
.rule(runtime)
|
||||||
.test(runtime)
|
.test(runtime)
|
||||||
.use('runtime/http')
|
.use('runtime/http')
|
||||||
|
@ -61,11 +62,11 @@ module.exports = async (flecks) => {
|
||||||
.options({
|
.options({
|
||||||
source: source.join('\n'),
|
source: source.join('\n'),
|
||||||
});
|
});
|
||||||
neutrino.config.resolve.alias
|
config.resolve.alias
|
||||||
.set('@flecks/http/runtime$', runtime);
|
.set('@flecks/http/runtime$', runtime);
|
||||||
flecks.runtimeCompiler('http', neutrino);
|
flecks.runtimeCompiler('http', neutrino);
|
||||||
// Handle runtime import.
|
// Handle runtime import.
|
||||||
neutrino.config.module
|
config.module
|
||||||
.rule(entry)
|
.rule(entry)
|
||||||
.test(entry)
|
.test(entry)
|
||||||
.use('entry/http')
|
.use('entry/http')
|
||||||
|
@ -75,7 +76,7 @@ module.exports = async (flecks) => {
|
||||||
if (Object.keys(aliases).length > 0) {
|
if (Object.keys(aliases).length > 0) {
|
||||||
Object.entries(aliases)
|
Object.entries(aliases)
|
||||||
.forEach(([from, to]) => {
|
.forEach(([from, to]) => {
|
||||||
neutrino.config.resolve.alias
|
config.resolve.alias
|
||||||
.set(from, to);
|
.set(from, to);
|
||||||
});
|
});
|
||||||
}
|
}
|
||||||
|
@ -104,10 +105,10 @@ module.exports = async (flecks) => {
|
||||||
});
|
});
|
||||||
// Test entrypoint.
|
// Test entrypoint.
|
||||||
if (testPaths.length > 0) {
|
if (testPaths.length > 0) {
|
||||||
const testEntry = neutrino.config.entry('test').clear();
|
const testEntry = config.entry('test').clear();
|
||||||
testPaths.forEach(([, path]) => testEntry.add(path));
|
testPaths.forEach(([, path]) => testEntry.add(path));
|
||||||
}
|
}
|
||||||
neutrino.config.module
|
config.module
|
||||||
.rule(tests)
|
.rule(tests)
|
||||||
.test(tests)
|
.test(tests)
|
||||||
.use('runtime/test')
|
.use('runtime/test')
|
||||||
|
|
|
@ -1,29 +0,0 @@
|
||||||
/* eslint-disable no-param-reassign */
|
|
||||||
const {dirname, join} = require('path');
|
|
||||||
const {realpath} = require('fs/promises');
|
|
||||||
|
|
||||||
const {require: R} = require('@flecks/core/server');
|
|
||||||
|
|
||||||
const {
|
|
||||||
FLECKS_CORE_ROOT = process.cwd(),
|
|
||||||
} = process.env;
|
|
||||||
|
|
||||||
module.exports = async (flecks) => {
|
|
||||||
const root = await realpath(dirname(R.resolve(join(flecks.resolve('@flecks/http'), 'entry.js'))));
|
|
||||||
return (neutrino) => {
|
|
||||||
const {options} = neutrino;
|
|
||||||
const {output: originalOutput} = options;
|
|
||||||
neutrino.config.resolve.modules.merge([
|
|
||||||
join(FLECKS_CORE_ROOT, 'node_modules'),
|
|
||||||
'node_modules',
|
|
||||||
]);
|
|
||||||
options.root = root;
|
|
||||||
options.source = '.';
|
|
||||||
options.mains.index = 'entry';
|
|
||||||
options.mains.tests = {
|
|
||||||
entry: './client/tests',
|
|
||||||
title: 'Testbed',
|
|
||||||
};
|
|
||||||
options.output = join(originalOutput, flecks.get('@flecks/http/server.output'));
|
|
||||||
};
|
|
||||||
};
|
|
|
@ -1,5 +1,8 @@
|
||||||
import {D, Hooks} from '@flecks/core';
|
import {D, Hooks} from '@flecks/core';
|
||||||
import {Flecks, 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';
|
||||||
|
|
||||||
import {configSource, inlineConfig} from './config';
|
import {configSource, inlineConfig} from './config';
|
||||||
import {createHttpServer} from './http';
|
import {createHttpServer} from './http';
|
||||||
|
@ -8,6 +11,18 @@ const debug = D('@flecks/http/server');
|
||||||
|
|
||||||
export default {
|
export default {
|
||||||
[Hooks]: {
|
[Hooks]: {
|
||||||
|
'@flecks/core.build': (target, config) => {
|
||||||
|
config.use.push(styleLoader({
|
||||||
|
extract: {
|
||||||
|
enabled: false,
|
||||||
|
},
|
||||||
|
style: {
|
||||||
|
injectType: 'lazyStyleTag',
|
||||||
|
},
|
||||||
|
}));
|
||||||
|
config.use.push(fontLoader());
|
||||||
|
config.use.push(imageLoader());
|
||||||
|
},
|
||||||
'@flecks/core.build.alter': (neutrinoConfigs, flecks) => {
|
'@flecks/core.build.alter': (neutrinoConfigs, flecks) => {
|
||||||
// Bail if there's no http build.
|
// Bail if there's no http build.
|
||||||
if (!neutrinoConfigs.http) {
|
if (!neutrinoConfigs.http) {
|
||||||
|
@ -60,7 +75,11 @@ export default {
|
||||||
/**
|
/**
|
||||||
* (webpack-dev-server) Webpack stats output.
|
* (webpack-dev-server) Webpack stats output.
|
||||||
*/
|
*/
|
||||||
devStats: 'minimal',
|
devStats: {
|
||||||
|
chunks: false,
|
||||||
|
colors: true,
|
||||||
|
modules: false,
|
||||||
|
},
|
||||||
/**
|
/**
|
||||||
* Host to bind.
|
* Host to bind.
|
||||||
*/
|
*/
|
||||||
|
@ -73,6 +92,14 @@ export default {
|
||||||
* Port to bind.
|
* Port to bind.
|
||||||
*/
|
*/
|
||||||
port: 32340,
|
port: 32340,
|
||||||
|
/**
|
||||||
|
* Webpack stats configuration when building HTTP target.
|
||||||
|
*/
|
||||||
|
stats: {
|
||||||
|
chunks: false,
|
||||||
|
colors: true,
|
||||||
|
modules: false,
|
||||||
|
},
|
||||||
/**
|
/**
|
||||||
* Proxies to trust.
|
* Proxies to trust.
|
||||||
*
|
*
|
||||||
|
|
|
@ -1,8 +1,13 @@
|
||||||
|
const {join} = require('path');
|
||||||
|
|
||||||
module.exports = {
|
module.exports = {
|
||||||
aliases: {
|
aliases: {
|
||||||
'react-dom': '@hot-loader/react-dom',
|
'react-dom': '@hot-loader/react-dom',
|
||||||
},
|
},
|
||||||
babel: {
|
babel: {
|
||||||
|
plugins: [
|
||||||
|
join(__dirname, '..', 'style-loader'),
|
||||||
|
],
|
||||||
presets: [
|
presets: [
|
||||||
'@babel/preset-react',
|
'@babel/preset-react',
|
||||||
],
|
],
|
||||||
|
|
|
@ -38,12 +38,17 @@
|
||||||
"router/server.js.map",
|
"router/server.js.map",
|
||||||
"server.js",
|
"server.js",
|
||||||
"server.js.map",
|
"server.js.map",
|
||||||
"src"
|
"src",
|
||||||
|
"style-loader.js",
|
||||||
|
"style-loader.js.map"
|
||||||
],
|
],
|
||||||
"dependencies": {
|
"dependencies": {
|
||||||
|
"@babel/parser": "^7.17.0",
|
||||||
|
"@babel/types": "^7.17.0",
|
||||||
"@flecks/core": "^1.3.0",
|
"@flecks/core": "^1.3.0",
|
||||||
"@hot-loader/react-dom": "^17.0.1",
|
"@hot-loader/react-dom": "^17.0.1",
|
||||||
"@neutrinojs/react": "^9.4.0",
|
"@neutrinojs/react": "^9.4.0",
|
||||||
|
"babel-merge": "^3.0.0",
|
||||||
"classnames": "^2.3.1",
|
"classnames": "^2.3.1",
|
||||||
"history": "^5.3.0",
|
"history": "^5.3.0",
|
||||||
"prop-types": "^15.7.2",
|
"prop-types": "^15.7.2",
|
||||||
|
|
|
@ -1,28 +1,19 @@
|
||||||
import {Hooks} from '@flecks/core';
|
import {Hooks} from '@flecks/core';
|
||||||
import react from '@neutrinojs/react';
|
|
||||||
|
|
||||||
import ssr from './ssr';
|
import ssr from './ssr';
|
||||||
|
|
||||||
export default {
|
export default {
|
||||||
[Hooks]: {
|
[Hooks]: {
|
||||||
'@flecks/http/server.compiler': (flecks) => (
|
'@flecks/core.build': (target, config) => {
|
||||||
react({
|
// Resolution.
|
||||||
clean: false,
|
config.use.push(({config}) => {
|
||||||
hot: false,
|
config.resolve.alias
|
||||||
html: {
|
.set('react-native', 'react-native-web');
|
||||||
inject: false,
|
config.resolve.extensions
|
||||||
template: flecks.buildConfig('template.ejs'),
|
.prepend('.web.js')
|
||||||
},
|
.prepend('.web.jsx');
|
||||||
style: {
|
});
|
||||||
extract: {
|
},
|
||||||
enabled: false,
|
|
||||||
},
|
|
||||||
style: {
|
|
||||||
injectType: 'lazyStyleTag',
|
|
||||||
},
|
|
||||||
},
|
|
||||||
})
|
|
||||||
),
|
|
||||||
'@flecks/http/server.stream.html': (stream, req, flecks) => (
|
'@flecks/http/server.stream.html': (stream, req, flecks) => (
|
||||||
flecks.get('@flecks/react.ssr') ? ssr(stream, req, flecks) : stream
|
flecks.get('@flecks/react.ssr') ? ssr(stream, req, flecks) : stream
|
||||||
),
|
),
|
||||||
|
|
22
packages/react/src/style-loader.js
Normal file
22
packages/react/src/style-loader.js
Normal file
|
@ -0,0 +1,22 @@
|
||||||
|
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(/\.s?css$/)) {
|
||||||
|
let defaultSpecifier = path.node.specifiers.find(types.isImportDefaultSpecifier);
|
||||||
|
if (!defaultSpecifier) {
|
||||||
|
defaultSpecifier = types.importDefaultSpecifier(types.identifier(`LATUS_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 */
|
||||||
|
},
|
||||||
|
});
|
|
@ -2,12 +2,6 @@ import {Hooks} from '@flecks/core';
|
||||||
|
|
||||||
export default {
|
export default {
|
||||||
[Hooks]: {
|
[Hooks]: {
|
||||||
/**
|
|
||||||
* Define neutrino compilation middleware (e.g. @neutrinojs/react).
|
|
||||||
*/
|
|
||||||
'@flecks/server.compiler': () => {
|
|
||||||
return require('@neutrinojs/node');
|
|
||||||
},
|
|
||||||
/**
|
/**
|
||||||
* Define sequential actions to run when the server comes up.
|
* Define sequential actions to run when the server comes up.
|
||||||
*/
|
*/
|
||||||
|
@ -16,4 +10,3 @@ export default {
|
||||||
},
|
},
|
||||||
},
|
},
|
||||||
};
|
};
|
||||||
|
|
||||||
|
|
|
@ -35,7 +35,7 @@
|
||||||
"dependencies": {
|
"dependencies": {
|
||||||
"@flecks/core": "^1.3.0",
|
"@flecks/core": "^1.3.0",
|
||||||
"@neutrinojs/banner": "^9.5.0",
|
"@neutrinojs/banner": "^9.5.0",
|
||||||
"@neutrinojs/node": "^9.4.0",
|
"@neutrinojs/clean": "^9.5.0",
|
||||||
"@neutrinojs/start-server": "^9.5.0",
|
"@neutrinojs/start-server": "^9.5.0",
|
||||||
"debug": "^4.3.3",
|
"debug": "^4.3.3",
|
||||||
"loader-utils": "^1.4.0",
|
"loader-utils": "^1.4.0",
|
||||||
|
|
|
@ -19,6 +19,14 @@ export default {
|
||||||
* Whether to start the server after building.
|
* Whether to start the server after building.
|
||||||
*/
|
*/
|
||||||
start: true,
|
start: true,
|
||||||
|
/**
|
||||||
|
* Webpack stats configuration when building server target.
|
||||||
|
*/
|
||||||
|
stats: {
|
||||||
|
chunks: false,
|
||||||
|
colors: true,
|
||||||
|
modules: false,
|
||||||
|
},
|
||||||
}),
|
}),
|
||||||
},
|
},
|
||||||
};
|
};
|
||||||
|
|
|
@ -6,13 +6,14 @@ const {require: R} = require('@flecks/core/server');
|
||||||
module.exports = async (flecks) => {
|
module.exports = async (flecks) => {
|
||||||
const runtime = await realpath(R.resolve(join(flecks.resolve('@flecks/server'), 'runtime')));
|
const runtime = await realpath(R.resolve(join(flecks.resolve('@flecks/server'), 'runtime')));
|
||||||
return (neutrino) => {
|
return (neutrino) => {
|
||||||
const {config, resolver} = flecks;
|
const {config, options} = neutrino;
|
||||||
|
const {resolver} = flecks;
|
||||||
// Inject flecks configuration.
|
// Inject flecks configuration.
|
||||||
const paths = Object.keys(resolver);
|
const paths = Object.keys(resolver);
|
||||||
const source = [
|
const source = [
|
||||||
"process.env.FLECKS_CORE_BUILD_TARGET = 'server';",
|
"process.env.FLECKS_CORE_BUILD_TARGET = 'server';",
|
||||||
'module.exports = (async () => ({',
|
'module.exports = (async () => ({',
|
||||||
` config: ${JSON.stringify(config)},`,
|
` config: ${JSON.stringify(flecks.config)},`,
|
||||||
' flecks: Object.fromEntries(await Promise.all([',
|
' flecks: Object.fromEntries(await Promise.all([',
|
||||||
paths.map((path) => ` ['${path}', import('${path}')]`).join(',\n'),
|
paths.map((path) => ` ['${path}', import('${path}')]`).join(',\n'),
|
||||||
' ].map(async ([path, M]) => [path, await M]))),',
|
' ].map(async ([path, M]) => [path, await M]))),',
|
||||||
|
@ -28,7 +29,7 @@ module.exports = async (flecks) => {
|
||||||
source.push(' module.hot.addStatusHandler((status) => {');
|
source.push(' module.hot.addStatusHandler((status) => {');
|
||||||
source.push(' if ("idle" === status) {');
|
source.push(' if ("idle" === status) {');
|
||||||
source.push(' require("glob")(');
|
source.push(' require("glob")(');
|
||||||
source.push(` join('${neutrino.options.output}', \`*\${previousHash}.hot-update.*\`),`);
|
source.push(` join('${options.output}', \`*\${previousHash}.hot-update.*\`),`);
|
||||||
source.push(' async (error, disposing) => {');
|
source.push(' async (error, disposing) => {');
|
||||||
source.push(' if (error) {');
|
source.push(' if (error) {');
|
||||||
source.push(' throw error;');
|
source.push(' throw error;');
|
||||||
|
@ -49,8 +50,7 @@ module.exports = async (flecks) => {
|
||||||
});
|
});
|
||||||
source.push('}');
|
source.push('}');
|
||||||
// Create runtime.
|
// Create runtime.
|
||||||
const entries = neutrino.config.entry('index');
|
config.module
|
||||||
neutrino.config.module
|
|
||||||
.rule(runtime)
|
.rule(runtime)
|
||||||
.test(runtime)
|
.test(runtime)
|
||||||
.use('runtime')
|
.use('runtime')
|
||||||
|
@ -63,19 +63,15 @@ module.exports = async (flecks) => {
|
||||||
'@flecks/server/runtime',
|
'@flecks/server/runtime',
|
||||||
/^@babel\/runtime\/helpers\/esm/,
|
/^@babel\/runtime\/helpers\/esm/,
|
||||||
];
|
];
|
||||||
neutrino.config.resolve.alias
|
config.resolve.alias
|
||||||
.set('@flecks/server/runtime$', runtime);
|
.set('@flecks/server/runtime$', runtime);
|
||||||
flecks.runtimeCompiler('server', neutrino, allowlist);
|
flecks.runtimeCompiler('server', neutrino, allowlist);
|
||||||
// Rewrite to signals for HMR.
|
// Rewrite to signals for HMR.
|
||||||
if ('production' !== neutrino.config.get('mode')) {
|
if ('production' !== config.get('mode')) {
|
||||||
allowlist.push(/^webpack/);
|
allowlist.push(/^webpack/);
|
||||||
if (entries.has(`${R.resolve('webpack/hot/poll')}?1000`)) {
|
|
||||||
entries.delete(`${R.resolve('webpack/hot/poll')}?1000`);
|
|
||||||
entries.add('webpack/hot/signal');
|
|
||||||
}
|
|
||||||
}
|
}
|
||||||
// Externalize the rest.
|
// Externalize the rest.
|
||||||
const nodeExternals = R('webpack-node-externals');
|
const nodeExternals = R('webpack-node-externals');
|
||||||
neutrino.config.externals(nodeExternals({allowlist}));
|
config.externals(nodeExternals({allowlist}));
|
||||||
};
|
};
|
||||||
};
|
};
|
||||||
|
|
|
@ -1,9 +1,9 @@
|
||||||
const {join} = require('path');
|
const {join} = require('path');
|
||||||
|
|
||||||
const {D} = require('@flecks/core');
|
const {D} = require('@flecks/core');
|
||||||
const {Flecks} = require('@flecks/core/server');
|
const {Flecks, require: R} = require('@flecks/core/server');
|
||||||
const banner = require('@neutrinojs/banner');
|
const banner = require('@neutrinojs/banner');
|
||||||
const node = require('@neutrinojs/node');
|
const clean = require('@neutrinojs/clean');
|
||||||
const startServer = require('@neutrinojs/start-server');
|
const startServer = require('@neutrinojs/start-server');
|
||||||
|
|
||||||
const runtime = require('./runtime');
|
const runtime = require('./runtime');
|
||||||
|
@ -27,46 +27,77 @@ module.exports = (async () => {
|
||||||
start: isStarting,
|
start: isStarting,
|
||||||
} = flecks.get('@flecks/server');
|
} = flecks.get('@flecks/server');
|
||||||
|
|
||||||
const entry = (neutrino) => {
|
const server = (neutrino) => {
|
||||||
const entries = neutrino.config.entry('index');
|
const {config, options} = neutrino;
|
||||||
entries.delete(join(FLECKS_CORE_ROOT, 'src', 'index'));
|
const isProduction = 'production' === config.get('mode');
|
||||||
|
neutrino.use(banner());
|
||||||
|
neutrino.use(clean({cleanStaleWebpackAssets: false}));
|
||||||
|
// Entrypoints.
|
||||||
|
config.context(options.root);
|
||||||
|
const entries = config.entry('index');
|
||||||
|
if (!isProduction && hot) {
|
||||||
|
config
|
||||||
|
.plugin('hot')
|
||||||
|
.use(R.resolve('webpack/lib/HotModuleReplacementPlugin'));
|
||||||
|
entries.add('webpack/hot/signal');
|
||||||
|
}
|
||||||
entries.add('@flecks/server/entry');
|
entries.add('@flecks/server/entry');
|
||||||
|
// Fold in existing source maps.
|
||||||
|
config.module
|
||||||
|
.rule('maps')
|
||||||
|
.test(/\.js$/)
|
||||||
|
.enforce('pre')
|
||||||
|
.use('source-map-loader')
|
||||||
|
.loader('source-map-loader');
|
||||||
|
// Resolution.
|
||||||
|
config.resolve.extensions
|
||||||
|
.merge([
|
||||||
|
'.wasm',
|
||||||
|
...options.extensions.map((ext) => `.${ext}`),
|
||||||
|
'.json',
|
||||||
|
]);
|
||||||
|
// Reporting.
|
||||||
|
config.stats(flecks.get('@flecks/server.stats'));
|
||||||
|
// Outputs.
|
||||||
|
config.output
|
||||||
|
.path(options.output)
|
||||||
|
.libraryTarget('commonjs2');
|
||||||
|
config.node
|
||||||
|
.set('__dirname', false)
|
||||||
|
.set('__filename', false);
|
||||||
|
config
|
||||||
|
.devtool('source-map')
|
||||||
|
.target('node');
|
||||||
};
|
};
|
||||||
|
|
||||||
// Augment the application-starting configuration.
|
// Augment the application-starting configuration.
|
||||||
const start = (neutrino) => {
|
const start = (neutrino) => {
|
||||||
if (isStarting) {
|
if (isStarting) {
|
||||||
neutrino.use(startServer({name: 'index.js'}));
|
neutrino.use(startServer({name: 'index.js'}));
|
||||||
}
|
// Really dumb that I can't just pass these in.
|
||||||
if (!neutrino.config.plugins.has('start-server')) {
|
neutrino.config
|
||||||
return;
|
.plugin('start-server')
|
||||||
}
|
.tap((args) => {
|
||||||
neutrino.config
|
const options = args[0];
|
||||||
.plugin('start-server')
|
options.keyboard = false;
|
||||||
.tap((args) => {
|
// HMR.
|
||||||
const options = args[0];
|
options.signal = !!hot;
|
||||||
options.keyboard = false;
|
// Debugging.
|
||||||
// HMR.
|
if (inspect) {
|
||||||
options.signal = !!hot;
|
options.nodeArgs.push('--inspect');
|
||||||
// Debugging.
|
}
|
||||||
if (inspect) {
|
// Profiling.
|
||||||
options.nodeArgs.push('--inspect');
|
if (profile) {
|
||||||
}
|
options.nodeArgs.push('--prof');
|
||||||
// Profiling.
|
}
|
||||||
if (profile) {
|
// Bail hard on unhandled rejections and report.
|
||||||
options.nodeArgs.push('--prof');
|
options.nodeArgs.push('--unhandled-rejections=strict');
|
||||||
}
|
options.nodeArgs.push('--trace-uncaught');
|
||||||
// Bail hard on unhandled rejections and report.
|
return args;
|
||||||
options.nodeArgs.push('--unhandled-rejections=strict');
|
});
|
||||||
options.nodeArgs.push('--trace-uncaught');
|
|
||||||
return args;
|
|
||||||
});
|
|
||||||
};
|
|
||||||
|
|
||||||
const compiler = flecks.invokeFleck(
|
}
|
||||||
'@flecks/server.compiler',
|
};
|
||||||
flecks.get('@flecks/server.compiler'),
|
|
||||||
);
|
|
||||||
|
|
||||||
const config = {
|
const config = {
|
||||||
options: {
|
options: {
|
||||||
|
@ -74,24 +105,11 @@ module.exports = (async () => {
|
||||||
root: FLECKS_CORE_ROOT,
|
root: FLECKS_CORE_ROOT,
|
||||||
},
|
},
|
||||||
use: [
|
use: [
|
||||||
entry,
|
server,
|
||||||
start,
|
start,
|
||||||
],
|
],
|
||||||
};
|
};
|
||||||
|
|
||||||
if (compiler) {
|
|
||||||
config.use.unshift(compiler);
|
|
||||||
}
|
|
||||||
else {
|
|
||||||
config.use.unshift((neutrino) => {
|
|
||||||
// Default to not starting application on build.
|
|
||||||
neutrino.config.plugins.delete('start-server');
|
|
||||||
});
|
|
||||||
config.use.unshift(node({
|
|
||||||
clean: false,
|
|
||||||
hot,
|
|
||||||
}));
|
|
||||||
}
|
|
||||||
// Stub out non-server-friendly modules on the server.
|
// Stub out non-server-friendly modules on the server.
|
||||||
const stubs = flecks.stubs();
|
const stubs = flecks.stubs();
|
||||||
if (Object.keys(stubs).length > 0) {
|
if (Object.keys(stubs).length > 0) {
|
||||||
|
@ -130,8 +148,8 @@ module.exports = (async () => {
|
||||||
config.use.push(await runtime(flecks));
|
config.use.push(await runtime(flecks));
|
||||||
|
|
||||||
// Give the resolver a helping hand.
|
// Give the resolver a helping hand.
|
||||||
config.use.push((neutrino) => {
|
config.use.push(({config}) => {
|
||||||
neutrino.config.resolve.modules.merge([
|
config.resolve.modules.merge([
|
||||||
join(FLECKS_CORE_ROOT, 'node_modules'),
|
join(FLECKS_CORE_ROOT, 'node_modules'),
|
||||||
'node_modules',
|
'node_modules',
|
||||||
]);
|
]);
|
||||||
|
|
Loading…
Reference in New Issue
Block a user