Skip to content

Commit

Permalink
fix(demos): use js files for the demo server code
Browse files Browse the repository at this point in the history
Since ts-node does not support project references we use js files with jsdoc type annotations instead.
  • Loading branch information
unstubbable committed Feb 16, 2021
1 parent 07e1c57 commit a5d1fed
Show file tree
Hide file tree
Showing 17 changed files with 164 additions and 146 deletions.
2 changes: 1 addition & 1 deletion package.json
Original file line number Diff line number Diff line change
Expand Up @@ -25,7 +25,7 @@
"preverify:sort-package-jsons": "yarn sort-package-jsons",
"verify:sort-package-jsons": "git diff --exit-code package.json packages/*/package.json",
"watch:compile": "yarn compile --watch",
"watch:demo": "lerna exec --scope @feature-hub/demos -- ts-node src/watch-demo.ts",
"watch:demo": "lerna exec --scope @feature-hub/demos -- node src/watch-demo.js",
"watch:test": "yarn test --watch --no-coverage --no-verbose",
"watch:test:integration": "yarn watch:test --testPathPattern packages/demos",
"watch:test:unit": "yarn watch:test --testPathIgnorePatterns packages/demos",
Expand Down
1 change: 0 additions & 1 deletion packages/demos/package.json
Original file line number Diff line number Diff line change
Expand Up @@ -47,7 +47,6 @@
"style-loader": "^1.0.0",
"styled-components": "^5.2.0",
"ts-loader": "^6.0.0",
"ts-node": "^8.0.0",
"url-loader": "^2.0.0",
"webpack": "^4.46.0",
"webpack-cli": "^4.5.0",
Expand Down
18 changes: 18 additions & 0 deletions packages/demos/src/app-renderer.d.ts
Original file line number Diff line number Diff line change
@@ -0,0 +1,18 @@
import {Css} from '@feature-hub/react';
import express from 'express';

export interface AppRendererOptions {
readonly port: number;
readonly req: express.Request;
}

export interface AppRendererResult {
readonly html: string;
readonly serializedStates?: string;
readonly stylesheetsForSsr?: Map<string, Css>;
readonly urlsForHydration?: Set<string>;
}

export type AppRenderer = (
options: AppRendererOptions
) => Promise<AppRendererResult>;
2 changes: 1 addition & 1 deletion packages/demos/src/custom-logging/integrator.node.tsx
Original file line number Diff line number Diff line change
Expand Up @@ -5,7 +5,7 @@ import {FeatureHubContextProvider} from '@feature-hub/react';
import pino from 'pino';
import * as React from 'react';
import * as ReactDOM from 'react-dom/server';
import {AppRendererOptions, AppRendererResult} from '../node-integrator';
import {AppRendererOptions, AppRendererResult} from '../app-renderer';
import {App} from './app';

