diff --git a/.gitignore b/.gitignore index f5794babbc..a1eb87e8d5 100644 --- a/.gitignore +++ b/.gitignore @@ -116,3 +116,6 @@ dist # Stores VSCode versions used for testing VSCode extensions .vscode-test + +# Temporary change files created by Vim +*.swp diff --git a/packages/app/package.json b/packages/app/package.json index 6aa82a0b36..1c643b437d 100644 --- a/packages/app/package.json +++ b/packages/app/package.json @@ -15,6 +15,7 @@ "@backstage/plugin-sentry": "^0.1.1-alpha.9", "@backstage/plugin-tech-radar": "^0.1.1-alpha.9", "@backstage/plugin-welcome": "^0.1.1-alpha.9", + "@backstage/test-utils": "^0.1.1-alpha.9", "@backstage/theme": "^0.1.1-alpha.9", "@material-ui/core": "^4.9.1", "@material-ui/icons": "^4.9.1", @@ -22,6 +23,7 @@ "react": "^16.12.0", "react-dom": "^16.12.0", "react-hot-loader": "^4.12.21", + "react-router": "6.0.0-alpha.5", "react-router-dom": "6.0.0-alpha.5", "react-use": "^14.2.0", "zen-observable": "^0.8.15" diff --git a/packages/app/src/App.test.tsx b/packages/app/src/App.test.tsx index 79f78e45e0..65e8ff64e6 100644 --- a/packages/app/src/App.test.tsx +++ b/packages/app/src/App.test.tsx @@ -15,23 +15,24 @@ */ import React from 'react'; -import { render } from '@testing-library/react'; +import { renderWithEffects } from '@backstage/test-utils'; import App from './App'; describe('App', () => { - beforeAll(() => { - Object.defineProperty(window, 'matchMedia', { - value: jest.fn(() => { - return { - matches: true, - addListener: jest.fn(), - removeListener: jest.fn(), - }; - }), + it('should render', async () => { + Object.defineProperty(process.env, 'APP_CONFIG', { + configurable: true, + value: [ + { + data: { + app: { title: 'Test' }, + }, + context: 'test', + }, + ], }); - }); - it('should render', () => { - const rendered = render(); + + const rendered = await renderWithEffects(); expect(rendered.baseElement).toBeInTheDocument(); }); }); diff --git a/packages/backend-common/src/hot.ts b/packages/backend-common/src/hot.ts index 3d4252b378..bd6454c537 100644 --- a/packages/backend-common/src/hot.ts +++ b/packages/backend-common/src/hot.ts @@ -14,10 +14,38 @@ * limitations under the License. */ +// Find all active hot module APIs of all ancestors of a module, including the module itself +function findAllAncestors(_module: NodeModule): NodeModule[] { + const ancestors = new Array(); + const parentIds = new Set(); + + function add(id: string | number, m: NodeModule) { + if (parentIds.has(id)) { + return; + } + parentIds.add(id); + ancestors.push(m); + + for (const parentId of (m as any).parents) { + const parent = require.cache[parentId]; + if (parent) { + add(parentId, parent); + } + } + } + + add(_module.id, _module); + + return ancestors; +} + /** - * This function allows devs to cleanup - * ongoing effects when module gets hot-reloaded + * useHotCleanup allows cleanup of ongoing effects when a module is + * hot-reloaded during development. The cleanup function will be called + * whenever the module itself or any of its parent modules is hot-reloaded. + * * Useful for cleaning intervals, timers, requests etc + * * @example * ```ts * const intervalId = setInterval(doStuff, 1000); @@ -28,9 +56,19 @@ */ export function useHotCleanup(_module: NodeModule, cancelEffect: () => void) { if (_module.hot) { - _module.hot.addDisposeHandler(() => { - cancelEffect(); - }); + const ancestors = findAllAncestors(_module); + let cancelled = false; + + const handler = () => { + if (!cancelled) { + cancelled = true; + cancelEffect(); + } + }; + + for (const m of ancestors) { + m.hot?.addDisposeHandler(handler); + } } } diff --git a/packages/backend/src/plugins/auth.ts b/packages/backend/src/plugins/auth.ts index a9c687cbc4..b24dd6ca6b 100644 --- a/packages/backend/src/plugins/auth.ts +++ b/packages/backend/src/plugins/auth.ts @@ -19,7 +19,8 @@ import { PluginEnvironment } from '../types'; export default async function createPlugin({ logger, + database, config, }: PluginEnvironment) { - return await createRouter({ logger, config }); + return await createRouter({ logger, config, database }); } diff --git a/packages/cli/src/lib/bundler/config.ts b/packages/cli/src/lib/bundler/config.ts index 6fe8092e50..aab244f7e9 100644 --- a/packages/cli/src/lib/bundler/config.ts +++ b/packages/cli/src/lib/bundler/config.ts @@ -178,8 +178,7 @@ export function createBackendConfig( context: paths.targetPath, entry: [ 'webpack/hot/poll?100', - paths.targetEntry, - ...(paths.targetRunFile ? [paths.targetRunFile] : []), + paths.targetRunFile ? paths.targetRunFile : paths.targetEntry, ], resolve: { extensions: ['.ts', '.tsx', '.mjs', '.js', '.jsx'], diff --git a/packages/cli/templates/default-app/package.json.hbs b/packages/cli/templates/default-app/package.json.hbs index a96061a5bd..c70e00e4d0 100644 --- a/packages/cli/templates/default-app/package.json.hbs +++ b/packages/cli/templates/default-app/package.json.hbs @@ -31,6 +31,9 @@ "lerna": "^3.20.2", "prettier": "^1.19.1" }, + "resolutions": { + "**/esbuild": "0.5.3" + }, "prettier": "@spotify/prettier-config", "lint-staged": { "*.{js,jsx,ts,tsx}": [ diff --git a/packages/cli/templates/default-app/packages/app/package.json.hbs b/packages/cli/templates/default-app/packages/app/package.json.hbs index 346e09a76a..79120e0d7e 100644 --- a/packages/cli/templates/default-app/packages/app/package.json.hbs +++ b/packages/cli/templates/default-app/packages/app/package.json.hbs @@ -8,10 +8,12 @@ "@material-ui/lab": "4.0.0-alpha.45", "@backstage/cli": "^{{version}}", "@backstage/core": "^{{version}}", + "@backstage/test-utils": "^{{version}}", "@backstage/theme": "^{{version}}", "plugin-welcome": "0.0.0", "react": "^16.13.1", "react-dom": "^16.13.1", + "react-router": "6.0.0-alpha.5", "react-router-dom": "6.0.0-alpha.5", "react-use": "^14.2.0" }, diff --git a/packages/cli/templates/default-app/packages/app/public/index.html b/packages/cli/templates/default-app/packages/app/public/index.html index 3d01107696..ea9208ca57 100644 --- a/packages/cli/templates/default-app/packages/app/public/index.html +++ b/packages/cli/templates/default-app/packages/app/public/index.html @@ -8,47 +8,38 @@ name="description" content="Backstage is an open platform for building developer portals" /> - + - - - + + - Backstage + <%= app.title %> - +