swap out monaco and babel-walk with codemirror and @babel/traverse' (#1)

Reviewed-on: #1
This commit is contained in:
Kai 2025-01-13 01:26:39 +00:00
commit 96535f9771
24 changed files with 478 additions and 291 deletions

View file

@ -1,6 +1,7 @@
{
"useTabs": true,
"singleQuote": true,
"semi": false,
"trailingComma": "none",
"printWidth": 100,
"plugins": ["prettier-plugin-svelte"],

BIN
bun.lockb

Binary file not shown.

2
bunfig.toml Normal file
View file

@ -0,0 +1,2 @@
[install.scopes]
"@jsr" = "https://npm.jsr.io"

View file

@ -15,20 +15,25 @@
},
"devDependencies": {
"@babel/parser": "^7.26.5",
"@babel/traverse": "^7.26.5",
"@codemirror/lang-javascript": "^6.2.2",
"@std/async": "npm:@jsr/std__async",
"@sveltejs/adapter-static": "^3.0.6",
"@sveltejs/kit": "^2.0.0",
"@sveltejs/vite-plugin-svelte": "^4.0.0",
"@tailwindcss/postcss": "^4.0.0-beta.9",
"babel-walk": "^3.0.1",
"constrained-editor-plugin": "^1.3.0",
"@types/babel__traverse": "^7.20.6",
"@typescript/vfs": "^1.6.0",
"@valtown/codemirror-ts": "^2.3.1",
"codemirror": "^6.0.1",
"daisyui": "^5.0.0-beta.1",
"esbuild-wasm": "^0.24.2",
"monaco-editor": "^0.52.2",
"prettier": "^3.3.2",
"prettier-plugin-svelte": "^3.2.6",
"sprig": "^1.1.3",
"svelte": "^5.0.0",
"svelte-check": "^4.0.0",
"svelte-codemirror-editor": "^1.4.1",
"tailwindcss": "^4.0.0-beta.9",
"typescript": "^5.0.0",
"vite": "^5.4.11",

View file

@ -1,5 +1,5 @@
export default {
plugins: {
'@tailwindcss/postcss': {},
'@tailwindcss/postcss': {}
}
};
}

View file

@ -11,11 +11,11 @@
color utility to any element that depends on these defaults.
*/
@layer base {
*,
::after,
::before,
::backdrop,
::file-selector-button {
border-color: var(--color-gray-200, currentColor);
}
*,
::after,
::before,
::backdrop,
::file-selector-button {
border-color: var(--color-gray-200, currentColor);
}
}

2
src/app.d.ts vendored
View file

@ -10,4 +10,4 @@ declare global {
}
}
export {};
export {}

View file

