svelte cleanup
This commit is contained in:
parent
0b4b7db0be
commit
dc82afe00d
13 changed files with 6 additions and 467 deletions
|
|
@ -11,6 +11,6 @@
|
||||||
<table-viewer root-path="{{ settings.root_path }}"></table-viewer>
|
<table-viewer root-path="{{ settings.root_path }}"></table-viewer>
|
||||||
</main>
|
</main>
|
||||||
</div>
|
</div>
|
||||||
<script src="{{ settings.root_path }}/js_dist/TableViewer.js"></script>
|
<script src="{{ settings.root_path }}/js_dist/table-viewer.webc.js"></script>
|
||||||
{% endblock %}
|
{% endblock %}
|
||||||
|
|
||||||
|
|
|
||||||
|
|
@ -1,13 +0,0 @@
|
||||||
<!doctype html>
|
|
||||||
<html lang="en">
|
|
||||||
<head>
|
|
||||||
<meta charset="UTF-8" />
|
|
||||||
<link rel="icon" type="image/svg+xml" href="/vite.svg" />
|
|
||||||
<meta name="viewport" content="width=device-width, initial-scale=1.0" />
|
|
||||||
<title>Vite + Svelte + TS</title>
|
|
||||||
</head>
|
|
||||||
<body>
|
|
||||||
<div id="app"></div>
|
|
||||||
<script type="module" src="/src/main.ts"></script>
|
|
||||||
</body>
|
|
||||||
</html>
|
|
||||||
|
|
@ -1,8 +0,0 @@
|
||||||
export function add(a: number, b: number): number {
|
|
||||||
return a + b;
|
|
||||||
}
|
|
||||||
|
|
||||||
// Learn more at https://docs.deno.com/runtime/manual/examples/module_metadata#concepts
|
|
||||||
if (import.meta.main) {
|
|
||||||
console.log("Add 2 + 3 =", add(2, 3));
|
|
||||||
}
|
|
||||||
|
|
@ -1,6 +0,0 @@
|
||||||
import { assertEquals } from "@std/assert";
|
|
||||||
import { add } from "./main.ts";
|
|
||||||
|
|
||||||
Deno.test(function addTest() {
|
|
||||||
assertEquals(add(2, 3), 5);
|
|
||||||
});
|
|
||||||
|
|
@ -1,47 +0,0 @@
|
||||||
<script lang="ts">
|
|
||||||
import svelteLogo from './assets/svelte.svg'
|
|
||||||
import viteLogo from '/vite.svg'
|
|
||||||
import Counter from './lib/Counter.svelte'
|
|
||||||
</script>
|
|
||||||
|
|
||||||
<main>
|
|
||||||
<div>
|
|
||||||
<a href="https://vite.dev" target="_blank" rel="noreferrer">
|
|
||||||
<img src={viteLogo} class="logo" alt="Vite Logo" />
|
|
||||||
</a>
|
|
||||||
<a href="https://svelte.dev" target="_blank" rel="noreferrer">
|
|
||||||
<img src={svelteLogo} class="logo svelte" alt="Svelte Logo" />
|
|
||||||
</a>
|
|
||||||
</div>
|
|
||||||
<h1>Vite + Svelte</h1>
|
|
||||||
|
|
||||||
<div class="card">
|
|
||||||
<Counter />
|
|
||||||
</div>
|
|
||||||
|
|
||||||
<p>
|
|
||||||
Check out <a href="https://github.com/sveltejs/kit#readme" target="_blank" rel="noreferrer">SvelteKit</a>, the official Svelte app framework powered by Vite!
|
|
||||||
</p>
|
|
||||||
|
|
||||||
<p class="read-the-docs">
|
|
||||||
Click on the Vite and Svelte logos to learn more
|
|
||||||
</p>
|
|
||||||
</main>
|
|
||||||
|
|
||||||
<style>
|
|
||||||
.logo {
|
|
||||||
height: 6em;
|
|
||||||
padding: 1.5em;
|
|
||||||
will-change: filter;
|
|
||||||
transition: filter 300ms;
|
|
||||||
}
|
|
||||||
.logo:hover {
|
|
||||||
filter: drop-shadow(0 0 2em #646cffaa);
|
|
||||||
}
|
|
||||||
.logo.svelte:hover {
|
|
||||||
filter: drop-shadow(0 0 2em #ff3e00aa);
|
|
||||||
}
|
|
||||||
.read-the-docs {
|
|
||||||
color: #888;
|
|
||||||
}
|
|
||||||
</style>
|
|
||||||
|
|
@ -1,79 +0,0 @@
|
||||||
:root {
|
|
||||||
font-family: system-ui, Avenir, Helvetica, Arial, sans-serif;
|
|
||||||
line-height: 1.5;
|
|
||||||
font-weight: 400;
|
|
||||||
|
|
||||||
color-scheme: light dark;
|
|
||||||
color: rgba(255, 255, 255, 0.87);
|
|
||||||
background-color: #242424;
|
|
||||||
|
|
||||||
font-synthesis: none;
|
|
||||||
text-rendering: optimizeLegibility;
|
|
||||||
-webkit-font-smoothing: antialiased;
|
|
||||||
-moz-osx-font-smoothing: grayscale;
|
|
||||||
}
|
|
||||||
|
|
||||||
a {
|
|
||||||
font-weight: 500;
|
|
||||||
color: #646cff;
|
|
||||||
text-decoration: inherit;
|
|
||||||
}
|
|
||||||
a:hover {
|
|
||||||
color: #535bf2;
|
|
||||||
}
|
|
||||||
|
|
||||||
body {
|
|
||||||
margin: 0;
|
|
||||||
display: flex;
|
|
||||||
place-items: center;
|
|
||||||
min-width: 320px;
|
|
||||||
min-height: 100vh;
|
|
||||||
}
|
|
||||||
|
|
||||||
h1 {
|
|
||||||
font-size: 3.2em;
|
|
||||||
line-height: 1.1;
|
|
||||||
}
|
|
||||||
|
|
||||||
.card {
|
|
||||||
padding: 2em;
|
|
||||||
}
|
|
||||||
|
|
||||||
#app {
|
|
||||||
max-width: 1280px;
|
|
||||||
margin: 0 auto;
|
|
||||||
padding: 2rem;
|
|
||||||
text-align: center;
|
|
||||||
}
|
|
||||||
|
|
||||||
button {
|
|
||||||
border-radius: 8px;
|
|
||||||
border: 1px solid transparent;
|
|
||||||
padding: 0.6em 1.2em;
|
|
||||||
font-size: 1em;
|
|
||||||
font-weight: 500;
|
|
||||||
font-family: inherit;
|
|
||||||
background-color: #1a1a1a;
|
|
||||||
cursor: pointer;
|
|
||||||
transition: border-color 0.25s;
|
|
||||||
}
|
|
||||||
button:hover {
|
|
||||||
border-color: #646cff;
|
|
||||||
}
|
|
||||||
button:focus,
|
|
||||||
button:focus-visible {
|
|
||||||
outline: 4px auto -webkit-focus-ring-color;
|
|
||||||
}
|
|
||||||
|
|
||||||
@media (prefers-color-scheme: light) {
|
|
||||||
:root {
|
|
||||||
color: #213547;
|
|
||||||
background-color: #ffffff;
|
|
||||||
}
|
|
||||||
a:hover {
|
|
||||||
color: #747bff;
|
|
||||||
}
|
|
||||||
button {
|
|
||||||
background-color: #f9f9f9;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
@ -1 +0,0 @@
|
||||||
<svg xmlns="http://www.w3.org/2000/svg" xmlns:xlink="http://www.w3.org/1999/xlink" aria-hidden="true" role="img" class="iconify iconify--logos" width="26.6" height="32" preserveAspectRatio="xMidYMid meet" viewBox="0 0 256 308"><path fill="#FF3E00" d="M239.682 40.707C211.113-.182 154.69-12.301 113.895 13.69L42.247 59.356a82.198 82.198 0 0 0-37.135 55.056a86.566 86.566 0 0 0 8.536 55.576a82.425 82.425 0 0 0-12.296 30.719a87.596 87.596 0 0 0 14.964 66.244c28.574 40.893 84.997 53.007 125.787 27.016l71.648-45.664a82.182 82.182 0 0 0 37.135-55.057a86.601 86.601 0 0 0-8.53-55.577a82.409 82.409 0 0 0 12.29-30.718a87.573 87.573 0 0 0-14.963-66.244"></path><path fill="#FFF" d="M106.889 270.841c-23.102 6.007-47.497-3.036-61.103-22.648a52.685 52.685 0 0 1-9.003-39.85a49.978 49.978 0 0 1 1.713-6.693l1.35-4.115l3.671 2.697a92.447 92.447 0 0 0 28.036 14.007l2.663.808l-.245 2.659a16.067 16.067 0 0 0 2.89 10.656a17.143 17.143 0 0 0 18.397 6.828a15.786 15.786 0 0 0 4.403-1.935l71.67-45.672a14.922 14.922 0 0 0 6.734-9.977a15.923 15.923 0 0 0-2.713-12.011a17.156 17.156 0 0 0-18.404-6.832a15.78 15.78 0 0 0-4.396 1.933l-27.35 17.434a52.298 52.298 0 0 1-14.553 6.391c-23.101 6.007-47.497-3.036-61.101-22.649a52.681 52.681 0 0 1-9.004-39.849a49.428 49.428 0 0 1 22.34-33.114l71.664-45.677a52.218 52.218 0 0 1 14.563-6.398c23.101-6.007 47.497 3.036 61.101 22.648a52.685 52.685 0 0 1 9.004 39.85a50.559 50.559 0 0 1-1.713 6.692l-1.35 4.116l-3.67-2.693a92.373 92.373 0 0 0-28.037-14.013l-2.664-.809l.246-2.658a16.099 16.099 0 0 0-2.89-10.656a17.143 17.143 0 0 0-18.398-6.828a15.786 15.786 0 0 0-4.402 1.935l-71.67 45.674a14.898 14.898 0 0 0-6.73 9.975a15.9 15.9 0 0 0 2.709 12.012a17.156 17.156 0 0 0 18.404 6.832a15.841 15.841 0 0 0 4.402-1.935l27.345-17.427a52.147 52.147 0 0 1 14.552-6.397c23.101-6.006 47.497 3.037 61.102 22.65a52.681 52.681 0 0 1 9.003 39.848a49.453 49.453 0 0 1-22.34 33.12l-71.664 45.673a52.218 52.218 0 0 1-14.563 6.398"></path></svg>
|
|
||||||
|
Before Width: | Height: | Size: 1.9 KiB |
|
|
@ -1,122 +0,0 @@
|
||||||
<script lang="ts">
|
|
||||||
import {
|
|
||||||
type Coords,
|
|
||||||
type Field,
|
|
||||||
type Row,
|
|
||||||
coords_eq,
|
|
||||||
} from "./field.svelte";
|
|
||||||
|
|
||||||
type Props = {
|
|
||||||
fields: Field[];
|
|
||||||
header_classes?: (string | boolean | undefined)[];
|
|
||||||
on_cell_click?(ev: MouseEvent, coords: Coords): void;
|
|
||||||
on_cell_dblclick?(coords: Coords): void;
|
|
||||||
on_focus?(): void;
|
|
||||||
on_keydown?(ev: KeyboardEvent): void;
|
|
||||||
rows: Row[];
|
|
||||||
root_element?: HTMLDivElement;
|
|
||||||
selections: Coords[];
|
|
||||||
show_headers?: boolean;
|
|
||||||
tab_index?: number;
|
|
||||||
};
|
|
||||||
|
|
||||||
let {
|
|
||||||
fields,
|
|
||||||
header_classes = [],
|
|
||||||
on_cell_click,
|
|
||||||
on_cell_dblclick,
|
|
||||||
on_focus,
|
|
||||||
on_keydown,
|
|
||||||
root_element = $bindable(),
|
|
||||||
rows,
|
|
||||||
selections,
|
|
||||||
show_headers = true,
|
|
||||||
tab_index = 0,
|
|
||||||
}: Props = $props();
|
|
||||||
</script>
|
|
||||||
|
|
||||||
<div
|
|
||||||
bind:this={root_element}
|
|
||||||
class="viewer-table"
|
|
||||||
onfocus={on_focus}
|
|
||||||
onkeydown={on_keydown}
|
|
||||||
role="grid"
|
|
||||||
tabindex={tab_index}
|
|
||||||
>
|
|
||||||
{#if show_headers}
|
|
||||||
<div class={["viewer-table__headers", ...header_classes]}>
|
|
||||||
{#each fields as field, field_index}
|
|
||||||
<div
|
|
||||||
aria-colindex={field_index}
|
|
||||||
class="viewer-header"
|
|
||||||
role="columnheader"
|
|
||||||
style:width={`${field.width_px}px`}
|
|
||||||
>
|
|
||||||
<div>{field.label ?? field.name}</div>
|
|
||||||
</div>
|
|
||||||
{/each}
|
|
||||||
<div class="viewer-header-actions">
|
|
||||||
TODO
|
|
||||||
</div>
|
|
||||||
</div>
|
|
||||||
{/if}
|
|
||||||
<div class="viewer-table__body">
|
|
||||||
{#each rows as row, row_index}
|
|
||||||
<div aria-rowindex={row_index} class="viewer-row" role="row">
|
|
||||||
{#each fields as field, field_index}
|
|
||||||
{@const cell_data = row.data[field_index]}
|
|
||||||
{@const cell_coords: Coords = [row_index, field_index]}
|
|
||||||
{@const cell_selected = selections.some(
|
|
||||||
(sel_coords) => coords_eq(sel_coords, cell_coords),
|
|
||||||
)}
|
|
||||||
<!-- svelte-ignore a11y_click_events_have_key_events -->
|
|
||||||
<div
|
|
||||||
aria-colindex={field_index}
|
|
||||||
aria-rowindex={row_index}
|
|
||||||
aria-selected={cell_selected}
|
|
||||||
class={[
|
|
||||||
"viewer-cell",
|
|
||||||
cell_selected && "viewer-cell--selected",
|
|
||||||
]}
|
|
||||||
onclick={(ev) => on_cell_click?.(ev, cell_coords)}
|
|
||||||
ondblclick={() => on_cell_dblclick?.(cell_coords)}
|
|
||||||
role="gridcell"
|
|
||||||
style:width={`${field.width_px}px`}
|
|
||||||
tabindex="-1"
|
|
||||||
>
|
|
||||||
{#if cell_data.t === "Text"}
|
|
||||||
<div
|
|
||||||
class={[
|
|
||||||
"viewer-cell__content",
|
|
||||||
"viewer-cell__content--text",
|
|
||||||
cell_data.c === null && "viewer-cell__content--null",
|
|
||||||
]}
|
|
||||||
>
|
|
||||||
{cell_data.c}
|
|
||||||
</div>
|
|
||||||
{:else if cell_data.t === "Uuid"}
|
|
||||||
<div
|
|
||||||
class={[
|
|
||||||
"viewer-cell__content",
|
|
||||||
"viewer-cell__content--uuid",
|
|
||||||
cell_data.c === null && "viewer-cell__content--null",
|
|
||||||
]}
|
|
||||||
>
|
|
||||||
{cell_data.c}
|
|
||||||
</div>
|
|
||||||
{:else}
|
|
||||||
<div
|
|
||||||
class={[
|
|
||||||
"viewer-cell__content",
|
|
||||||
"viewer-cell__content--unknown",
|
|
||||||
]}
|
|
||||||
>
|
|
||||||
UNKNOWN
|
|
||||||
</div>
|
|
||||||
{/if}
|
|
||||||
</div>
|
|
||||||
{/each}
|
|
||||||
</div>
|
|
||||||
{/each}
|
|
||||||
</div>
|
|
||||||
</div>
|
|
||||||
|
|
@ -1,10 +0,0 @@
|
||||||
<script lang="ts">
|
|
||||||
let count: number = $state(0)
|
|
||||||
const increment = () => {
|
|
||||||
count += 1
|
|
||||||
}
|
|
||||||
</script>
|
|
||||||
|
|
||||||
<button onclick={increment}>
|
|
||||||
count is {count}
|
|
||||||
</button>
|
|
||||||
|
|
@ -1,9 +0,0 @@
|
||||||
import { mount } from 'svelte'
|
|
||||||
import './app.css'
|
|
||||||
import App from './App.svelte'
|
|
||||||
|
|
||||||
const app = mount(App, {
|
|
||||||
target: document.getElementById('app')!,
|
|
||||||
})
|
|
||||||
|
|
||||||
export default app
|
|
||||||
|
|
@ -1,168 +0,0 @@
|
||||||
<svelte:options customElement={{ tag: "table-viewer", shadow: "none" }} />
|
|
||||||
|
|
||||||
<script lang="ts">
|
|
||||||
import { type Encodable, type Field } from "./field.svelte";
|
|
||||||
|
|
||||||
type Coords = [string, string];
|
|
||||||
interface CommittedChange {
|
|
||||||
coords_initial: Coords;
|
|
||||||
// This will be identical to coords_initial, unless the change altered a
|
|
||||||
// primary key.
|
|
||||||
coords_updated: Coords;
|
|
||||||
value_initial: Encodable;
|
|
||||||
value_updated: Encodable;
|
|
||||||
}
|
|
||||||
|
|
||||||
let selections = $state<Coords[]>([]);
|
|
||||||
let table_focused = $state(false);
|
|
||||||
let editing = $state(false);
|
|
||||||
let editor_input_value = $state("");
|
|
||||||
let committed_changes = $state<CommittedChange[][]>([]);
|
|
||||||
let reverted_changes = $state<CommittedChange[][]>([]);
|
|
||||||
let editor_input_element = $state<HTMLInputElement | undefined>();
|
|
||||||
|
|
||||||
interface GetDataResult {
|
|
||||||
pkeys: string[];
|
|
||||||
data: Record<string, Record<string, Encodable>>;
|
|
||||||
fields: Record<string, Field>;
|
|
||||||
field_names: string[];
|
|
||||||
}
|
|
||||||
|
|
||||||
function coords_eq(a: Coords, b: Coords): boolean {
|
|
||||||
return a[0] === b[0] && a[1] === b[1];
|
|
||||||
}
|
|
||||||
|
|
||||||
function handle_click(ev: MouseEvent, coords: Coords, cell_data: Encodable) {
|
|
||||||
if (!editing) {
|
|
||||||
if (ev.metaKey || ev.ctrlKey) {
|
|
||||||
// TODO
|
|
||||||
// selections = [...selections.filter((prev) => !coords_eq(prev, coords)), coords];
|
|
||||||
// editor_input_value = "";
|
|
||||||
} else {
|
|
||||||
selections = [coords];
|
|
||||||
if (cell_data.t === "Text" || cell_data.t === "Uuid") {
|
|
||||||
editor_input_value = cell_data.c;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
function handle_dblclick(_coords: Coords) {
|
|
||||||
if (!editing) {
|
|
||||||
editing = true;
|
|
||||||
editor_input_element?.focus();
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
function handle_table_focusin() {
|
|
||||||
table_focused = true;
|
|
||||||
}
|
|
||||||
|
|
||||||
function handle_table_focusout() {
|
|
||||||
table_focused = false;
|
|
||||||
}
|
|
||||||
|
|
||||||
function handle_keydown(ev: KeyboardEvent) {
|
|
||||||
if (table_focused && ev.key === "ArrowDown") {
|
|
||||||
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
$effect(() => {
|
|
||||||
document.addEventListener("keydown", handle_keydown);
|
|
||||||
return () => document.removeEventListener("keydown", handle_keydown);
|
|
||||||
});
|
|
||||||
|
|
||||||
const data_promise: Promise<GetDataResult> = fetch("get-data")
|
|
||||||
.then((resp) => resp.json())
|
|
||||||
.then((body) => ({
|
|
||||||
...body,
|
|
||||||
data: Object.fromEntries(body.data.map(({ pkey, data }) => [
|
|
||||||
pkey,
|
|
||||||
Object.fromEntries(body.fields.map(({ name }, i) => [name, data[i]])),
|
|
||||||
])),
|
|
||||||
field_names: body.fields.map(({ name }) => name),
|
|
||||||
fields: Object.fromEntries(body.fields.map((field) => [field.name, field])),
|
|
||||||
}));
|
|
||||||
</script>
|
|
||||||
|
|
||||||
{#await data_promise}
|
|
||||||
<div class="loading-indicator">Loading...</div>
|
|
||||||
{:then data}
|
|
||||||
<div
|
|
||||||
class="viewer-table"
|
|
||||||
onfocusin={handle_table_focusin}
|
|
||||||
onfocusout={handle_table_focusout}
|
|
||||||
role="grid"
|
|
||||||
tabindex="0"
|
|
||||||
>
|
|
||||||
<div class="viewer-table__headers">
|
|
||||||
{#each data.field_names as field_name, field_index}
|
|
||||||
<div
|
|
||||||
aria-colindex={field_index}
|
|
||||||
class="viewer-header"
|
|
||||||
role="columnheader"
|
|
||||||
style:width={`${data.fields[field_name].width_px}px`}
|
|
||||||
>
|
|
||||||
<div>{data.fields[field_name].label ?? field_name}</div>
|
|
||||||
</div>
|
|
||||||
{/each}
|
|
||||||
<div class="viewer-header-actions">
|
|
||||||
TODO
|
|
||||||
</div>
|
|
||||||
</div>
|
|
||||||
<div class="viewer-table__body">
|
|
||||||
{#each data.pkeys as pkey, row_index}
|
|
||||||
<div aria-rowindex={row_index} class="viewer-row" role="row">
|
|
||||||
{#each data.field_names as field_name, field_index}
|
|
||||||
{@const cell_data = data.data[pkey][field_name]}
|
|
||||||
{@const selected = selections.some(
|
|
||||||
([sel_pkey, sel_field]) => sel_pkey === pkey && sel_field === field_name,
|
|
||||||
)}
|
|
||||||
<!-- svelte-ignore a11y_click_events_have_key_events -->
|
|
||||||
<div
|
|
||||||
aria-colindex={field_index}
|
|
||||||
aria-rowindex={row_index}
|
|
||||||
aria-selected={selected}
|
|
||||||
class="viewer-cell"
|
|
||||||
onclick={(ev) => handle_click(ev, [pkey, field_name], cell_data)}
|
|
||||||
ondblclick={() => handle_dblclick([pkey, field_name])}
|
|
||||||
role="gridcell"
|
|
||||||
style:width={`${data.fields[field_name].width_px}px`}
|
|
||||||
tabindex="-1"
|
|
||||||
>
|
|
||||||
{#if cell_data.t === "Text"}
|
|
||||||
<div
|
|
||||||
class={[
|
|
||||||
"viewer-cell__content",
|
|
||||||
"viewer-cell__content--text",
|
|
||||||
selections.some((coords) => coords_eq(coords, [pkey, field_name])) && "viewer-cell__content--selected",
|
|
||||||
]}
|
|
||||||
>
|
|
||||||
{cell_data.c}
|
|
||||||
</div>
|
|
||||||
{:else if cell_data.t === "Uuid"}
|
|
||||||
<div class="viewer-cell__content viewer-cell__content--uuid">{cell_data.c}</div>
|
|
||||||
{:else}
|
|
||||||
<div class="viewer-cell__content viewer-cell__content--unknown">Unknown type</div>
|
|
||||||
{/if}
|
|
||||||
</div>
|
|
||||||
{/each}
|
|
||||||
</div>
|
|
||||||
{/each}
|
|
||||||
</div>
|
|
||||||
</div>
|
|
||||||
<div class="editor">
|
|
||||||
<input
|
|
||||||
class={["editor__input", selections.length !== 1 && "editor__input--hidden"]}
|
|
||||||
onfocus={() => {
|
|
||||||
editing = true;
|
|
||||||
}}
|
|
||||||
role="combobox"
|
|
||||||
bind:this={editor_input_element}
|
|
||||||
bind:value={editor_input_value}
|
|
||||||
/>
|
|
||||||
</div>
|
|
||||||
{:catch err}
|
|
||||||
Error {err}
|
|
||||||
{/await}
|
|
||||||
|
|
@ -7,9 +7,11 @@ export default defineConfig({
|
||||||
plugins: [svelte()],
|
plugins: [svelte()],
|
||||||
build: {
|
build: {
|
||||||
rollupOptions: {
|
rollupOptions: {
|
||||||
input: path.fromFileUrl(
|
input: [
|
||||||
new URL("./src/TableViewer.svelte", import.meta.url),
|
...Deno.readDirSync("./src")
|
||||||
),
|
.filter(({ name }) => name.endsWith(".webc.svelte"))
|
||||||
|
.map(({ name }) => path.join("./src", name)),
|
||||||
|
],
|
||||||
output: {
|
output: {
|
||||||
dir: path.fromFileUrl(new URL("../js_dist", import.meta.url)),
|
dir: path.fromFileUrl(new URL("../js_dist", import.meta.url)),
|
||||||
entryFileNames: "[name].js",
|
entryFileNames: "[name].js",
|
||||||
|
|
|
||||||
Loading…
Add table
Reference in a new issue