export default async function renderApp({
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -3,7 +3,7 @@ import {createCommonJsModuleLoader} from '@feature-hub/module-loader-commonjs';
import {FeatureAppLoader, FeatureHubContextProvider} from '@feature-hub/react';
import * as React from 'react';
import * as ReactDOM from 'react-dom/server';
import {AppRendererOptions, AppRendererResult} from '../node-integrator';
import {AppRendererOptions, AppRendererResult} from '../app-renderer';
import {externals} from './externals';

export default async function renderApp({
Expand Down
2 changes: 1 addition & 1 deletion packages/demos/src/get-pkg-version.js
Original file line number Diff line number Diff line change
Expand Up @@ -10,4 +10,4 @@ function getPkgVersion(pkgName) {
return require(pkgJsonPath).version;
}

exports.getPkgVersion = getPkgVersion;
module.exports = {getPkgVersion};
2 changes: 1 addition & 1 deletion packages/demos/src/history-service/integrator.node.tsx
Original file line number Diff line number Diff line change
Expand Up @@ -3,7 +3,7 @@ import {defineHistoryService} from '@feature-hub/history-service';
import {defineServerRequest} from '@feature-hub/server-request';
import * as React from 'react';
import * as ReactDOM from 'react-dom/server';
import {AppRendererOptions, AppRendererResult} from '../node-integrator';
import {AppRendererOptions, AppRendererResult} from '../app-renderer';
import {App} from './app';
import {rootLocationTransformer} from './root-location-transformer';

Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -3,7 +3,7 @@ import {loadCommonJsModule} from '@feature-hub/module-loader-commonjs';
import {FeatureAppLoader, FeatureHubContextProvider} from '@feature-hub/react';
import * as React from 'react';
import * as ReactDOM from 'react-dom/server';
import {AppRendererOptions, AppRendererResult} from '../node-integrator';
import {AppRendererOptions, AppRendererResult} from '../app-renderer';

export default async function renderApp({
port,
Expand Down
43 changes: 43 additions & 0 deletions packages/demos/src/node-integrator.js
Original file line number Diff line number Diff line change
@@ -0,0 +1,43 @@
// @ts-check

/**
* @param {string} source
* @return {any}
*/
function evalNodeSource(source) {
const mod = {exports: {}};

// tslint:disable-next-line:function-constructor
Function('module', 'exports', 'require', source)(mod, mod.exports, require);

return mod.exports;
}

/**
* @param {import('express').Response} res
* @param {string} nodeIntegratorFilename
* @return {import('./app-renderer').AppRenderer | undefined}
*/
function loadNodeIntegrator(res, nodeIntegratorFilename) {
try {
/** @type {import('webpack').InputFileSystem & import('webpack').OutputFileSystem} */
const outputFileSystem = res.locals.webpack.devMiddleware.outputFileSystem;

/** @type {import('webpack').Stats.ToJsonOutput} */
const {outputPath} = res.locals.webpack.devMiddleware.stats.toJson();

if (!outputPath) {
return undefined;
}

const source = outputFileSystem
.readFileSync(outputFileSystem.join(outputPath, nodeIntegratorFilename))
.toString();

return evalNodeSource(source).default;
} catch {
return undefined;
}
}

module.exports = {loadNodeIntegrator};
49 changes: 0 additions & 49 deletions packages/demos/src/node-integrator.ts

This file was deleted.

Original file line number Diff line number Diff line change
Expand Up @@ -15,7 +15,7 @@ import {
} from '@feature-hub/serialized-state-manager';
import * as React from 'react';
import * as ReactDOM from 'react-dom/server';
import {AppRendererOptions, AppRendererResult} from '../node-integrator';
import {AppRendererOptions, AppRendererResult} from '../app-renderer';
import {App} from './app';

export default async function renderApp({
Expand Down
Original file line number Diff line number Diff line change
@@ -1,27 +1,36 @@
import {Css} from '@feature-hub/react';
import express from 'express';
import getPort from 'get-port';
import {Server} from 'http';
import webpack from 'webpack';
import devMiddleware from 'webpack-dev-middleware';
import {AppRendererResult, loadNodeIntegrator} from './node-integrator';

function createStylesheetLink({href, media = 'all'}: Css): string {
// @ts-check

const express = require('express');
const getPort = require('get-port');
const webpack = require('webpack');
const devMiddleware = require('webpack-dev-middleware');
const {loadNodeIntegrator} = require('./node-integrator');

/**
* @param {import('@feature-hub/react').Css} stylesheet
* @return {string}
*/
function createStylesheetLink({href, media = 'all'}) {
return `<link href="${href}" media="${media}" rel="stylesheet" />`;
}

function createStylesheetLinks(stylesheets: Css[]): string {
/**
* @param {import('@feature-hub/react').Css[]} stylesheets
* @return {string}
*/
function createStylesheetLinks(stylesheets) {
return stylesheets.map(createStylesheetLink).join('\n');
}

/**
* @param {string} bodyHtml
* @param {Partial<import('./app-renderer').AppRendererResult>} appRenderResult
* @return {string}
*/
function createDocumentHtml(
bodyHtml: string,
{
serializedStates,
stylesheetsForSsr,
urlsForHydration,
}: Partial<AppRendererResult> = {}
): string {
bodyHtml,
{serializedStates, stylesheetsForSsr, urlsForHydration} = {}
) {
const stylesheetLinks = stylesheetsForSsr
? createStylesheetLinks(Array.from(stylesheetsForSsr.values()))
: '';
Expand Down Expand Up @@ -53,11 +62,17 @@ function createDocumentHtml(
`;
}

export async function startServer(
webpackConfigs: webpack.Configuration[],
nodeIntegratorWebpackConfig?: webpack.Configuration,
demoName?: string
): Promise<Server> {
/**
* @param {import('webpack').Configuration[]} webpackConfigs
* @param {webpack.Configuration=} nodeIntegratorWebpackConfig
* @param {string=} demoName
* @return {Promise<import('http').Server>}
*/
async function startServer(
webpackConfigs,
nodeIntegratorWebpackConfig,
demoName
) {
const port = await getPort(demoName ? {port: 3000} : undefined);
const app = express();

Expand Down Expand Up @@ -104,7 +119,9 @@ export async function startServer(
}
});

return new Promise<Server>((resolve) => {
return new Promise((resolve) => {
const server = app.listen(port, () => resolve(server));
});
}

module.exports = {startServer};
45 changes: 45 additions & 0 deletions packages/demos/src/watch-demo.js
Original file line number Diff line number Diff line change
@@ -0,0 +1,45 @@
// @ts-check

const {startServer} = require('./start-server');

const demoName = process.argv[2];

/**
* @return {import('webpack').Configuration[]}
*/
function loadWebpackConfigs() {
/** @type {import('webpack').Configuration[]} */
const configs = require(`./${demoName}/webpack-config`);

for (const config of configs) {
config.devtool = 'source-map';
}

return configs;
}

/**
* @return {import('webpack').Configuration | undefined}
*/
function loadNodeIntegratorWebpackConfig() {
try {
/** @type {import('webpack').Configuration} */
const config = require(`./${demoName}/webpack-config.node`);

config.devtool = 'source-map';

return config;
} catch {
return undefined;
}
}

startServer(loadWebpackConfigs(), loadNodeIntegratorWebpackConfig(), demoName)
.then((server) => {
const {port} = /** @type {import('net').AddressInfo} */ (server.address());

console.log(`The ${demoName} demo is running at: http://localhost:${port}`);
})
.catch((error) => {
console.error(error);
});
37 changes: 0 additions & 37 deletions packages/demos/src/watch-demo.ts

This file was deleted.

10 changes: 9 additions & 1 deletion packages/demos/src/webpack-base-config.js
Original file line number Diff line number Diff line change
Expand Up @@ -5,6 +5,14 @@ const webpack = require('webpack');
const merge = require('webpack-merge');
const {getPkgVersion} = require('./get-pkg-version');

/**
* @type {Partial<import('ts-loader').Options>}
*/
const tsLoaderOptions = {
projectReferences: true,
onlyCompileBundledFiles: true,
};

/**
* @type {webpack.Configuration}
*/
Expand All @@ -15,7 +23,7 @@ const webpackBaseConfig = {
rules: [
{
test: /\.tsx?$/,
use: {loader: 'ts-loader', options: {transpileOnly: true}},
use: {loader: 'ts-loader', options: tsLoaderOptions},
},
{
test: /\.css$/,
Expand Down
4 changes: 2 additions & 2 deletions packages/demos/tsconfig.json
Original file line number Diff line number Diff line change
Expand Up @@ -3,8 +3,8 @@
"include": ["src/**/*", "types/**/*"],
"compilerOptions": {
"allowJs": true,
"noEmit": true,
"outDir": "lib"
"outDir": "lib",
"rootDir": "src"
},
"references": [
{"path": "../async-ssr-manager"},
Expand Down
Loading

0 comments on commit a5d1fed

Please sign in to comment.