diff --git a/jest.config.js b/jest.config.js index 5ee1a1fa..bcc940d1 100644 --- a/jest.config.js +++ b/jest.config.js @@ -17,7 +17,8 @@ module.exports = { moduleFileExtensions: ['js', 'json', 'ts', 'tsx'], moduleNameMapper: { '^@feature-hub/([^/]+)$': '/packages/$1/src/index.ts', - '^@feature-hub/([^/]+)/node$': '/packages/$1/src/node.ts' + '^@feature-hub/module-loader/lib/node$': + '/packages/module-loader/src/node.ts' }, modulePathIgnorePatterns: ['/lib'], setupTestFrameworkScriptFile: '/scripts/setup-test-framework.js', diff --git a/packages/demos/README.md b/packages/demos/README.md index 82a7cb01..a083318a 100644 --- a/packages/demos/README.md +++ b/packages/demos/README.md @@ -19,6 +19,10 @@ Now run one of the following demos: yarn watch:demo amd-module-loader ``` +```sh +yarn watch:demo commonjs-module-loader +``` + ```sh yarn watch:demo history-service ``` diff --git a/packages/demos/src/amd-module-loader/index.test.ts b/packages/demos/src/amd-module-loader/index.test.ts index d37b8a7d..64f59299 100644 --- a/packages/demos/src/amd-module-loader/index.test.ts +++ b/packages/demos/src/amd-module-loader/index.test.ts @@ -16,7 +16,7 @@ describe('integration test: "amd module loader"', () => { let server: Server; beforeAll(async () => { - server = await startServer(webpackConfigs); + server = await startServer(webpackConfigs, undefined); const {port} = server.address() as AddressInfo; diff --git a/packages/demos/src/commonjs-module-loader/feature-app.tsx b/packages/demos/src/commonjs-module-loader/feature-app.tsx new file mode 100644 index 00000000..b65d0340 --- /dev/null +++ b/packages/demos/src/commonjs-module-loader/feature-app.tsx @@ -0,0 +1,17 @@ +import {Card, Label} from '@blueprintjs/core'; +import {ReactFeatureApp} from '@feature-hub/react'; +import * as React from 'react'; + +export default { + id: 'test:hello-world', + + create(): ReactFeatureApp { + return { + render: () => ( + + + + ) + }; + } +}; diff --git a/packages/demos/src/commonjs-module-loader/index.test.ts b/packages/demos/src/commonjs-module-loader/index.test.ts new file mode 100644 index 00000000..a1f14984 --- /dev/null +++ b/packages/demos/src/commonjs-module-loader/index.test.ts @@ -0,0 +1,32 @@ +/** + * @jest-environment puppeteer + */ + +import {Server} from 'http'; +import {AddressInfo} from 'net'; +import {Browser} from '../browser'; +import {startServer} from '../start-server'; +import renderMainHtml from './integrator.node'; +import webpackConfigs from './webpack-config'; + +jest.setTimeout(60000); + +describe('integration test: "commonjs module loader"', () => { + const browser = new Browser(5000); + + let server: Server; + + beforeAll(async () => { + server = await startServer(webpackConfigs, renderMainHtml); + + const {port} = server.address() as AddressInfo; + + await browser.goto(`http://localhost:${port}`, 60000); + }); + + afterAll(done => server.close(done)); + + it('loads the server-side rendered feature app HTML', async () => { + await expect(page).toMatch('Hello, World!'); + }); +}); diff --git a/packages/demos/src/commonjs-module-loader/integrator.node.tsx b/packages/demos/src/commonjs-module-loader/integrator.node.tsx new file mode 100644 index 00000000..dca7c946 --- /dev/null +++ b/packages/demos/src/commonjs-module-loader/integrator.node.tsx @@ -0,0 +1,20 @@ +import {FeatureAppManager, FeatureServiceRegistry} from '@feature-hub/core'; +import {loadCommonJsModule} from '@feature-hub/module-loader/lib/node'; +import {FeatureAppLoader} from '@feature-hub/react'; +import * as React from 'react'; +import * as ReactDOM from 'react-dom/server'; + +export default async function renderMainHtml(port: number): Promise { + const featureAppNodeUrl = `http://localhost:${port}/feature-app.commonjs.js`; + const registry = new FeatureServiceRegistry(); + + const manager = new FeatureAppManager(registry, { + moduleLoader: loadCommonJsModule + }); + + await manager.preloadFeatureApp(featureAppNodeUrl); + + return ReactDOM.renderToString( + + ); +} diff --git a/packages/demos/src/commonjs-module-loader/integrator.ts b/packages/demos/src/commonjs-module-loader/integrator.ts new file mode 100644 index 00000000..62aca2c2 --- /dev/null +++ b/packages/demos/src/commonjs-module-loader/integrator.ts @@ -0,0 +1,2 @@ +// tslint:disable-next-line:no-import-side-effect +import '../blueprint-css'; diff --git a/packages/demos/src/commonjs-module-loader/webpack-config.ts b/packages/demos/src/commonjs-module-loader/webpack-config.ts new file mode 100644 index 00000000..33730db2 --- /dev/null +++ b/packages/demos/src/commonjs-module-loader/webpack-config.ts @@ -0,0 +1,24 @@ +import {join} from 'path'; +import {Configuration} from 'webpack'; +import {webpackBaseConfig} from '../webpack-base-config'; + +export default [ + { + ...webpackBaseConfig, + entry: join(__dirname, './feature-app.tsx'), + output: { + filename: 'feature-app.commonjs.js', + libraryTarget: 'commonjs2', + publicPath: '/' + }, + target: 'node' + }, + { + ...webpackBaseConfig, + entry: join(__dirname, './integrator.ts'), + output: { + filename: 'integrator.js', + publicPath: '/' + } + } +] as Configuration[]; diff --git a/packages/demos/src/history-service/index.test.ts b/packages/demos/src/history-service/index.test.ts index 4f99a696..fd4aceb9 100644 --- a/packages/demos/src/history-service/index.test.ts +++ b/packages/demos/src/history-service/index.test.ts @@ -69,7 +69,7 @@ describe('integration test: "history-service"', () => { let url: string; beforeAll(async () => { - server = await startServer(webpackConfigs); + server = await startServer(webpackConfigs, undefined); const {port} = server.address() as AddressInfo; diff --git a/packages/demos/src/start-server.ts b/packages/demos/src/start-server.ts index c83675ba..798d3386 100644 --- a/packages/demos/src/start-server.ts +++ b/packages/demos/src/start-server.ts @@ -4,19 +4,27 @@ import {Server} from 'http'; import webpack from 'webpack'; import devMiddleware from 'webpack-dev-middleware'; +export type MainHtmlRenderer = (port: number) => Promise; + export async function startServer( - webpackConfigs: webpack.Configuration[] + webpackConfigs: webpack.Configuration[], + renderMainHtml: MainHtmlRenderer | undefined ): Promise { + // tslint:disable-next-line:await-promise + const port = await getPort(); + const app = express(); - app.get('/', (_req, res) => { + app.get('/', async (_req, res) => { + const mainHtml = renderMainHtml ? await renderMainHtml(port) : ''; + res.send( ` -
+
${mainHtml}
` @@ -25,9 +33,6 @@ export async function startServer( app.use(devMiddleware(webpack(webpackConfigs), {publicPath: '/'})); - // tslint:disable-next-line:await-promise - const port = await getPort(); - return new Promise(resolve => { const server = app.listen(port, () => resolve(server)); }); diff --git a/packages/demos/src/watch-demo.ts b/packages/demos/src/watch-demo.ts index cc3c2a33..5b605512 100644 --- a/packages/demos/src/watch-demo.ts +++ b/packages/demos/src/watch-demo.ts @@ -1,6 +1,6 @@ import {AddressInfo} from 'net'; import {Configuration} from 'webpack'; -import {startServer} from './start-server'; +import {MainHtmlRenderer, startServer} from './start-server'; const demoName = process.argv[2]; @@ -15,7 +15,17 @@ function loadWebpackConfigs(): Configuration[] { return configs; } -startServer(loadWebpackConfigs()) +function loadNodeIntegrator(): MainHtmlRenderer | undefined { + const nodeIntegratorPath = `./${demoName}/integrator.node`; + + try { + return require(nodeIntegratorPath).default; + } catch { + return; + } +} + +startServer(loadWebpackConfigs(), loadNodeIntegrator()) .then(server => { const {port} = server.address() as AddressInfo; diff --git a/packages/module-loader/index.d.ts b/packages/module-loader/index.d.ts deleted file mode 100644 index 11aece60..00000000 --- a/packages/module-loader/index.d.ts +++ /dev/null @@ -1 +0,0 @@ -export * from './lib/index'; diff --git a/packages/module-loader/index.js b/packages/module-loader/index.js deleted file mode 100644 index b58e228f..00000000 --- a/packages/module-loader/index.js +++ /dev/null @@ -1 +0,0 @@ -module.exports = require('./lib/index'); diff --git a/packages/module-loader/node.d.ts b/packages/module-loader/node.d.ts deleted file mode 100644 index ef80b5f6..00000000 --- a/packages/module-loader/node.d.ts +++ /dev/null @@ -1 +0,0 @@ -export * from './lib/node'; diff --git a/packages/module-loader/node.js b/packages/module-loader/node.js deleted file mode 100644 index daea9872..00000000 --- a/packages/module-loader/node.js +++ /dev/null @@ -1 +0,0 @@ -module.exports = require('./lib/node'); diff --git a/packages/module-loader/package.json b/packages/module-loader/package.json index a2f7efde..c31d5f65 100644 --- a/packages/module-loader/package.json +++ b/packages/module-loader/package.json @@ -13,12 +13,10 @@ "author": "SinnerSchrader Deutschland GmbH", "files": [ "lib", - "!__tests__", - "index.d.ts", - "index.js", - "node.d.ts", - "node.js" + "!__tests__" ], + "main": "lib/index.js", + "typings": "lib/index.d.ts", "dependencies": { "@feature-hub/core": "^0.9.0", "fs-extra": "^7.0.1", diff --git a/packages/module-loader/src/node.ts b/packages/module-loader/src/node.ts index 656d66c2..0cfd4c7a 100644 --- a/packages/module-loader/src/node.ts +++ b/packages/module-loader/src/node.ts @@ -37,7 +37,7 @@ async function requireAsync(url: string): Promise { /** * ```js - * import {loadCommonJsModule} from '@feature-hub/module-loader/node'; + * import {loadCommonJsModule} from '@feature-hub/module-loader/lib/node'; * ``` */ export const loadCommonJsModule: ModuleLoader = async (url: string) => diff --git a/scripts/ci/test.sh b/scripts/ci/test.sh index 6f1b8a6a..26430b73 100755 --- a/scripts/ci/test.sh +++ b/scripts/ci/test.sh @@ -6,7 +6,7 @@ set -e yarn commitlint-travis -yarn compile -yarn lint yarn test --no-cache --maxWorkers 2 --no-verbose +yarn lint +yarn compile yarn verify diff --git a/tsconfig.json b/tsconfig.json index a4eb40f2..e7b87732 100644 --- a/tsconfig.json +++ b/tsconfig.json @@ -19,7 +19,9 @@ "baseUrl": ".", "paths": { "@feature-hub/*": ["packages/*/src/index.ts"], - "@feature-hub/*/node": ["packages/*/src/node.ts"] + "@feature-hub/module-loader/lib/node": [ + "packages/module-loader/src/node.ts" + ] } } }