diff --git a/.eslintrc.js b/.eslintrc.js
index a8876a1510..da18d19a95 100644
--- a/.eslintrc.js
+++ b/.eslintrc.js
@@ -1,6 +1,6 @@
module.exports = {
extends: [
- require.resolve('@backstage/cli/config/eslint.js'),
+ require.resolve('@backstage/cli/config/eslint'),
'@spotify/eslint-config-oss',
],
};
diff --git a/packages/app/.eslintrc.js b/packages/app/.eslintrc.js
index b321cd0fb8..930c98ee1b 100644
--- a/packages/app/.eslintrc.js
+++ b/packages/app/.eslintrc.js
@@ -1,4 +1,5 @@
module.exports = {
+ extends: [require.resolve('@backstage/cli/config/eslint')],
overrides: [
{
files: ['**/*.ts?(x)'],
diff --git a/packages/cli/.eslintrc.js b/packages/cli/.eslintrc.js
index f3f858836d..4ae4e8d91b 100644
--- a/packages/cli/.eslintrc.js
+++ b/packages/cli/.eslintrc.js
@@ -1,4 +1,5 @@
module.exports = {
+ extends: [require.resolve('@backstage/cli/config/eslint')],
ignorePatterns: ['templates/**'],
rules: {
'no-console': 0,
diff --git a/packages/cli/config/eslint.js b/packages/cli/config/eslint.js
index 983a423a57..230a95c324 100644
--- a/packages/cli/config/eslint.js
+++ b/packages/cli/config/eslint.js
@@ -65,7 +65,7 @@ module.exports = {
},
},
{
- files: ['**/*.test.*', '**/src/setupTests.*'],
+ files: ['*.test.*', 'src/setupTests.*', 'dev/**'],
rules: {
// Tests are allowed to import dev dependencies
'import/no-extraneous-dependencies': [
diff --git a/packages/cli/src/commands/plugin/rollup.config.ts b/packages/cli/src/commands/plugin/rollup.config.ts
index f2c46d1976..e267bb9582 100644
--- a/packages/cli/src/commands/plugin/rollup.config.ts
+++ b/packages/cli/src/commands/plugin/rollup.config.ts
@@ -46,6 +46,17 @@ export default {
json(),
typescript({
include: `${paths.resolveTarget('src')}/**/*.{js,jsx,ts,tsx}`,
+ tsconfigOverride: {
+ // The dev folder is for the local plugin serve, ignore it in the build
+ // If we don't do this we get a folder structure similar to dist/{src,dev}/...
+ exclude: ['dev'],
+ compilerOptions: {
+ // Use absolute path to src dir as root for declarations, relying on the default
+ // seems to produce declaration maps that are relative to dist/ instead of src/
+ // Using a relative path like ../src doesn't work either becaus it will be used as is in subdirs.
+ sourceRoot: paths.resolveTarget('src'),
+ },
+ },
clean: true,
}),
],
diff --git a/packages/cli/src/commands/plugin/serve/config.ts b/packages/cli/src/commands/plugin/serve/config.ts
index c3f850d00a..7381165b5d 100644
--- a/packages/cli/src/commands/plugin/serve/config.ts
+++ b/packages/cli/src/commands/plugin/serve/config.ts
@@ -31,18 +31,19 @@ export function createConfig(paths: Paths): webpack.Configuration {
profile: false,
bail: false,
devtool: 'cheap-module-eval-source-map',
- context: paths.appPath,
+ context: paths.targetPath,
entry: [
`${require.resolve('webpack-dev-server/client')}?/`,
require.resolve('webpack/hot/dev-server'),
- paths.appDevEntry,
+ paths.targetDevEntry,
],
resolve: {
- extensions: ['.ts', '.tsx', '.js', '.jsx'],
+ extensions: ['.ts', '.tsx', '.mjs', '.js', '.jsx'],
+ modules: ['node_modules', paths.targetSrc],
plugins: [
new ModuleScopePlugin(
- [paths.appSrc, paths.appDev],
- [paths.appPackageJson],
+ [paths.targetSrc, paths.targetDev],
+ [paths.targetPackageJson],
),
],
},
@@ -51,7 +52,7 @@ export function createConfig(paths: Paths): webpack.Configuration {
{
test: /\.(tsx?|jsx?|mjs)$/,
enforce: 'pre',
- include: [paths.appSrc, paths.appDev],
+ include: [paths.targetSrc, paths.targetDev],
use: {
loader: 'eslint-loader',
options: {
@@ -61,7 +62,7 @@ export function createConfig(paths: Paths): webpack.Configuration {
},
{
test: /\.(tsx?|jsx?|mjs)$/,
- include: [paths.appSrc, paths.appDev],
+ include: [paths.targetSrc, paths.targetDev],
exclude: /node_modules/,
loader: 'ts-loader',
options: {
@@ -72,7 +73,7 @@ export function createConfig(paths: Paths): webpack.Configuration {
{
test: [/\.bmp$/, /\.gif$/, /\.jpe?g$/, /\.png$/, /\.frag/, /\.xml/],
loader: 'url-loader',
- include: paths.appAssets,
+ include: paths.targetAssets,
options: {
limit: 10000,
name: 'static/media/[name].[hash:8].[ext]',
@@ -98,15 +99,15 @@ export function createConfig(paths: Paths): webpack.Configuration {
},
plugins: [
new HtmlWebpackPlugin({
- template: paths.appHtml,
+ template: paths.targetHtml,
}),
new ForkTsCheckerWebpackPlugin({
- tsconfig: paths.appTsConfig,
+ tsconfig: paths.targetTsConfig,
eslint: true,
eslintOptions: {
parserOptions: {
- project: paths.appTsConfig,
- tsconfigRootDir: paths.appPath,
+ project: paths.targetTsConfig,
+ tsconfigRootDir: paths.targetPath,
},
},
reportFiles: ['**', '!**/__tests__/**', '!**/?(*.)(spec|test).*'],
diff --git a/packages/cli/src/commands/plugin/serve/index.ts b/packages/cli/src/commands/plugin/serve/index.ts
index de6f871b0e..00c7728b63 100644
--- a/packages/cli/src/commands/plugin/serve/index.ts
+++ b/packages/cli/src/commands/plugin/serve/index.ts
@@ -15,7 +15,13 @@
*/
import { startDevServer } from './server';
+import { watchDeps } from 'lib/watchDeps';
export default async () => {
+ await watchDeps({ build: true });
+
await startDevServer();
+
+ // Wait for interrupt signal
+ await new Promise(() => {});
};
diff --git a/packages/cli/src/commands/plugin/serve/paths.ts b/packages/cli/src/commands/plugin/serve/paths.ts
index 732efc46f1..b44a7bff74 100644
--- a/packages/cli/src/commands/plugin/serve/paths.ts
+++ b/packages/cli/src/commands/plugin/serve/paths.ts
@@ -14,39 +14,35 @@
* limitations under the License.
*/
-import { resolve as resolvePath } from 'path';
-import { existsSync, realpathSync } from 'fs';
+import { existsSync } from 'fs';
+import { paths } from 'lib/paths';
export function getPaths() {
- const appDir = realpathSync(process.cwd());
-
- const resolveApp = (path: string) => resolvePath(appDir, path);
- const resolveOwn = (path: string) => resolvePath(__dirname, '..', path);
- const resolveAppModule = (path: string) => {
+ const resolveTargetModule = (path: string) => {
for (const ext of ['mjs', 'js', 'ts', 'tsx', 'jsx']) {
- const filePath = resolveApp(`${path}.${ext}`);
+ const filePath = paths.resolveTarget(`${path}.${ext}`);
if (existsSync(filePath)) {
return filePath;
}
}
- return resolveApp(`${path}.js`);
+ return paths.resolveTarget(`${path}.js`);
};
- let appHtml = resolveApp('dev/index.html');
- if (!existsSync(appHtml)) {
- appHtml = resolveOwn('../../templates/serve_index.html');
+ let targetHtml = paths.resolveTarget('dev/index.html');
+ if (!existsSync(targetHtml)) {
+ targetHtml = paths.resolveOwn('templates/serve_index.html');
}
return {
- appHtml,
- appPath: resolveApp('.'),
- appAssets: resolveApp('assets'),
- appSrc: resolveApp('src'),
- appDev: resolveApp('dev'),
- appDevEntry: resolveAppModule('dev/index'),
- appTsConfig: resolveApp('tsconfig.json'),
- appNodeModules: resolveApp('node_modules'),
- appPackageJson: resolveApp('package.json'),
+ targetHtml,
+ targetPath: paths.resolveTarget('.'),
+ targetAssets: paths.resolveTarget('assets'),
+ targetSrc: paths.resolveTarget('src'),
+ targetDev: paths.resolveTarget('dev'),
+ targetDevEntry: resolveTargetModule('dev/index'),
+ targetTsConfig: paths.resolveTarget('tsconfig.json'),
+ targetNodeModules: paths.resolveTarget('node_modules'),
+ targetPackageJson: paths.resolveTarget('package.json'),
};
}
diff --git a/packages/cli/src/commands/plugin/serve/server.ts b/packages/cli/src/commands/plugin/serve/server.ts
index 850ab00941..066f741406 100644
--- a/packages/cli/src/commands/plugin/serve/server.ts
+++ b/packages/cli/src/commands/plugin/serve/server.ts
@@ -39,6 +39,7 @@ export async function startDevServer() {
const server = new WebpackDevServer(compiler, {
hot: true,
publicPath: '/',
+ historyApiFallback: true,
quiet: true,
https: protocol === 'https',
host,
diff --git a/packages/cli/templates/default-app/.eslintrc.js b/packages/cli/templates/default-app/.eslintrc.js
index dd47f29781..13573efa9c 100644
--- a/packages/cli/templates/default-app/.eslintrc.js
+++ b/packages/cli/templates/default-app/.eslintrc.js
@@ -1,3 +1,3 @@
module.exports = {
- extends: [require.resolve('@backstage/cli/config/eslint.js')],
+ extends: [require.resolve('@backstage/cli/config/eslint')],
};
diff --git a/packages/cli/templates/default-app/packages/app/.eslintrc.js b/packages/cli/templates/default-app/packages/app/.eslintrc.js
new file mode 100644
index 0000000000..13573efa9c
--- /dev/null
+++ b/packages/cli/templates/default-app/packages/app/.eslintrc.js
@@ -0,0 +1,3 @@
+module.exports = {
+ extends: [require.resolve('@backstage/cli/config/eslint')],
+};
diff --git a/packages/cli/templates/default-app/plugins/welcome/.eslintrc.js b/packages/cli/templates/default-app/plugins/welcome/.eslintrc.js
new file mode 100644
index 0000000000..13573efa9c
--- /dev/null
+++ b/packages/cli/templates/default-app/plugins/welcome/.eslintrc.js
@@ -0,0 +1,3 @@
+module.exports = {
+ extends: [require.resolve('@backstage/cli/config/eslint')],
+};
diff --git a/packages/cli/templates/default-plugin/.eslintrc.js b/packages/cli/templates/default-plugin/.eslintrc.js
index dd47f29781..13573efa9c 100644
--- a/packages/cli/templates/default-plugin/.eslintrc.js
+++ b/packages/cli/templates/default-plugin/.eslintrc.js
@@ -1,3 +1,3 @@
module.exports = {
- extends: [require.resolve('@backstage/cli/config/eslint.js')],
+ extends: [require.resolve('@backstage/cli/config/eslint')],
};
diff --git a/packages/core/.eslintrc.js b/packages/core/.eslintrc.js
index 02b430e588..d592a653c8 100644
--- a/packages/core/.eslintrc.js
+++ b/packages/core/.eslintrc.js
@@ -1,5 +1,5 @@
module.exports = {
- extends: [require.resolve('@backstage/cli/config/eslint.js')],
+ extends: [require.resolve('@backstage/cli/config/eslint')],
rules: {
// TODO: add prop types to JS and remove
'react/prop-types': 0,
diff --git a/packages/test-utils-core/.eslintrc.js b/packages/test-utils-core/.eslintrc.js
new file mode 100644
index 0000000000..13573efa9c
--- /dev/null
+++ b/packages/test-utils-core/.eslintrc.js
@@ -0,0 +1,3 @@
+module.exports = {
+ extends: [require.resolve('@backstage/cli/config/eslint')],
+};
diff --git a/packages/test-utils/.eslintrc.js b/packages/test-utils/.eslintrc.js
new file mode 100644
index 0000000000..13573efa9c
--- /dev/null
+++ b/packages/test-utils/.eslintrc.js
@@ -0,0 +1,3 @@
+module.exports = {
+ extends: [require.resolve('@backstage/cli/config/eslint')],
+};
diff --git a/plugins/home-page/.eslintrc.js b/plugins/home-page/.eslintrc.js
index dd47f29781..13573efa9c 100644
--- a/plugins/home-page/.eslintrc.js
+++ b/plugins/home-page/.eslintrc.js
@@ -1,3 +1,3 @@
module.exports = {
- extends: [require.resolve('@backstage/cli/config/eslint.js')],
+ extends: [require.resolve('@backstage/cli/config/eslint')],
};
diff --git a/plugins/home-page/dev/index.tsx b/plugins/home-page/dev/index.tsx
new file mode 100644
index 0000000000..c68b8f7a51
--- /dev/null
+++ b/plugins/home-page/dev/index.tsx
@@ -0,0 +1,54 @@
+/*
+ * Copyright 2020 Spotify AB
+ *
+ * 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 React, { FC } from 'react';
+import ReactDOM from 'react-dom';
+import { BrowserRouter } from 'react-router-dom';
+import HomeIcon from '@material-ui/icons/Home';
+import { ThemeProvider, CssBaseline } from '@material-ui/core';
+import {
+ createApp,
+ SidebarPage,
+ Sidebar,
+ SidebarItem,
+ SidebarSpacer,
+} from '@backstage/core';
+import { lightTheme } from '@backstage/theme';
+import { plugin } from '../src/plugin';
+
+const app = createApp();
+app.registerPlugin(plugin);
+const AppComponent = app.build();
+
+const App: FC<{}> = () => {
+ return (
+
+
+
+
+
+
+
+
+
+
+
+
+
+ );
+};
+
+ReactDOM.render(, document.getElementById('root'));
diff --git a/plugins/home-page/package.json b/plugins/home-page/package.json
index 4cc553b994..28c5dfeeb6 100644
--- a/plugins/home-page/package.json
+++ b/plugins/home-page/package.json
@@ -7,6 +7,7 @@
"private": true,
"scripts": {
"build": "backstage-cli plugin:build",
+ "start": "backstage-cli plugin:serve",
"lint": "backstage-cli lint",
"test": "backstage-cli test",
"clean": "backstage-cli clean"
@@ -18,7 +19,8 @@
"@testing-library/user-event": "^7.1.2",
"@types/jest": "^24.0.0",
"@types/node": "^12.0.0",
- "@types/testing-library__jest-dom": "5.0.2"
+ "@types/testing-library__jest-dom": "5.0.2",
+ "react-router-dom": "^5.1.2"
},
"dependencies": {
"@backstage/core": "^0.1.1-alpha.4",
diff --git a/plugins/home-page/tsconfig.json b/plugins/home-page/tsconfig.json
index 7b73db2f0f..55fa1e2384 100644
--- a/plugins/home-page/tsconfig.json
+++ b/plugins/home-page/tsconfig.json
@@ -1,6 +1,6 @@
{
"extends": "../../tsconfig.json",
- "include": ["src"],
+ "include": ["src", "dev"],
"compilerOptions": {
"baseUrl": "src"
}
diff --git a/plugins/lighthouse/.eslintrc.js b/plugins/lighthouse/.eslintrc.js
index dd47f29781..13573efa9c 100644
--- a/plugins/lighthouse/.eslintrc.js
+++ b/plugins/lighthouse/.eslintrc.js
@@ -1,3 +1,3 @@
module.exports = {
- extends: [require.resolve('@backstage/cli/config/eslint.js')],
+ extends: [require.resolve('@backstage/cli/config/eslint')],
};
diff --git a/plugins/welcome/.eslintrc.js b/plugins/welcome/.eslintrc.js
index dd47f29781..13573efa9c 100644
--- a/plugins/welcome/.eslintrc.js
+++ b/plugins/welcome/.eslintrc.js
@@ -1,3 +1,3 @@
module.exports = {
- extends: [require.resolve('@backstage/cli/config/eslint.js')],
+ extends: [require.resolve('@backstage/cli/config/eslint')],
};