Browse Source

Split out editor - reduce bundle size significantly

fix #39
mj-deploy
Standa Lukeš 4 years ago
parent
commit
623cb491f0
  1. 1
      frontend/package.json
  2. 19
      frontend/public/editor.html
  3. 54
      frontend/rollup.config.js
  4. 30
      frontend/src/App.svelte
  5. 27
      frontend/src/Editor-main.svelte
  6. 2
      frontend/src/Graph.svelte
  7. 8
      frontend/src/editor-main.ts
  8. 3
      frontend/src/main.ts
  9. 1
      frontend/src/typescripthack.d.ts
  10. 3
      frontend/tsconfig.json
  11. 10
      frontend/yarn.lock

1
frontend/package.json

@ -11,6 +11,7 @@
"devDependencies": { "devDependencies": {
"@rollup/plugin-commonjs": "^14.0.0", "@rollup/plugin-commonjs": "^14.0.0",
"@rollup/plugin-node-resolve": "^8.4.0", "@rollup/plugin-node-resolve": "^8.4.0",
"@rollup/plugin-replace": "^2.3.3",
"@rollup/plugin-typescript": "^6.0.0", "@rollup/plugin-typescript": "^6.0.0",
"@testing-library/svelte": "^3.0.0", "@testing-library/svelte": "^3.0.0",
"@tsconfig/svelte": "^1.0.0", "@tsconfig/svelte": "^1.0.0",

19
frontend/public/editor.html

@ -0,0 +1,19 @@
<!DOCTYPE html>
<html lang="en">
<head>
<meta charset='utf-8'>
<meta name='viewport' content='width=device-width,initial-scale=1'>
<title>Editor úloh</title>
<link rel='icon' type='image/png' href='/favicon.png'>
<link rel='stylesheet' href='/global.css'>
<link rel='stylesheet' href='/build/editor.css'>
<script type="module" src='/build/editor.js'></script>
</head>
<body style="padding: 0">
<div id="svelte-root" style="position: relative;"></div>
</body>
</html>

54
frontend/rollup.config.js

@ -5,13 +5,13 @@ import livereload from 'rollup-plugin-livereload';
import { terser } from 'rollup-plugin-terser'; import { terser } from 'rollup-plugin-terser';
import sveltePreprocess from 'svelte-preprocess'; import sveltePreprocess from 'svelte-preprocess';
import typescript from '@rollup/plugin-typescript'; import typescript from '@rollup/plugin-typescript';
import replace from '@rollup/plugin-replace'
const production = !process.env.ROLLUP_WATCH; const production = !process.env.ROLLUP_WATCH;
const halfProduction = production || !!process.env.HALF_PRODUCTION; const halfProduction = production || !!process.env.HALF_PRODUCTION;
function serve() { function serve() {
let server; let server;
function toExit() { function toExit() {
if (server) server.kill(0); if (server) server.kill(0);
} }
@ -30,33 +30,19 @@ function serve() {
}; };
} }
export default { function plugins(editor) {
input: 'src/main.ts', return [
output: {
sourcemap: true,
format: 'es',
name: 'app',
file: 'public/build/bundle.js'
},
plugins: [
// nodePolyfills(),
svelte({ svelte({
// enable run-time checks when not in production // enable run-time checks when not in production
dev: !halfProduction, dev: !halfProduction,
// we'll extract any component CSS out into // we'll extract any component CSS out into
// a separate file - better for performance // a separate file - better for performance
css: css => { css: css => {
css.write('bundle.css'); css.write(editor ? 'editor.css' : 'bundle.css');
}, },
preprocess: sveltePreprocess(), preprocess: sveltePreprocess(),
}), }),
// If you have external dependencies installed from
// npm, you'll most likely need these plugins. In
// some cases you'll need additional configuration -
// consult the documentation for details:
// https://github.com/rollup/plugins/tree/master/packages/commonjs
resolve({ resolve({
browser: true, browser: true,
dedupe: ['svelte'] dedupe: ['svelte']
@ -66,20 +52,42 @@ export default {
sourceMap: !halfProduction, sourceMap: !halfProduction,
inlineSources: !halfProduction inlineSources: !halfProduction
}), }),
replace({
"allowEditor": false,
}),
// In dev mode, call `npm run start` once // In dev mode, call `npm run start` once
// the bundle has been generated // the bundle has been generated
!production && serve(), !production && !editor && serve(),
// Watch the `public` directory and refresh the // Watch the `public` directory and refresh the
// browser on changes when not in production // browser on changes when not in production
!halfProduction && livereload('public'), !halfProduction && !editor && livereload('public'),
// If we're building for production (npm run build // If we're building for production (npm run build
// instead of npm run dev), minify // instead of npm run dev), minify
halfProduction && terser() // halfProduction && terser()
], ]
}
export default [{
input: 'src/main.ts',
output: {
sourcemap: !halfProduction,
format: 'es',
file: 'public/build/bundle.js'
},
plugins: plugins(false),
watch: { watch: {
clearScreen: false clearScreen: false
} }
}; },
{
input: 'src/editor-main.ts',
output: {
sourcemap: !halfProduction,
format: 'es',
file: 'public/build/editor.js'
},
plugins: plugins(true)
}];

30
frontend/src/App.svelte

@ -4,13 +4,9 @@
import type { TasksFile, TaskDescriptor } from "./tasks"; import type { TasksFile, TaskDescriptor } from "./tasks";
import TasksLoader from "./TasksLoader.svelte"; import TasksLoader from "./TasksLoader.svelte";
import TaskPanel from "./TaskPanel.svelte"; import TaskPanel from "./TaskPanel.svelte";
import Editor from "./Editor.svelte";
import Modal from "svelte-simple-modal";
const tasksPromise: Promise<TasksFile> = loadTasks(); const tasksPromise: Promise<TasksFile> = loadTasks();
let taskPanel: TaskPanel;
// react to hash changes // react to hash changes
let hash = window.location.hash.substr(1); let hash = window.location.hash.substr(1);
window.onhashchange = () => { window.onhashchange = () => {
@ -28,21 +24,13 @@
</style> </style>
<main> <main>
<Modal> <TasksLoader promise={tasksPromise} let:data={t}>
{#if hash == 'editor'} <TaskPanel tasks={t} {selectedTaskId} />
<TasksLoader promise={tasksPromise} let:data={t}> <div style="height: 100%">
<Editor tasks={t} /> <Graph
</TasksLoader> tasks={t}
{:else} on:closeTask={() => { location.hash = ""}}
<TasksLoader promise={tasksPromise} let:data={t}> on:selectTask={(e) => { if (e.detail.type != "label") (location.hash = `#task/${e.detail.id}`)}}/>
<TaskPanel tasks={t} bind:this={taskPanel} {selectedTaskId} /> </div>
<div style="height: 100%"> </TasksLoader>
<Graph
tasks={t}
on:selectTask={(e) => { if (e.detail.type != "label") (location.hash = `#task/${e.detail.id}`)}}
on:closeTask={() => {location.hash = '#'}} />
</div>
</TasksLoader>
{/if}
</Modal>
</main> </main>

27
frontend/src/Editor-main.svelte

@ -0,0 +1,27 @@
<script type="ts">
import Editor from "./Editor.svelte";
import Modal from "svelte-simple-modal";
import { loadTasks } from "./tasks";
import type { TasksFile, TaskDescriptor } from "./tasks";
import TasksLoader from "./TasksLoader.svelte";
const tasksPromise: Promise<TasksFile> = loadTasks();
</script>
<style>
main {
text-align: center;
margin: 0 auto;
min-height: 420px;
}
</style>
<main>
<Modal>
<TasksLoader promise={tasksPromise} let:data={t}>
<Editor tasks={t}/>
</TasksLoader>
</Modal>
</main>

2
frontend/src/Graph.svelte

@ -6,8 +6,6 @@
import type { TasksFile, TaskDescriptor } from "./tasks"; import type { TasksFile, TaskDescriptor } from "./tasks";
import { createEdges } from "./tasks"; import { createEdges } from "./tasks";
import { taskStatuses } from "./task-status-cache"; import { taskStatuses } from "./task-status-cache";
import { grabAssignment } from "./ksp-task-grabber";
import TaskDetailEditor from "./TaskDetailEditor.svelte";
export let tasks: TasksFile; export let tasks: TasksFile;
export let nodeDraggingEnabled: boolean = false; export let nodeDraggingEnabled: boolean = false;

8
frontend/src/editor-main.ts

@ -0,0 +1,8 @@
import Editor from './Editor-main.svelte';
import { loadTasks } from './tasks';
import type { TasksFile } from './tasks'
const app = new Editor({
target: document.getElementById("svelte-root")!,
props: {}
});

3
frontend/src/main.ts

@ -2,8 +2,7 @@ import App from './App.svelte';
const app = new App({ const app = new App({
target: document.getElementById("svelte-root")!, target: document.getElementById("svelte-root")!,
props: { props: { }
}
}); });
export default app; export default app;

1
frontend/src/typescripthack.d.ts

@ -0,0 +1 @@
declare const allowEditor: boolean

3
frontend/tsconfig.json

@ -3,7 +3,8 @@
"compilerOptions": { "compilerOptions": {
// "target": "ES2019" // "target": "ES2019"
"strict": true, "strict": true,
"types": ["jest", "node"] "types": ["jest", "node"],
"module": "esnext"
}, },
"include": ["src/**/*"], "include": ["src/**/*"],

10
frontend/yarn.lock

@ -524,6 +524,14 @@
is-module "^1.0.0" is-module "^1.0.0"
resolve "^1.17.0" resolve "^1.17.0"
"@rollup/plugin-replace@^2.3.3":
version "2.3.3"
resolved "https://registry.yarnpkg.com/@rollup/plugin-replace/-/plugin-replace-2.3.3.tgz#cd6bae39444de119f5d905322b91ebd4078562e7"
integrity sha512-XPmVXZ7IlaoWaJLkSCDaa0Y6uVo5XQYHhiMFzOd5qSv5rE+t/UJToPIOE56flKIxBFQI27ONsxb7dqHnwSsjKQ==
dependencies:
"@rollup/pluginutils" "^3.0.8"
magic-string "^0.25.5"
"@rollup/plugin-typescript@^6.0.0": "@rollup/plugin-typescript@^6.0.0":
version "6.0.0" version "6.0.0"
resolved "https://registry.yarnpkg.com/@rollup/plugin-typescript/-/plugin-typescript-6.0.0.tgz#08635d9d04dc3a099ef0150c289ba5735200bc63" resolved "https://registry.yarnpkg.com/@rollup/plugin-typescript/-/plugin-typescript-6.0.0.tgz#08635d9d04dc3a099ef0150c289ba5735200bc63"
@ -3215,7 +3223,7 @@ lower-case@^2.0.1:
dependencies: dependencies:
tslib "^1.10.0" tslib "^1.10.0"
magic-string@^0.25.2: magic-string@^0.25.2, magic-string@^0.25.5:
version "0.25.7" version "0.25.7"
resolved "https://registry.yarnpkg.com/magic-string/-/magic-string-0.25.7.tgz#3f497d6fd34c669c6798dcb821f2ef31f5445051" resolved "https://registry.yarnpkg.com/magic-string/-/magic-string-0.25.7.tgz#3f497d6fd34c669c6798dcb821f2ef31f5445051"
integrity sha512-4CrMT5DOHTDk4HYDlzmwu4FVCcIYI8gauveasrdCu2IKIFOJ3f0v/8MDGJCDL9oD2ppz/Av1b0Nj345H9M+XIA== integrity sha512-4CrMT5DOHTDk4HYDlzmwu4FVCcIYI8gauveasrdCu2IKIFOJ3f0v/8MDGJCDL9oD2ppz/Av1b0Nj345H9M+XIA==