Compare commits

..

2 Commits

Author SHA1 Message Date
jaandrle e4e41197b9 🐛 fixes routing 2026-05-20 14:40:47 +02:00
jaandrle 7d6240e28a 🐛 📺 fixes dev server 2026-05-20 14:40:00 +02:00
10 changed files with 137 additions and 56 deletions
+7 -5
View File
@@ -9,15 +9,17 @@ set -eo pipefail # this can be harmful, see https://www.youtube.com/watch?v=4Jo3
# depends on
declare -r server='node_modules/.bin/web-dev-server'
declare -r lint='bs/lint'
declare -r index='index.html'
declare -r server_config='web-dev-server.config.js'
help(){
if ! isHelp "${@}"; then return 0; fi
echoReadmeInfo
cat <<-EOF
Options:
./src Starts the development server (default)
./dist Starts the production server
Defaults:
See server config file: '$server_config'
EOF
$server --help
exit 0
@@ -26,12 +28,12 @@ main(){
help "${@}"
local -r target="${1:-./src}" # ./src or ./dist
if [[ "$target" == './dist' ]]; then
if [[ "$target" =~ 'dist' ]]; then
# console warns because of config file, use npx serve?
$server --root-dir "$target" --app-index $index --open
$server "${@}"
else
$lint --watch --preserveWatchOutput &
$server &
$server "${@}" &
wait
fi
}
+9
View File
@@ -0,0 +1,9 @@
import { css } from "lit";
export const styles = css`
:host {
display: flex;
flex-direction: column;
align-items: center;
justify-content: flex-start;
}
`;
+14
View File
@@ -0,0 +1,14 @@
import { LitElement, html } from "lit";
import { property, customElement } from "lit/decorators.js";
import { styles } from "./index.css.js";
@customElement("app-episode")
export class AppEpisode extends LitElement {
static override styles = styles;
@property({ type: String }) override id = "";
override render() {
return html`
Episode ${this.id}
`;
}
}
+16
View File
@@ -0,0 +1,16 @@
import { route } from "../../core/route.js";
import { html } from "lit";
export const path = "/episodes" as const;
export const routes = route(
{
path: "/episodes/:id",
async enter() {
await import("./index.js");
return true;
},
render({ id }){
return html`<app-episode id=${id}></app-episode>`;
},
},
);
+5 -4
View File
@@ -1,15 +1,16 @@
import { LitElement, html } from "lit";
import { property, customElement } from "lit/decorators.js";
import { customElement } from "lit/decorators.js";
import { styles } from "./index.css.js";
const logo = import.meta.resolve("../../../assets/logo.svg");
const logo = new URL("../../../assets/logo.svg", import.meta.url);
@customElement("app-episodes")
export class AppEpisodes extends LitElement {
static styles = styles;
render() {
static override styles = styles;
override render() {
return html`
<div class="logo"><img alt="open-wc logo" src=${logo} /></div>
<a href="/episodes/1">Episode 1</a>
`;
}
}
+15 -13
View File
@@ -1,16 +1,18 @@
import type { RouteConfig } from "@lit-labs/router";
import { route } from "../core/route.js";
import { routes as routeEpisode } from "./:id/routes.js";
import { html } from "lit";
export const route = {
path: "/episodes" as const,
async enter() {
await import("./index.js");
return true;
export const path = "/episodes" as const;
export const routes = route(
{
path,
async enter() {
await import("./index.js");
return true;
},
render(){
return html`<app-episodes></app-episodes>`;
},
},
render(){
return html`<app-episodes></app-episodes>`;
},
};
export default [
route,
] as RouteConfig[];
routeEpisode,
);
+13
View File
@@ -0,0 +1,13 @@
import type { PathRouteConfig } from "@lit-labs/router";
export function route(...routes: (PathRouteConfig|PathRouteConfig[])[]): PathRouteConfig[] {
return routes.flatMap(function process(route){
if (Array.isArray(route)) // already processed
return route;
const { path, ...rest }= route;
return [
{ path, ...rest },
{ path: path + "/", rest },
];
});
}
+6 -5
View File
@@ -1,17 +1,18 @@
import { LitElement, html } from "lit";
import { property, customElement } from "lit/decorators.js";
import { customElement } from "lit/decorators.js";
import { styles } from "./index.css.js";
import { Router } from "@lit-labs/router";
import { default as routesEpisodes, route as routeEpisodes } from "./app-episodes/routes.js";
import * as routeEpisodes from "./app-episodes/routes.js";
@customElement("app-cfpodcasts")
export class AppCfpodcasts extends LitElement {
static styles = styles;
static override styles = styles;
private _routes = new Router(this, [
{ path: "/", render: () => html`Hello world` },
...routesEpisodes
...routeEpisodes.routes,
]);
render() {
override render() {
console.log(this._routes);
return html`
<main>${this._routes.outlet()}</main>
<nav>
+36 -19
View File
@@ -1,21 +1,38 @@
{
"compilerOptions": {
"target": "es2021",
"module": "NodeNext",
"moduleResolution": "NodeNext",
"noEmitOnError": true,
"lib": ["es2021", "dom", "DOM.Iterable"],
"strict": true,
"allowSyntheticDefaultImports": true,
"experimentalDecorators": true,
"importHelpers": true,
"outDir": "out-tsc",
"sourceMap": true,
"inlineSources": true,
"rootDir": "./",
"incremental": true,
"skipLibCheck": true,
"types": ["mocha"]
},
"include": ["**/*.ts"]
"compilerOptions": {
"verbatimModuleSyntax": true,
"noEmitOnError": true,
"target": "es2021",
"skipLibCheck": true,
"module": "NodeNext",
"moduleResolution": "NodeNext",
"isolatedModules": true,
"strict": true,
"strictBindCallApply": true,
"noUnusedLocals": true,
"noUnusedParameters": true,
"noUncheckedSideEffectImports": true,
"allowUnreachableCode": false,
"noUncheckedIndexedAccess": true,
"noPropertyAccessFromIndexSignature": true,
"erasableSyntaxOnly": true,
"noImplicitOverride": true,
"allowSyntheticDefaultImports": true,
"forceConsistentCasingInFileNames": true,
"useDefineForClassFields": false,
"experimentalDecorators": true,
"importHelpers": true,
"noErrorTruncation": false,
"outDir": "out-tsc",
"sourceMap": true,
"inlineSources": true,
"rootDir": "./",
"incremental": true,
"types": ["mocha"],
"lib": ["es2021", "dom", "DOM.Iterable"]
},
"include": ["**/*.ts"]
}
+16 -10
View File
@@ -1,21 +1,27 @@
// import { hmrPlugin, presets } from "@open-wc/dev-server-hmr";
/** Use Hot Module replacement by adding --hmr to the start command */
const hmr = process.argv.includes("--hmr");
/** Use Hot Module replacement by adding --watch to the start command */
//const hmr = process.argv.includes("--watch");
const [ mode ] = process.argv.slice(2);
const target = mode === "src" // OR "dist"
? {
rootDir: ".",
appIndex: "./index.html",
}
: {
rootDir: "./dist",
appIndex: "./dist/index.html",
};
export default /** @type {import("@web/dev-server").DevServerConfig} */ ({
open: "/",
watch: !hmr,
/** Resolve bare module imports */
nodeResolve: {
open: "/", // SPA routing
nodeResolve: { // Resolve bare module imports
exportConditions: ["browser", "development"],
},
/** Compile JS for older browsers. Requires @web/dev-server-esbuild plugin */
// esbuildTarget: "auto"
// esbuildTarget: "auto" // Compile JS for older browsers. Requires @web/dev-server-esbuild plugin */
/** Set appIndex to enable SPA routing */
appIndex: "./index.html",
...target,
plugins: [
/** Use Hot Module Replacement by uncommenting. Requires @open-wc/dev-server-hmr plugin */