mirror of
https://github.com/lowdefy/lowdefy.git
synced 2025-03-19 15:01:06 +08:00
feat(server-dev): Updates to dev server manager.
This commit is contained in:
parent
b610a63a52
commit
b4861d0892
@ -18,18 +18,35 @@ import path from 'path';
|
||||
import yargs from 'yargs';
|
||||
import { hideBin } from 'yargs/helpers';
|
||||
|
||||
import lowdefyBuild from './processes/lowdefyBuild.mjs';
|
||||
import nextBuild from './processes/nextBuild.mjs';
|
||||
import installServer from './processes/installServer.mjs';
|
||||
import reloadClients from './processes/reloadClients.mjs';
|
||||
|
||||
const argv = yargs(hideBin(process.argv)).argv;
|
||||
|
||||
async function getContext() {
|
||||
const { configDirectory = process.cwd(), packageManager = 'npm', skipInstall } = argv;
|
||||
const {
|
||||
configDirectory = process.cwd(),
|
||||
packageManager = 'npm',
|
||||
skipInstall,
|
||||
verbose = false,
|
||||
} = argv;
|
||||
const context = {
|
||||
directories: {
|
||||
config: path.resolve(configDirectory),
|
||||
},
|
||||
packageManager,
|
||||
restartServer: () => {},
|
||||
skipInstall,
|
||||
restartServer: () => {},
|
||||
shutdownServer: () => {},
|
||||
verbose,
|
||||
};
|
||||
context.installServer = installServer(context);
|
||||
context.lowdefyBuild = lowdefyBuild(context);
|
||||
context.nextBuild = nextBuild(context);
|
||||
context.reloadClients = reloadClients(context);
|
||||
|
||||
return context;
|
||||
}
|
||||
|
||||
|
@ -15,15 +15,11 @@
|
||||
limitations under the License.
|
||||
*/
|
||||
|
||||
import installServer from './processes/installServer.mjs';
|
||||
import lowdefyBuild from './processes/lowdefyBuild.mjs';
|
||||
import nextBuild from './processes/nextBuild.mjs';
|
||||
|
||||
async function initialBuild(context) {
|
||||
await installServer(context);
|
||||
await lowdefyBuild(context);
|
||||
await installServer(context);
|
||||
await nextBuild(context);
|
||||
await context.installServer();
|
||||
await context.lowdefyBuild();
|
||||
await context.installServer();
|
||||
await context.nextBuild();
|
||||
}
|
||||
|
||||
export default initialBuild;
|
||||
|
@ -21,15 +21,17 @@ const args = {
|
||||
yarn: ['install'],
|
||||
};
|
||||
|
||||
async function installServer({ packageManager, skipInstall }) {
|
||||
if (skipInstall) return;
|
||||
console.log('Installing server');
|
||||
await spawnProcess({
|
||||
logger: console,
|
||||
command: packageManager, // npm or yarn
|
||||
args: args[packageManager],
|
||||
silent: false,
|
||||
});
|
||||
function installServer({ packageManager, skipInstall, verbose }) {
|
||||
return async () => {
|
||||
if (skipInstall) return;
|
||||
console.log('Installing server...');
|
||||
await spawnProcess({
|
||||
logger: console,
|
||||
command: packageManager, // npm or yarn
|
||||
args: args[packageManager],
|
||||
silent: !verbose,
|
||||
});
|
||||
};
|
||||
}
|
||||
|
||||
export default installServer;
|
||||
|
@ -16,21 +16,23 @@
|
||||
|
||||
import { spawnProcess } from '@lowdefy/node-utils';
|
||||
|
||||
async function runLowdefyBuild({ packageManager, directories }) {
|
||||
await spawnProcess({
|
||||
logger: console,
|
||||
args: ['run', 'build:lowdefy'],
|
||||
command: packageManager,
|
||||
processOptions: {
|
||||
env: {
|
||||
...process.env,
|
||||
LOWDEFY_BUILD_DIRECTORY: './build',
|
||||
LOWDEFY_CONFIG_DIRECTORY: directories.config,
|
||||
LOWDEFY_SERVER_DIRECTORY: process.cwd(),
|
||||
function lowdefyBuild({ packageManager, directories }) {
|
||||
return async () => {
|
||||
await spawnProcess({
|
||||
logger: console,
|
||||
args: ['run', 'build:lowdefy'],
|
||||
command: packageManager,
|
||||
processOptions: {
|
||||
env: {
|
||||
...process.env,
|
||||
LOWDEFY_BUILD_DIRECTORY: './build',
|
||||
LOWDEFY_CONFIG_DIRECTORY: directories.config,
|
||||
LOWDEFY_SERVER_DIRECTORY: process.cwd(),
|
||||
},
|
||||
},
|
||||
},
|
||||
silent: false,
|
||||
});
|
||||
silent: false,
|
||||
});
|
||||
};
|
||||
}
|
||||
|
||||
export default runLowdefyBuild;
|
||||
export default lowdefyBuild;
|
||||
|
@ -16,13 +16,16 @@
|
||||
|
||||
import { spawnProcess } from '@lowdefy/node-utils';
|
||||
|
||||
async function runNextBuild({ packageManager }) {
|
||||
await spawnProcess({
|
||||
logger: console,
|
||||
args: ['run', 'build:next'],
|
||||
command: packageManager,
|
||||
silent: false,
|
||||
});
|
||||
function nextBuild({ packageManager, verbose }) {
|
||||
return async () => {
|
||||
console.log('Building next app...');
|
||||
await spawnProcess({
|
||||
logger: console,
|
||||
args: ['run', 'build:next'],
|
||||
command: packageManager,
|
||||
silent: !verbose,
|
||||
});
|
||||
};
|
||||
}
|
||||
|
||||
export default runNextBuild;
|
||||
export default nextBuild;
|
||||
|
26
packages/server-dev/src/manager/processes/reloadClients.mjs
Normal file
26
packages/server-dev/src/manager/processes/reloadClients.mjs
Normal file
@ -0,0 +1,26 @@
|
||||
/*
|
||||
Copyright 2020-2021 Lowdefy, Inc
|
||||
|
||||
Licensed under the Apache License, Version 2.0 (the "License");
|
||||
you may not use this file except in compliance with the License.
|
||||
You may obtain a copy of the License at
|
||||
|
||||
http://www.apache.org/licenses/LICENSE-2.0
|
||||
|
||||
Unless required by applicable law or agreed to in writing, software
|
||||
distributed under the License is distributed on an "AS IS" BASIS,
|
||||
WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
|
||||
See the License for the specific language governing permissions and
|
||||
limitations under the License.
|
||||
*/
|
||||
|
||||
import { writeFile } from '@lowdefy/node-utils';
|
||||
|
||||
function reloadClients(context) {
|
||||
return async () => {
|
||||
await writeFile({ filePath: './build/reload', content: `${Date.now()}` });
|
||||
console.log('Reloaded');
|
||||
};
|
||||
}
|
||||
|
||||
export default reloadClients;
|
@ -24,17 +24,22 @@ function startServerProcess({ context, handleExit }) {
|
||||
silent: false,
|
||||
});
|
||||
context.serverProcess.on('exit', handleExit);
|
||||
context.restartServer = async () => {
|
||||
context.restartServer = () => {
|
||||
console.log('Restarting server...');
|
||||
context.serverProcess.kill();
|
||||
startServerProcess({ context, handleExit });
|
||||
};
|
||||
context.shutdownServer = () => {
|
||||
console.log('Shutting down server...');
|
||||
context.serverProcess.kill();
|
||||
};
|
||||
}
|
||||
|
||||
async function startServer(context) {
|
||||
return new Promise((resolve, reject) => {
|
||||
function handleExit(code) {
|
||||
if (code !== 0) {
|
||||
// TODO: Shutdown server
|
||||
context.shutdownServer && context.shutdownServer();
|
||||
reject(new Error('Server error.'));
|
||||
}
|
||||
resolve();
|
||||
@ -42,7 +47,7 @@ async function startServer(context) {
|
||||
try {
|
||||
startServerProcess({ context, handleExit });
|
||||
} catch (error) {
|
||||
// TODO: Shutdown server
|
||||
context.shutdownServer && context.shutdownServer();
|
||||
reject(error);
|
||||
}
|
||||
});
|
||||
|
21
packages/server-dev/src/manager/wait.mjs
Normal file
21
packages/server-dev/src/manager/wait.mjs
Normal file
@ -0,0 +1,21 @@
|
||||
/*
|
||||
Copyright 2020-2021 Lowdefy, Inc
|
||||
|
||||
Licensed under the Apache License, Version 2.0 (the "License");
|
||||
you may not use this file except in compliance with the License.
|
||||
You may obtain a copy of the License at
|
||||
|
||||
http://www.apache.org/licenses/LICENSE-2.0
|
||||
|
||||
Unless required by applicable law or agreed to in writing, software
|
||||
distributed under the License is distributed on an "AS IS" BASIS,
|
||||
WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
|
||||
See the License for the specific language governing permissions and
|
||||
limitations under the License.
|
||||
*/
|
||||
|
||||
async function wait(ms) {
|
||||
return new Promise((resolve) => setTimeout(resolve, ms));
|
||||
}
|
||||
|
||||
export default wait;
|
@ -14,13 +14,12 @@
|
||||
limitations under the License.
|
||||
*/
|
||||
|
||||
import lowdefyBuild from '../processes/lowdefyBuild.mjs';
|
||||
import setupWatcher from './setupWatcher.mjs';
|
||||
|
||||
async function configWatcher(context) {
|
||||
const callback = async () => {
|
||||
await lowdefyBuild(context);
|
||||
context.restartServer();
|
||||
await context.lowdefyBuild();
|
||||
context.reloadClients({ type: 'soft' });
|
||||
};
|
||||
// TODO: Add ignored paths
|
||||
return setupWatcher({ callback, watchPaths: [context.directories.config] });
|
||||
|
37
packages/server-dev/src/manager/watchers/envWatcher.mjs
Normal file
37
packages/server-dev/src/manager/watchers/envWatcher.mjs
Normal file
@ -0,0 +1,37 @@
|
||||
/*
|
||||
Copyright 2020-2021 Lowdefy, Inc
|
||||
|
||||
Licensed under the Apache License, Version 2.0 (the "License");
|
||||
you may not use this file except in compliance with the License.
|
||||
You may obtain a copy of the License at
|
||||
|
||||
http://www.apache.org/licenses/LICENSE-2.0
|
||||
|
||||
Unless required by applicable law or agreed to in writing, software
|
||||
distributed under the License is distributed on an "AS IS" BASIS,
|
||||
WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
|
||||
See the License for the specific language governing permissions and
|
||||
limitations under the License.
|
||||
*/
|
||||
|
||||
import path from 'path';
|
||||
import setupWatcher from './setupWatcher.mjs';
|
||||
import wait from '../wait.mjs';
|
||||
|
||||
async function envWatcher(context) {
|
||||
const callback = async () => {
|
||||
console.log('.env file changed, restarting server...');
|
||||
context.reloadClients({ type: 'hard' });
|
||||
// Wait for clients to get reload event.
|
||||
await wait(500);
|
||||
context.restartServer();
|
||||
};
|
||||
// TODO: Add ignored paths
|
||||
return setupWatcher({
|
||||
callback,
|
||||
watchPaths: [path.resolve(context.directories.config, '.env')],
|
||||
watchDotfiles: true,
|
||||
});
|
||||
}
|
||||
|
||||
export default envWatcher;
|
@ -17,16 +17,19 @@
|
||||
import chokidar from 'chokidar';
|
||||
import BatchChanges from '../BatchChanges.mjs';
|
||||
|
||||
function setupWatcher({ callback, watchPaths }) {
|
||||
function setupWatcher({ callback, watchDotfiles = false, ignorePaths = [], watchPaths }) {
|
||||
return new Promise((resolve) => {
|
||||
// const { watch = [], watchIgnore = [] } = context.options;
|
||||
// const resolvedWatchPaths = watch.map((pathName) => path.resolve(pathName));
|
||||
|
||||
const batchChanges = new BatchChanges({ fn: callback });
|
||||
const defaultIgnorePaths = watchDotfiles
|
||||
? []
|
||||
: [
|
||||
/(^|[/\\])\../, // ignore dotfiles
|
||||
];
|
||||
const configWatcher = chokidar.watch(watchPaths, {
|
||||
ignored: [
|
||||
/(^|[/\\])\../, // ignore dotfiles
|
||||
],
|
||||
ignored: [...defaultIgnorePaths, ...ignorePaths],
|
||||
persistent: true,
|
||||
ignoreInitial: true,
|
||||
});
|
||||
|
@ -15,6 +15,7 @@
|
||||
*/
|
||||
|
||||
import configWatcher from './configWatcher.mjs';
|
||||
import envWatcher from './envWatcher.mjs';
|
||||
|
||||
/*
|
||||
Config change
|
||||
@ -57,7 +58,7 @@ Watch <server-dir>/build/plugins/*
|
||||
*/
|
||||
|
||||
async function startWatchers(context) {
|
||||
await Promise.all([configWatcher(context)]);
|
||||
await Promise.all([configWatcher(context), envWatcher(context)]);
|
||||
}
|
||||
|
||||
export default startWatchers;
|
||||
|
@ -28,13 +28,9 @@ async function writeFile({ filePath, content }) {
|
||||
`Could not write file, file path should be a string, received ${JSON.stringify(filePath)}.`
|
||||
);
|
||||
}
|
||||
if (filePath !== path.resolve(filePath)) {
|
||||
throw new Error(
|
||||
`Could not write file, file path was not resolved, received ${JSON.stringify(filePath)}.`
|
||||
);
|
||||
}
|
||||
|
||||
try {
|
||||
await writeFilePromise(filePath, content);
|
||||
await writeFilePromise(path.resolve(filePath), content);
|
||||
} catch (error) {
|
||||
if (error.code === 'ENOENT') {
|
||||
await mkdirPromise(path.dirname(filePath), { recursive: true });
|
||||
|
Loading…
x
Reference in New Issue
Block a user