Skip to content
Merged
Show file tree
Hide file tree
Changes from 2 commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
4 changes: 2 additions & 2 deletions scully.config.js
Original file line number Diff line number Diff line change
Expand Up @@ -6,8 +6,8 @@ require('./extraPlugin/voidPlugin');
exports.config = {
/** projectRoot is mandatory! */
projectRoot: './projects/sampleBlog/src/app',
/** outFolder is where the static distribution files end up */
outFolder: './dist/static',
Comment thread
aaronfrost marked this conversation as resolved.
/** outDir is where the static distribution files end up */
outDir: './dist/static',

routes: {
'/demo/:id': {
Expand Down
17 changes: 16 additions & 1 deletion scully/renderPlugins/puppeteerRenderPlugin.ts
Original file line number Diff line number Diff line change
@@ -1,12 +1,15 @@
// tslint:disable: no-string-literal
// const puppeteer = require('puppeteer');
import {readFileSync} from 'fs-extra';
import {join} from 'path';
import {Browser, Page} from 'puppeteer';
import {HandledRoute} from '../routerPlugins/addOptionalRoutesPlugin';
import {launchedBrowser} from './launchedBrowser';
import {scullyConfig} from '../utils/config';
import {logError, yellow} from '../utils/log';
import {launchedBrowser} from './launchedBrowser';

export const puppeteerRender = async (route: HandledRoute): Promise<string> => {
const {version} = JSON.parse(readFileSync(join(__dirname, '../package.json')).toString()) || '0.0.0';
const path = `http://localhost:${scullyConfig.appPort}${route.route}`;
let pageHtml: string;
let browser: Browser;
Expand All @@ -25,6 +28,8 @@ export const puppeteerRender = async (route: HandledRoute): Promise<string> => {
resolve();
});

windowSet(page, 'scullyVersion', version);

/** Inject this into the running page, runs in browser*/
await page.evaluateOnNewDocument(() => {
/** set "running" mode */
Expand All @@ -34,6 +39,7 @@ export const puppeteerRender = async (route: HandledRoute): Promise<string> => {
const d = document.createElement('script');
d.innerHTML = `window['ScullyIO']='generated';`;
document.head.appendChild(d);
document.body.setAttribute('scully-version', window['scullyVersion']);
window['onCustomEvent']();
});
});
Expand Down Expand Up @@ -63,3 +69,12 @@ export const puppeteerRender = async (route: HandledRoute): Promise<string> => {
function waitForIt(milliSeconds) {
return new Promise(resolve => setTimeout(() => resolve(), milliSeconds));
}

const windowSet = (page, name, value) =>
Comment thread
SanderElias marked this conversation as resolved.
page.evaluateOnNewDocument(`
Object.defineProperty(window, '${name}', {
get() {
return '${value}'
}
})
`);
204 changes: 61 additions & 143 deletions scully/scully.ts
Original file line number Diff line number Diff line change
@@ -1,180 +1,98 @@
#!/usr/bin/env node
// the above line is needed for node bin running

import {spawn} from 'child_process';
import {existsSync} from 'fs-extra';
import {readFileSync} from 'fs-extra';
import {join} from 'path';
import * as yargs from 'yargs';
import './pluginManagement/systemPlugins';
import {routeContentRenderer} from './renderPlugins/routeContentRenderer';
import {startBackgroundServer} from './startBackgroundServer';
import {loadConfig} from './utils/config';
import {checkChangeAngular, existDistAngular, moveDistAngular} from './utils/fsAngular';
import {checkStaticFolder} from './utils/fsFolder';
import {moveDistAngular} from './utils/fsAngular';
import {httpGetJson} from './utils/httpGetJson';
import {RouteTypes, ScullyConfig} from './utils/interfacesandenums';
import {RouteTypes} from './utils/interfacesandenums';
import {isPortTaken} from './utils/isPortTaken';
import {logError} from './utils/log';
import {startScully} from './utils/startup';
import {closeExpress, staticServer} from './utils/staticServer';
import {waitForServerToBeAvailable} from './utils/waitForServerToBeAvailable';
import {bootServe, isBuildThere, watchMode} from './watchMode';

/** the default of 10 is too shallow for generating pages. */
require('events').defaultMaxListeners = 100;

let port;
// tslint:disable-next-line:variable-name
let _options = {};
export let _options = {};

const {argv: options} = yargs
.option('path', {
alias: 'p',
type: 'string',
description: 'The path to generate',
})
.option('type', {
alias: 't',
type: 'string',
description: 'The type to generate',
})
.option('port', {
alias: 'p',
type: 'number',
description: 'The port to run on',
})
.option('folder', {
type: 'string',
description: 'home folder',
});

if (process.argv.includes('version')) {
const {version} = JSON.parse(readFileSync(join(__dirname, './package.json')).toString());
console.log('version:', version);
process.exit(0);
}

(async () => {
if (process.argv.includes('killServer')) {
await httpGetJson('http://localhost:1864/killMe', {suppressErrors: true});
process.exit(0);
return;
}
/** make sure not to do something before the config is ready */
const scullyConfig = await loadConfig;
await isBuildThere(scullyConfig);

const {argv: options} = yargs
.option('path', {
alias: 'p',
type: 'string',
description: 'The path to generate',
})
.option('type', {
alias: 't',
type: 'string',
description: 'The type to generate',
})
.option('port', {
alias: 'p',
type: 'number',
description: 'The port to run on',
});

if (process.argv.includes('serve')) {
port = options.path;
console.log('starting static server...');
process.title = 'ScullyServer';
checkChangeAngular(options.path);
restartStaticServer();
await bootServe(scullyConfig);
} else {
const folder = join(scullyConfig.homeFolder, scullyConfig.distFolder);
/** copy in current buildfile */
await moveDistAngular(folder, scullyConfig.outDir, {removeStaticDist: true, reset: false});

/** server already up and running? */
const isTaken = await isPortTaken(scullyConfig.staticport);
if (!isTaken) {
startBackgroundServer(scullyConfig);
} else {
// debug only
console.log(`Background servers already running.`);
}

if (!existDistAngular(scullyConfig.homeFolder)) {
if (!(await waitForServerToBeAvailable().catch(e => false))) {
logError('Could not connect to server');
process.exit(15);
}

await moveDistAngular(folder, scullyConfig.outDir, {removeStaticDist: true, reset: false});
console.log('servers available');
await startScully();

if (options.path && options.type) {
routeContentRenderer({
route: options.path,
type: (options.type as unknown) as RouteTypes,
});
if (process.argv.includes('watch')) {
_options = options;
watchMode();
}
if (process.argv.includes('watch')) {
_options = options;
watchMode();
} else {
/** server already up and running? */
const isTaken = await isPortTaken(scullyConfig.staticport);
if (!isTaken) {
spawn('node', [join(scullyConfig.homeFolder, './node_modules/.bin/scully'), 'serve'], {
detached: true,
}).on('close', err => {
if (+err > 0) {
spawn(
'node',
[join(scullyConfig.homeFolder, './node_modules/@scullyio/scully/scully.js'), 'serve'],
{
detached: true,
}
).on('close', err2 => {
if (+err2 > 0) {
spawn('node', [join(scullyConfig.homeFolder, '/dist/scully/scully'), 'serve'], {
detached: true,
});
}
});
}
});

console.log('started servers in background');
} else {
// debug only
console.log(`Background servers already running.`);
}

if (!(await waitForServerToBeAvailable().catch(e => false))) {
logError('Could not connect to server');
process.exit(15);
// kill serve ports
await httpGetJson('http://localhost:1864/killMe', {suppressErrors: true});
}

console.log('servers available');
await startScully();

if (process.argv.includes('watch')) {
_options = options;
watchMode();
} else {
if (!isTaken) {
// kill serve ports
await httpGetJson('http://localhost:1864/killMe', {suppressErrors: true});
}
/** done, stop the program */
process.exit(0);
}
}
}
})();

// TODO : we need rewrite this to observables for don't have memory leaks
async function watchMode() {
await checkStaticFolder();
// g for generate and the q for quit
checkForManualRestart();
// @ts-ignore
await checkChangeAngular(_options.path, false, true);
}

export function checkForManualRestart() {
const readline = require('readline').createInterface({
input: process.stdin,
output: process.stdout,
});

readline.question(`Press g for manual regenerate, or q for close the server. \n`, command => {
if (command.toLowerCase() === 'g') {
startScully().then(() => checkForManualRestart());
} else if (command.toLowerCase() === 'q') {
readline.close();
/** done, stop the program */
process.exit(0);
} else {
readline.close();
checkForManualRestart();
}
});
}

export function startScullyWatchMode() {
startScully();
}

function startStaticServer() {
staticServer();
}

let restartTimer: NodeJS.Timer;
export function restartStaticServer() {
// tslint:disable-next-line: no-unused-expression
restartTimer && clearTimeout(restartTimer);
restartTimer = setTimeout(() => {
closeExpress();
startStaticServer();
}, 500);
}

export async function isBuildThere(config: ScullyConfig) {
const dist = join(config.homeFolder, config.distFolder);
if (existsSync(dist) && existsSync(join(dist, 'index.html'))) {
return true;
}
logError(`Angular distribution files not found, run "ng build" first`);
process.exit(15);
}
})();
28 changes: 28 additions & 0 deletions scully/startBackgroundServer.ts
Original file line number Diff line number Diff line change
@@ -0,0 +1,28 @@
import {spawn} from 'child_process';
import {existsSync} from 'fs-extra';
import {join} from 'path';
import {ScullyConfig} from './utils/interfacesandenums';
import {logError, log, green} from './utils/log';

export function startBackgroundServer(scullyConfig: ScullyConfig) {
const binary = ['/dist/scully/scully', '/node_modules/.bin/scully', '/node_modules/@scullyio/scully/scully']
.map(p => join(scullyConfig.homeFolder, p + '.js'))
.find(p => existsSync(p));

if (!binary) {
logError('Could not find scully binaries');
process.exit(15);
return;
}
console.log('starting', binary);
Comment thread
jorgeucano marked this conversation as resolved.
Outdated
spawn('node', [binary, 'serve'], {
detached: true,
// stdio: 'inherit',
}).on('close', err => {
if (+err > 0) {
logError('Problem starting background servers', err);
process.exit(15);
}
});
log(` ${green('☺')} Started servers in background`);
}
2 changes: 1 addition & 1 deletion scully/tsconfig.scully.json
Original file line number Diff line number Diff line change
Expand Up @@ -27,5 +27,5 @@
]
},
"files": ["./index.ts", "scully.ts"],
"exclude": ["bin/**/*","bin/**/*.d.ts", "bin/index.js"]
"exclude": ["bin/**/*", "bin/**/*.d.ts", "bin/index.js", "../dist/**/*"]
}
16 changes: 1 addition & 15 deletions scully/utils/fsAngular.ts
Original file line number Diff line number Diff line change
Expand Up @@ -4,12 +4,11 @@ import {copy, remove} from 'fs-extra';
import {join} from 'path';
import {Observable} from 'rxjs';
import {debounceTime, filter, tap} from 'rxjs/operators';
import {restartStaticServer, startScullyWatchMode} from '../scully';
import {restartStaticServer, startScullyWatchMode} from '../watchMode';
import {green, log, logWarn, red} from './log';
import {scullyConfig} from './config';
import {createFolderFor} from './createFolderFor';


export async function checkChangeAngular(
folder = join(scullyConfig.homeFolder, scullyConfig.distFolder) ||
join(scullyConfig.homeFolder, './dist/browser'),
Expand Down Expand Up @@ -57,19 +56,6 @@ function watchFolder(folder): Observable<{eventType: string; fileName: string}>
});
}

export function existDistAngular(src) {
try {
if (!existsSync(src)) {
log(`${red(`Build not found`)}.`);
log(`Please build first your angular app`);
return false;
}
return true;
} catch (e) {
return false;
}
}

// tslint:disable-next-line:no-shadowed-variable
export async function moveDistAngular(src, dest, {reset = true, removeStaticDist = false}, watch = false) {
try {
Expand Down
Loading