@ -1,153 +1,39 @@
<script lang=ts>
import { onMount } from 'svelte';
import * as monaco from 'monaco-editor';
import tsWorker from 'monaco-editor/esm/vs/language/typescript/ts.worker?worker';
import {} from 'sprig/web';
import { constrainedEditor } from 'constrained-editor-plugin';
import { parse } from '@babel/parser';
import { buildProject } from './build/esbuild';
<script lang="ts">
import { onMount } from 'svelte'
import { buildProject } from './build/esbuild'
import checkBabel, { setupBabel } from './text-editor/babel'
import { basicSetup, EditorView } from 'codemirror'
import CodeMirror from 'svelte-codemirror-editor'
import { env, typescriptExtensions } from './text-editor/extensions/typescript'
let { code = $bindable() }: { code: string } = $props()
let editor = $state<EditorView>();
let value = $state<string>(
`/// <reference types="lib.sprig.d.ts" />
async function game(api: sprig.FullSprigAPI): void {
// Code here
}`)
const extensions = [basicSetup, ...typescriptExtensions]
let editorContainer: HTMLDivElement;
let editor: import('monaco-editor').editor.IStandaloneCodeEditor;
// const monaco = await import ('monaco-editor')
// Initial code inside the function
function debounce<A, T = void>(func: (this: T, ...args: A[]) => any, timeout = 300) {
let timer: number;
return function (this: T, ...args: A[]) {
clearTimeout(timer);
timer = setTimeout(() => {
func.apply(this, args);
}, timeout);
};
}
let { code = $bindable() }: { code: string } = $props();
onMount(async () => {
window.build = () => buildProject(code, true);
globalThis.process = {};
globalThis.process.env = {};
const { recursive } = await import('babel-walk');
await addGlobalTypes();
setupEditor();
self.MonacoEnvironment = {
getWorker: function (_: any, label: string) {
return new tsWorker();
}
};
// @ts-expect-error: @babel/types uses process.env without `?.` (ironic that babel is only implemented to warn against using `?.` )
window.process = { env: {} }
// @ts-expect-error
window.env = env
async function addGlobalTypes() {
const sprigTypeDef = (await import('./editorcontext/sprig.d.ts?raw')).default;
monaco.languages.typescript.typescriptDefaults.addExtraLib(
sprigTypeDef,
'context/sprig.d.ts'
);
// IMPLEMENT ONCE v2 IS DONE!
// const sprigsyTypeDef = (await import('./editorcontext/sprigsy.d.ts?raw')).default;
// monaco.languages.typescript.typescriptDefaults.addExtraLib(
// sprigsyTypeDef,
// 'context/sprigsy.d.ts'
// );
}
const disallowedIdentifiers = ['window', 'globalThis'];
type ASTState = {
disallowedWarnings: { identifier: string; loc: [number, number, number, number] }[];
errors: { reason: string; loc: [number, number, number, number] }[];
};
const ASTWalker = recursive<ASTState>({
Identifier(node, state, c) {
if (disallowedIdentifiers.includes(node.name)) {
state.disallowedWarnings.push({
identifier: node.name,
loc: [
node.loc?.start?.line!,
node.loc?.start?.column!,
node.loc?.end?.line!,
node.loc?.end?.column!
]
});
}
},
MemberExpression(node, state, c) {
if (node.optional) {
state.errors.push({
reason: 'optional chaining (?.) will work in the editor but it will not work on the sprig console',
loc: [
node.loc?.start.line!,
node.loc?.start.column!,
node.loc?.end.line!,
node.loc?.end.column!
]
});
}
}
});
const checkBabel = debounce(() => {
let ast;
try {
ast = parse(editor.getValue(), {
plugins: ['typescript']
});
} catch {
return;
}
const state: ASTState = { disallowedWarnings: [], errors: [] };
ASTWalker(ast, state);
state.disallowedWarnings.forEach((v) => {
monaco.editor.setModelMarkers(editor.getModel()!, editor.getId(), [
{
message: `'${v.identifier}' is not allowed.`,
severity: monaco.MarkerSeverity.Error,
startLineNumber: v.loc[0],
startColumn: v.loc[1] + 1,
endLineNumber: v.loc[2],
endColumn: v.loc[3] + 1
}
]);
});
});
function setupEditor() {
editor = monaco.editor.create(editorContainer, {
value: `async function game(api: sprig.FullSprigAPI): void {
// Code here
}`,
language: 'typescript',
automaticLayout: true,
scrollBeyondLastLine: false,
theme: 'vs-dark'
});
const model = editor.getModel()!;
const constrainedInstance = constrainedEditor(monaco);
constrainedInstance.initializeIn(editor);
constrainedInstance.addRestrictionsTo(model, [
{
range: [2, 1, 2, 14], // Range of Function definition
allowMultiline: true,
label: 'funcDefinition'
}
]);
model.updateValueInEditableRanges({
funcDefinition: code
});
editor.onDidChangeModelContent((event) => {
code = model.getValueInEditableRanges().funcDefinition;
checkBabel();
});
}
return () => {
if (editor) {
editor.dispose();
}
};
});
await setupBabel()
})
</script>
<div bind:this={editorContainer} class="editor-container"></div>
<!-- <div bind:this={editorContainer} class="editor-container"></div> -->
<CodeMirror on:ready={(e) => editor = e.detail} on:change={(e) => {
console.log(e)
}} bind:value {extensions} class="editor-container" />
<style lang=postcss>
.editor-container {
<style lang="postcss">
:global(.editor-container) {
@apply h-screen w-full;
}
</style>

View file

@ -0,0 +1,147 @@
<script lang="ts">
import { onMount } from 'svelte'
import { parse } from '@babel/parser'
import { buildProject } from './build/esbuild'
let editorContainer: HTMLDivElement
let editor: import('monaco-editor').editor.IStandaloneCodeEditor
// const monaco = await import ('monaco-editor')
// Initial code inside the function
function debounce<A, T = void>(func: (this: T, ...args: A[]) => any, timeout = 300) {
let timer: number
return function (this: T, ...args: A[]) {
clearTimeout(timer)
timer = setTimeout(() => {
func.apply(this, args)
}, timeout)
}
}
let { code = $bindable() }: { code: string } = $props()
onMount(async () => {
window.build = () => buildProject(code, true)
globalThis.process = {}
globalThis.process.env = {}
const { recursive } = await import('babel-walk')
await addGlobalTypes()
setupEditor()
self.MonacoEnvironment = {
getWorker: function (_: any, label: string) {
return new tsWorker()
}
}
async function addGlobalTypes() {
const sprigTypeDef = (await import('./editorcontext/sprig.d.ts?raw')).default
monaco.languages.typescript.typescriptDefaults.addExtraLib(sprigTypeDef, 'context/sprig.d.ts')
// IMPLEMENT ONCE v2 IS DONE!
// const sprigsyTypeDef = (await import('./editorcontext/sprigsy.d.ts?raw')).default;
// monaco.languages.typescript.typescriptDefaults.addExtraLib(
// sprigsyTypeDef,
// 'context/sprigsy.d.ts'
// );
}
const disallowedIdentifiers = ['window', 'globalThis']
type ASTState = {
disallowedWarnings: { identifier: string; loc: [number, number, number, number] }[]
errors: { reason: string; loc: [number, number, number, number] }[]
}
const ASTWalker = recursive<ASTState>({
Identifier(node, state, c) {
if (disallowedIdentifiers.includes(node.name)) {
state.disallowedWarnings.push({
identifier: node.name,
loc: [
node.loc?.start?.line!,
node.loc?.start?.column!,
node.loc?.end?.line!,
node.loc?.end?.column!
]
})
}
},
MemberExpression(node, state, c) {
if (node.optional) {
state.errors.push({
reason:
'optional chaining (?.) will work in the editor but it will not work on the sprig console',
loc: [
node.loc?.start.line!,
node.loc?.start.column!,
node.loc?.end.line!,
node.loc?.end.column!
]
})
}
}
})
const checkBabel = debounce(() => {
let ast
try {
ast = parse(editor.getValue(), {
plugins: ['typescript']
})
} catch {
return
}
const state: ASTState = { disallowedWarnings: [], errors: [] }
ASTWalker(ast, state)
state.disallowedWarnings.forEach((v) => {
monaco.editor.setModelMarkers(editor.getModel()!, editor.getId(), [
{
message: `'${v.identifier}' is not allowed.`,
severity: monaco.MarkerSeverity.Error,
startLineNumber: v.loc[0],
startColumn: v.loc[1] + 1,
endLineNumber: v.loc[2],
endColumn: v.loc[3] + 1
}
])
})
})
function setupEditor() {
editor = monaco.editor.create(editorContainer, {
value: `async function game(api: sprig.FullSprigAPI): void {
// Code here
}`,
language: 'typescript',
automaticLayout: true,
scrollBeyondLastLine: false,
theme: 'vs-dark'
})
const model = editor.getModel()!
const constrainedInstance = constrainedEditor(monaco)
constrainedInstance.initializeIn(editor)
constrainedInstance.addRestrictionsTo(model, [
{
range: [2, 1, 2, 14], // Range of Function definition
allowMultiline: true,
label: 'funcDefinition'
}
])
model.updateValueInEditableRanges({
funcDefinition: code
})
editor.onDidChangeModelContent((event) => {
code = model.getValueInEditableRanges().funcDefinition
checkBabel()
})
}
return () => {
if (editor) {
editor.dispose()
}
}
})
</script>
<div bind:this={editorContainer} class="editor-container"></div>
<style lang="postcss">
.editor-container {
@apply h-screen w-full;
}
</style>

View file

@ -1,23 +1,23 @@
import { transform, initialize } from 'esbuild-wasm';
import { transform, initialize } from 'esbuild-wasm'
await initialize({
wasmURL: (await import('esbuild-wasm/esbuild.wasm?url')).default
});
})
export async function buildProject(code: string, vanilla: boolean) {
let template = '';
let template = ''
if (vanilla) {
template += `async function game(api) {
${code}
}
console.log("Made with Sprigsy")
game({ addSprite, addText, afterInput, bitmap, clearInterval, clearText, clearTile, clearTimeout, color, getAll, getFirst, getGrid, getTile, height, map, onInput, playTune, setBackground, setInterval, setLegend, setMap, setPushables, setSolids, setTimeout, tilesWith, tune, width })
`;
`
} else {
throw new Error('not implemented');
throw new Error('not implemented')
}
return await transform(template, {
loader: 'ts',
});
loader: 'ts'
})
}

View file

@ -1,5 +1,5 @@
<script lang="ts">
import type { Snippet } from 'svelte';
import type { Snippet } from 'svelte'
let {
tab = $bindable(),
@ -7,17 +7,17 @@
map,
...props
}: {
tab: string | undefined;
disabled?: boolean;
map?: Record<string, string>;
class?: string;
[x: `_${string}`]: Snippet<[]>;
} = $props();
tab: string | undefined
disabled?: boolean
map?: Record<string, string>
class?: string
[x: `_${string}`]: Snippet<[]>
} = $props()
const tabs = Object.fromEntries(
Object.entries(props)
.filter((v) => v[0].startsWith('_'))
.map(([name, snippet]): [string, Snippet<[]>] => [name.replace('_', ''), snippet])
);
)
</script>
<div role="tablist" class="tabs tabs-boxed {props.class}">

View file

@ -1,79 +0,0 @@
/**
* normal sprig api
* this is provided because your project type is
*/
declare namespace sprig {
export declare const VALID_INPUTS: readonly ['w', 's', 'a', 'd', 'i', 'j', 'k', 'l'];
export type InputKey = (typeof VALID_INPUTS)[number];
export interface AddTextOptions {
x?: number;
y?: number;
color?: string;
}
export declare class SpriteType {
type: string;
x: number;
y: number;
readonly dx: number;
readonly dy: number;
remove(): void;
}
export type Rgba = [number, number, number, number];
export interface TextElement {
x: number;
y: number;
color: Rgba;
content: string;
}
export interface GameState {
legend: [string, string][];
texts: TextElement[];
dimensions: {
width: number;
height: number;
};
sprites: SpriteType[];
solids: string[];
pushable: Record<string, string[]>;
background: string | null;
}
export interface PlayTuneRes {
end(): void;
isPlaying(): boolean;
}
// export declare const tones: Record<string, number>;
// export declare const instruments: readonly ["sine", "triangle", "square", "sawtooth"];
export type InstrumentType = (typeof instruments)[number];
// export declare const instrumentKey: Record<string, InstrumentType>;
// export declare const reverseInstrumentKey: Record<"sine" | "triangle" | "square" | "sawtooth", string>;
export type Tune = [number, ...(InstrumentType | number | string)[]][];
export interface FullSprigAPI {
map(template: TemplateStringsArray, ...params: string[]): string;
bitmap(template: TemplateStringsArray, ...params: string[]): string;
color(template: TemplateStringsArray, ...params: string[]): string;
tune(template: TemplateStringsArray, ...params: string[]): string;
setMap(string: string): void;
addText(str: string, opts?: AddTextOptions): void;
clearText(): void;
addSprite(x: number, y: number, type: string): void;
getGrid(): SpriteType[][];
getTile(x: number, y: number): SpriteType[];
tilesWith(...matchingTypes: string[]): SpriteType[][];
clearTile(x: number, y: number): void;
setSolids(types: string[]): void;
setPushables(map: Record<string, string[]>): void;
setBackground(type: string): void;
getFirst(type: string): SpriteType | undefined;
getAll(type?: string): SpriteType[];
width(): number;
height(): number;
setLegend(...bitmaps: [string, string][]): void;
onInput(key: InputKey, fn: () => void): void;
afterInput(fn: () => void): void;
playTune(text: string, n?: number): PlayTuneRes;
setTimeout(fn: TimerHandler, ms: number): number;
setInterval(fn: TimerHandler, ms: number): number;
clearTimeout(id: number): void;
clearInterval(id: number): void;
}
}

View file

@ -1,30 +1,26 @@
import { buildProject } from "$lib/build/esbuild"
import { buildProject } from '$lib/build/esbuild'
enum Capability {
BuildToVite,
ProjectDB
BuildToVite,
ProjectDB
}
export default abstract class Provider {
constructor(
constructor() {}
) {
abstract capabilities(): Capability[]
}
/**
* Builds HTML project
*/
async buildHTML(input: string): Promise<string> {
throw new TypeError('BuildToVite capability is not available')
}
abstract capabilities(): Capability[]
/**
* Builds HTML project
*/
async buildHTML(input: string): Promise<string> {
throw new TypeError("BuildToVite capability is not available")
}
/**
* Build JS
*/
async buildJS(input: string): Promise<string> {
return (await buildProject(input, true)).code
}
/**
* Build JS
*/
async buildJS(input: string): Promise<string> {
return (await buildProject(input, true)).code
}
}

View file

@ -0,0 +1,6 @@
<script lang=ts>
import type { HoverInfo } from "@valtown/codemirror-ts"
let { info }: { info: HoverInfo } = $props();
console.log(info)
</script>

View file

@ -0,0 +1,71 @@
import { debounce } from '@std/async'
import { parse } from '@babel/parser'
let traverse: typeof import("@babel/traverse")['default']
export async function setupBabel() {
traverse = (await import("@babel/traverse")).default
}
const disallowedIdentifiers = ['window', 'globalThis']
type ASTState = {
disallowedWarnings: { identifier: string; loc: [number, number, number, number] }[]
errors: { reason: string; loc: [number, number, number, number] }[]
}
export default debounce((code: string) => {
let ast
try {
ast = parse(code, {
plugins: ['typescript']
})
} catch {
return
}
const state: ASTState = { disallowedWarnings: [], errors: [] }
traverse(ast, {
MemberExpression: {
enter: (path, state) => {
if (path.node.optional) {
state.errors.push({
reason:
'optional chaining (?.) will work in the editor but it will not work on the sprig console',
loc: [
path.node.loc?.start.line!,
path.node.loc?.start.column!,
path.node.loc?.end.line!,
path.node.loc?.end.column!
]
})
}
}
},
Identifier: {
enter: (path, state) => {
if (disallowedIdentifiers.includes(path.node.name)) {
state.disallowedWarnings.push({
identifier: path.node.name,
loc: [
path.node.loc?.start?.line!,
path.node.loc?.start?.column!,
path.node.loc?.end?.line!,
path.node.loc?.end?.column!
]
})
}
}
},
}, undefined, state)
state.disallowedWarnings.forEach((v) => {
monaco.editor.setModelMarkers(editor.getModel()!, editor.getId(), [
{
message: `'${v.identifier}' is not allowed.`,
severity: monaco.MarkerSeverity.Error,
startLineNumber: v.loc[0],
startColumn: v.loc[1] + 1,
endLineNumber: v.loc[2],
endColumn: v.loc[3] + 1
}
])
})
}, 300)

84
src/lib/text-editor/context/sprig.d.ts vendored Normal file
View file

@ -0,0 +1,84 @@
/**
* basic sprig API
* this is provided because your project type is base
*/
declare global {
declare namespace sprig {
export declare const VALID_INPUTS: readonly ['w', 's', 'a', 'd', 'i', 'j', 'k', 'l']
export type InputKey = (typeof VALID_INPUTS)[number]
export interface AddTextOptions {
x?: number
y?: number
color?: string
}
export declare class SpriteType {
type: string
x: number
y: number
readonly dx: number
readonly dy: number
remove(): void
}
export type Rgba = [number, number, number, number]
export interface TextElement {
x: number
y: number
color: Rgba
content: string
}
export interface GameState {
legend: [string, string][]
texts: TextElement[]
dimensions: {
width: number
height: number
}
sprites: SpriteType[]
solids: string[]
pushable: Record<string, string[]>
background: string | null
}
export interface PlayTuneRes {
end(): void
isPlaying(): boolean
}
// export declare const tones: Record<string, number>;
// export declare const instruments: readonly ["sine", "triangle", "square", "sawtooth"];
export type InstrumentType = (typeof instruments)[number]
// export declare const instrumentKey: Record<string, InstrumentType>;
// export declare const reverseInstrumentKey: Record<"sine" | "triangle" | "square" | "sawtooth", string>;
export type Tune = [number, ...(InstrumentType | number | string)[]][]
export interface FullSprigAPI {
map(template: TemplateStringsArray, ...params: string[]): string
bitmap(template: TemplateStringsArray, ...params: string[]): string
color(template: TemplateStringsArray, ...params: string[]): string
tune(template: TemplateStringsArray, ...params: string[]): string
setMap(string: string): void
addText(str: string, opts?: AddTextOptions): void
clearText(): void
addSprite(x: number, y: number, type: string): void
getGrid(): SpriteType[][]
getTile(x: number, y: number): SpriteType[]
tilesWith(...matchingTypes: string[]): SpriteType[][]
clearTile(x: number, y: number): void
setSolids(types: string[]): void
setPushables(map: Record<string, string[]>): void
setBackground(type: string): void
getFirst(type: string): SpriteType | undefined
getAll(type?: string): SpriteType[]
width(): number
height(): number
setLegend(...bitmaps: [string, string][]): void
onInput(key: InputKey, fn: () => void): void
afterInput(fn: () => void): void
playTune(text: string, n?: number): PlayTuneRes
setTimeout(fn: TimerHandler, ms: number): number
setInterval(fn: TimerHandler, ms: number): number
clearTimeout(id: number): void
clearInterval(id: number): void
}
}
}
export {};

View file

@ -1,4 +1,5 @@
/**
* THIS SHOULD NOT BE HERE
* API for sprigsy
* this is provided because your project has sprigsy v2 enabeled
*/
@ -8,6 +9,6 @@ declare namespace sprigsy {
* Retrieve a sprite key for the sprite name
* @param name Sprite name
*/
spriteKeyFor(name: string): string;
spriteKeyFor(name: string): string
}
}

View file

View file

@ -0,0 +1,62 @@
import { javascript } from '@codemirror/lang-javascript'
import { autocompletion } from '@codemirror/autocomplete'
import Tooltip from '../Tooltip.svelte'
import { mount, unmount } from 'svelte'
import {
createDefaultMapFromCDN,
createSystem,
createVirtualTypeScriptEnvironment
} from '@typescript/vfs'
import ts from 'typescript'
import { tsFacet, tsLinter, tsHover, tsAutocomplete, tsSync } from '@valtown/codemirror-ts'
import sprigDeclarations from '$lib/text-editor/context/sprig.d.ts?raw'
const fsMap = await createDefaultMapFromCDN({ target: ts.ScriptTarget.ES2022 }, '5.7.3', true, ts)
fsMap.set('lib.sprig.d.ts', sprigDeclarations)
const system = createSystem(fsMap)
const compilerOpts = {}
const env = createVirtualTypeScriptEnvironment(system, ['lib.sprig.d.ts'], ts, compilerOpts)
console.log(fsMap.entries().toArray())
const path = 'index.ts'
export const typescriptExtensions = [
javascript({
jsx: false,
typescript: true
}),
tsFacet.of({ env, path }),
tsSync(),
tsLinter(),
autocompletion({
override: [tsAutocomplete()],
}),
tsHover({
renderTooltip: (info) => {
console.log("rendering tooltip")
let tooltip: Tooltip;
const div = document.createElement('div')
return {
dom: div,
mount() {
tooltip = mount(Tooltip, {
target: div,
intro: true,
props: {
info
}
})
},
destroy() {
unmount(tooltip, { outro: true })
}
}
}
})
]
export {
env
}

View file

@ -1,6 +1,6 @@
<script lang="ts">
import '../app.css';
const { children } = $props();
import '../app.css'
const { children } = $props()
</script>
{@render children()}

View file

@ -1,2 +1,3 @@
export const csr = true;
export const prerender = true;
export const csr = true
export const prerender = true
export const ssr = false

View file

@ -1,8 +1,11 @@
<script>
import CodeEditor from '$lib/CodeEditor.svelte';
import Tab from '$lib/components/Tab.svelte';
let tab = 'code';
let code = '';
import CodeEditor from '$lib/CodeEditor.svelte'
import Tab from '$lib/components/Tab.svelte'
let tab = 'code'
let code = ''
function keypress() {
debugger;
}
</script>
<div class="flex h-full! w-full select-none flex-col bg-base-100">
@ -56,3 +59,5 @@
This will have the game screen
{/if}
</div>
<svelte:window on:keypress={keypress}></svelte:window>

View file

@ -1,18 +1,17 @@
import adapter from '@sveltejs/adapter-static';
import { vitePreprocess } from '@sveltejs/vite-plugin-svelte';
import adapter from '@sveltejs/adapter-static'
import { vitePreprocess } from '@sveltejs/vite-plugin-svelte'
/** @type {import('@sveltejs/kit').Config} */
const config = {
// Consult https://svelte.dev/docs/kit/integrations
// for more information about preprocessors
preprocess: vitePreprocess(),
kit: {
// adapter-auto only supports some environments, see https://svelte.dev/docs/kit/adapter-auto for a list.
// If your environment is not supported, or you settled on a specific environment, switch out the adapter.
// See https://svelte.dev/docs/kit/adapters for more information about adapters.
adapter: adapter()
}
};
}
export default config;
export default config

View file

@ -1,9 +1,9 @@
import { sveltekit } from '@sveltejs/kit/vite';
import { defineConfig } from 'vite';
import { sveltekit } from '@sveltejs/kit/vite'
import { defineConfig } from 'vite'
export default defineConfig({
plugins: [sveltekit()],
build: {
target: ['es2022']
}
});
})