Merge pull request #621 from spotify/rugvip/plugin-serve

Make plugin:serve work and add for home-page plugin + fix declaration maps
This commit is contained in:
Patrik Oldsberg
2020-04-24 18:50:39 +02:00
committed by GitHub
22 changed files with 128 additions and 43 deletions
+1 -1
View File
@@ -1,6 +1,6 @@
module.exports = {
extends: [
require.resolve('@backstage/cli/config/eslint.js'),
require.resolve('@backstage/cli/config/eslint'),
'@spotify/eslint-config-oss',
],
};
+1
View File
@@ -1,4 +1,5 @@
module.exports = {
extends: [require.resolve('@backstage/cli/config/eslint')],
overrides: [
{
files: ['**/*.ts?(x)'],
+1
View File
@@ -1,4 +1,5 @@
module.exports = {
extends: [require.resolve('@backstage/cli/config/eslint')],
ignorePatterns: ['templates/**'],
rules: {
'no-console': 0,
+1 -1
View File
@@ -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': [
@@ -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,
}),
],
@@ -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).*'],
@@ -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(() => {});
};
+17 -21
View File
@@ -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'),
};
}
@@ -39,6 +39,7 @@ export async function startDevServer() {
const server = new WebpackDevServer(compiler, {
hot: true,
publicPath: '/',
historyApiFallback: true,
quiet: true,
https: protocol === 'https',
host,
@@ -1,3 +1,3 @@
module.exports = {
extends: [require.resolve('@backstage/cli/config/eslint.js')],
extends: [require.resolve('@backstage/cli/config/eslint')],
};
@@ -0,0 +1,3 @@
module.exports = {
extends: [require.resolve('@backstage/cli/config/eslint')],
};
@@ -0,0 +1,3 @@
module.exports = {
extends: [require.resolve('@backstage/cli/config/eslint')],
};
@@ -1,3 +1,3 @@
module.exports = {
extends: [require.resolve('@backstage/cli/config/eslint.js')],
extends: [require.resolve('@backstage/cli/config/eslint')],
};
+1 -1
View File
@@ -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,
+3
View File
@@ -0,0 +1,3 @@
module.exports = {
extends: [require.resolve('@backstage/cli/config/eslint')],
};
+3
View File
@@ -0,0 +1,3 @@
module.exports = {
extends: [require.resolve('@backstage/cli/config/eslint')],
};
+1 -1
View File
@@ -1,3 +1,3 @@
module.exports = {
extends: [require.resolve('@backstage/cli/config/eslint.js')],
extends: [require.resolve('@backstage/cli/config/eslint')],
};
+54
View File
@@ -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 (
<ThemeProvider theme={lightTheme}>
<CssBaseline>
<BrowserRouter>
<SidebarPage>
<Sidebar>
<SidebarSpacer />
<SidebarItem icon={HomeIcon} to="/home" text="Home" />
</Sidebar>
<AppComponent />
</SidebarPage>
</BrowserRouter>
</CssBaseline>
</ThemeProvider>
);
};
ReactDOM.render(<App />, document.getElementById('root'));
+3 -1
View File
@@ -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",
+1 -1
View File
@@ -1,6 +1,6 @@
{
"extends": "../../tsconfig.json",
"include": ["src"],
"include": ["src", "dev"],
"compilerOptions": {
"baseUrl": "src"
}
+1 -1
View File
@@ -1,3 +1,3 @@
module.exports = {
extends: [require.resolve('@backstage/cli/config/eslint.js')],
extends: [require.resolve('@backstage/cli/config/eslint')],
};
+1 -1
View File
@@ -1,3 +1,3 @@
module.exports = {
extends: [require.resolve('@backstage/cli/config/eslint.js')],
extends: [require.resolve('@backstage/cli/config/eslint')],
};