updated task
This commit is contained in:
@@ -0,0 +1,24 @@
|
||||
# Logs
|
||||
logs
|
||||
*.log
|
||||
npm-debug.log*
|
||||
yarn-debug.log*
|
||||
yarn-error.log*
|
||||
pnpm-debug.log*
|
||||
lerna-debug.log*
|
||||
|
||||
node_modules
|
||||
dist
|
||||
dist-ssr
|
||||
*.local
|
||||
|
||||
# Editor directories and files
|
||||
.vscode/*
|
||||
!.vscode/extensions.json
|
||||
.idea
|
||||
.DS_Store
|
||||
*.suo
|
||||
*.ntvs*
|
||||
*.njsproj
|
||||
*.sln
|
||||
*.sw?
|
||||
@@ -0,0 +1,28 @@
|
||||
import js from '@eslint/js';
|
||||
import globals from 'globals';
|
||||
import reactHooks from 'eslint-plugin-react-hooks';
|
||||
import reactRefresh from 'eslint-plugin-react-refresh';
|
||||
import tseslint from 'typescript-eslint';
|
||||
|
||||
export default tseslint.config(
|
||||
{ ignores: ['dist'] },
|
||||
{
|
||||
extends: [js.configs.recommended, ...tseslint.configs.recommended],
|
||||
files: ['**/*.{ts,tsx}'],
|
||||
languageOptions: {
|
||||
ecmaVersion: 2020,
|
||||
globals: globals.browser,
|
||||
},
|
||||
plugins: {
|
||||
'react-hooks': reactHooks,
|
||||
'react-refresh': reactRefresh,
|
||||
},
|
||||
rules: {
|
||||
...reactHooks.configs.recommended.rules,
|
||||
'react-refresh/only-export-components': [
|
||||
'warn',
|
||||
{ allowConstantExport: true },
|
||||
],
|
||||
},
|
||||
}
|
||||
);
|
||||
@@ -0,0 +1,13 @@
|
||||
<!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 + React + TS</title>
|
||||
</head>
|
||||
<body>
|
||||
<div id="root"></div>
|
||||
<script type="module" src="/src/main.tsx"></script>
|
||||
</body>
|
||||
</html>
|
||||
Generated
+4106
File diff suppressed because it is too large
Load Diff
@@ -0,0 +1,36 @@
|
||||
{
|
||||
"name": "vite-react-typescript-starter",
|
||||
"private": true,
|
||||
"version": "0.0.0",
|
||||
"type": "module",
|
||||
"scripts": {
|
||||
"dev": "vite",
|
||||
"build": "vite build",
|
||||
"lint": "eslint .",
|
||||
"preview": "vite preview"
|
||||
},
|
||||
"dependencies": {
|
||||
"lucide-react": "^0.344.0",
|
||||
"react": "^18.3.1",
|
||||
"react-dom": "^18.3.1",
|
||||
"react-router-dom": "^6.22.3",
|
||||
"prismjs": "^1.29.0"
|
||||
},
|
||||
"devDependencies": {
|
||||
"@eslint/js": "^9.9.1",
|
||||
"@types/react": "^18.3.5",
|
||||
"@types/react-dom": "^18.3.0",
|
||||
"@types/prismjs": "^1.26.3",
|
||||
"@vitejs/plugin-react": "^4.3.1",
|
||||
"autoprefixer": "^10.4.18",
|
||||
"eslint": "^9.9.1",
|
||||
"eslint-plugin-react-hooks": "^5.1.0-rc.0",
|
||||
"eslint-plugin-react-refresh": "^0.4.11",
|
||||
"globals": "^15.9.0",
|
||||
"postcss": "^8.4.35",
|
||||
"tailwindcss": "^3.4.1",
|
||||
"typescript": "^5.5.3",
|
||||
"typescript-eslint": "^8.3.0",
|
||||
"vite": "^5.4.2"
|
||||
}
|
||||
}
|
||||
@@ -0,0 +1,6 @@
|
||||
export default {
|
||||
plugins: {
|
||||
tailwindcss: {},
|
||||
autoprefixer: {},
|
||||
},
|
||||
};
|
||||
@@ -0,0 +1,17 @@
|
||||
import React from 'react';
|
||||
import { BrowserRouter, Routes, Route } from 'react-router-dom';
|
||||
import { Landing } from './pages/Landing';
|
||||
import { Editor } from './pages/Editor';
|
||||
|
||||
function App() {
|
||||
return (
|
||||
<BrowserRouter>
|
||||
<Routes>
|
||||
<Route path="/" element={<Landing />} />
|
||||
<Route path="/editor" element={<Editor />} />
|
||||
</Routes>
|
||||
</BrowserRouter>
|
||||
);
|
||||
}
|
||||
|
||||
export default App;
|
||||
@@ -0,0 +1,23 @@
|
||||
import React from 'react';
|
||||
import { ChevronRight } from 'lucide-react';
|
||||
|
||||
interface BreadcrumbProps {
|
||||
path: string;
|
||||
}
|
||||
|
||||
export function Breadcrumb({ path }: BreadcrumbProps) {
|
||||
const parts = path.split('/').filter(Boolean);
|
||||
|
||||
return (
|
||||
<div className="flex items-center gap-1 px-3 py-1 bg-[#1E1E1E] text-gray-400 text-sm border-b border-gray-800">
|
||||
{parts.map((part, index) => (
|
||||
<React.Fragment key={index}>
|
||||
{index > 0 && <ChevronRight className="w-3 h-3" />}
|
||||
<span className="hover:text-white cursor-pointer">
|
||||
{part}
|
||||
</span>
|
||||
</React.Fragment>
|
||||
))}
|
||||
</div>
|
||||
);
|
||||
}
|
||||
@@ -0,0 +1,51 @@
|
||||
import React from 'react';
|
||||
import { MessageSquare, Send } from 'lucide-react';
|
||||
|
||||
export function Chat() {
|
||||
const [messages, setMessages] = React.useState([
|
||||
{ role: 'assistant', content: 'Hello! I\'m Bolt, your AI programming assistant. How can I help you today?' }
|
||||
]);
|
||||
|
||||
return (
|
||||
<div className="h-full flex flex-col bg-white">
|
||||
<div className="flex items-center gap-2 p-3 border-b">
|
||||
<MessageSquare className="w-5 h-5" />
|
||||
<span className="font-medium">Chat</span>
|
||||
</div>
|
||||
|
||||
<div className="flex-1 overflow-auto p-4 space-y-4">
|
||||
{messages.map((message, i) => (
|
||||
<div
|
||||
key={i}
|
||||
className={`flex ${
|
||||
message.role === 'assistant' ? 'justify-start' : 'justify-end'
|
||||
}`}
|
||||
>
|
||||
<div
|
||||
className={`max-w-[80%] rounded-lg p-3 ${
|
||||
message.role === 'assistant'
|
||||
? 'bg-gray-100'
|
||||
: 'bg-blue-500 text-white'
|
||||
}`}
|
||||
>
|
||||
{message.content}
|
||||
</div>
|
||||
</div>
|
||||
))}
|
||||
</div>
|
||||
|
||||
<div className="p-4 border-t">
|
||||
<div className="flex gap-2">
|
||||
<input
|
||||
type="text"
|
||||
placeholder="Ask me anything..."
|
||||
className="flex-1 px-3 py-2 rounded-lg border focus:outline-none focus:ring-2 focus:ring-blue-500"
|
||||
/>
|
||||
<button className="p-2 rounded-lg bg-blue-500 text-white hover:bg-blue-600 transition-colors">
|
||||
<Send className="w-5 h-5" />
|
||||
</button>
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
);
|
||||
}
|
||||
@@ -0,0 +1,48 @@
|
||||
import React from 'react';
|
||||
import Prism from 'prismjs';
|
||||
import 'prismjs/themes/prism-tomorrow.css';
|
||||
import 'prismjs/components/prism-typescript';
|
||||
import 'prismjs/components/prism-jsx';
|
||||
import 'prismjs/components/prism-tsx';
|
||||
|
||||
interface CodeEditorProps {
|
||||
value: string;
|
||||
onChange: (value: string) => void;
|
||||
}
|
||||
|
||||
export function CodeEditor({ value, onChange }: CodeEditorProps) {
|
||||
const lines = value.split('\n');
|
||||
const textareaRef = React.useRef<HTMLTextAreaElement>(null);
|
||||
const [highlighted, setHighlighted] = React.useState('');
|
||||
|
||||
React.useEffect(() => {
|
||||
const highlighted = Prism.highlight(
|
||||
value,
|
||||
Prism.languages.tsx,
|
||||
'tsx'
|
||||
);
|
||||
setHighlighted(highlighted);
|
||||
}, [value]);
|
||||
|
||||
return (
|
||||
<div className="relative h-full bg-[#1E1E1E] text-gray-300 font-mono text-sm">
|
||||
<div className="absolute left-0 top-0 bottom-0 w-12 flex flex-col items-end pr-2 pt-4 text-gray-500 select-none bg-[#1E1E1E] border-r border-gray-800">
|
||||
{lines.map((_, i) => (
|
||||
<div key={i} className="leading-6">
|
||||
{i + 1}
|
||||
</div>
|
||||
))}
|
||||
</div>
|
||||
<pre className="absolute left-12 right-0 top-0 bottom-0 m-0 p-4 overflow-hidden pointer-events-none">
|
||||
<code dangerouslySetInnerHTML={{ __html: highlighted }} />
|
||||
</pre>
|
||||
<textarea
|
||||
ref={textareaRef}
|
||||
value={value}
|
||||
onChange={(e) => onChange(e.target.value)}
|
||||
className="w-full h-full pl-14 pr-4 pt-4 bg-transparent resize-none focus:outline-none leading-6 text-transparent caret-white"
|
||||
spellCheck={false}
|
||||
/>
|
||||
</div>
|
||||
);
|
||||
}
|
||||
@@ -0,0 +1,53 @@
|
||||
import React from 'react';
|
||||
import { FileTree } from './FileTree';
|
||||
import { CodeEditor } from './CodeEditor';
|
||||
import { EditorTabs } from './EditorTabs';
|
||||
import { EditorNavBar } from './EditorNavBar';
|
||||
import { Breadcrumb } from './Breadcrumb';
|
||||
|
||||
export function Editor() {
|
||||
const [code, setCode] = React.useState(`// Your code will appear here
|
||||
import React from 'react';
|
||||
import { Prompt } from './components/Prompt';
|
||||
import { Chat } from './components/Chat';
|
||||
import { Editor } from './components/Editor';
|
||||
|
||||
function App() {
|
||||
return (
|
||||
<div className="min-h-screen flex flex-col bg-gray-50">
|
||||
<header className="bg-white border-b">
|
||||
<div className="text-xl font-bold text-blue-500">bolt.new</div>
|
||||
</header>
|
||||
|
||||
<Prompt />
|
||||
|
||||
<main className="flex-1 grid grid-cols-2 gap-4 p-4">
|
||||
<Chat />
|
||||
<Editor />
|
||||
</main>
|
||||
</div>
|
||||
);
|
||||
}
|
||||
export default App;`);
|
||||
const [currentFile, setCurrentFile] = React.useState('/src/App.tsx');
|
||||
|
||||
return (
|
||||
<>
|
||||
<EditorTabs />
|
||||
<EditorNavBar />
|
||||
<div className="h-full flex bg-[#1E1E1E]">
|
||||
<FileTree onFileSelect={(path) => {
|
||||
setCurrentFile(path);
|
||||
// In a real app, we would load the file content here
|
||||
}} />
|
||||
<div className="flex-1 flex flex-col">
|
||||
<Breadcrumb path={currentFile} />
|
||||
<CodeEditor
|
||||
value={code}
|
||||
onChange={setCode}
|
||||
/>
|
||||
</div>
|
||||
</div>
|
||||
</>
|
||||
);
|
||||
}
|
||||
@@ -0,0 +1,18 @@
|
||||
import React from 'react';
|
||||
import { RefreshCw } from 'lucide-react';
|
||||
|
||||
export function EditorNavBar() {
|
||||
return (
|
||||
<div className="flex items-center gap-2 p-2 bg-[#1E1E1E] border-b border-gray-800">
|
||||
<input
|
||||
type="text"
|
||||
value="http://localhost:5173"
|
||||
readOnly
|
||||
className="flex-1 px-3 py-1 text-sm bg-[#2D2D2D] text-gray-300 rounded border border-gray-800 focus:outline-none focus:border-gray-600"
|
||||
/>
|
||||
<button className="p-1.5 text-gray-400 hover:text-white rounded hover:bg-[#2D2D2D] transition-colors">
|
||||
<RefreshCw className="w-4 h-4" />
|
||||
</button>
|
||||
</div>
|
||||
);
|
||||
}
|
||||
@@ -0,0 +1,14 @@
|
||||
import React from 'react';
|
||||
|
||||
export function EditorTabs() {
|
||||
return (
|
||||
<div className="flex items-center bg-[#252526] border-b border-gray-800">
|
||||
<button className="px-4 py-2 text-sm text-white bg-[#1E1E1E] border-r border-gray-800">
|
||||
Code
|
||||
</button>
|
||||
<button className="px-4 py-2 text-sm text-gray-400 hover:text-white transition-colors">
|
||||
Preview
|
||||
</button>
|
||||
</div>
|
||||
);
|
||||
}
|
||||
@@ -0,0 +1,83 @@
|
||||
import React from 'react';
|
||||
import { ChevronDown, File, Folder } from 'lucide-react';
|
||||
|
||||
interface FileTreeProps {
|
||||
onFileSelect: (path: string) => void;
|
||||
}
|
||||
|
||||
export function FileTree({ onFileSelect }: FileTreeProps) {
|
||||
const [expandedFolders, setExpandedFolders] = React.useState<Set<string>>(new Set(['src', 'components']));
|
||||
|
||||
const toggleFolder = (folder: string) => {
|
||||
setExpandedFolders(prev => {
|
||||
const next = new Set(prev);
|
||||
if (next.has(folder)) {
|
||||
next.delete(folder);
|
||||
} else {
|
||||
next.add(folder);
|
||||
}
|
||||
return next;
|
||||
});
|
||||
};
|
||||
|
||||
return (
|
||||
<div className="h-full w-64 bg-[#1E1E1E] text-gray-300 border-r border-gray-800">
|
||||
<div
|
||||
className="flex items-center gap-2 p-2 text-sm cursor-pointer hover:bg-[#2D2D2D]"
|
||||
onClick={() => toggleFolder('src')}
|
||||
>
|
||||
<span className="flex items-center gap-1">
|
||||
<ChevronDown className={`w-4 h-4 transition-transform ${
|
||||
expandedFolders.has('src') ? '' : '-rotate-90'
|
||||
}`} />
|
||||
<Folder className="w-4 h-4" />
|
||||
src
|
||||
</span>
|
||||
</div>
|
||||
{expandedFolders.has('src') && <div className="pl-4">
|
||||
<div
|
||||
className="flex items-center gap-2 p-2 text-sm cursor-pointer hover:bg-[#2D2D2D]"
|
||||
onClick={() => toggleFolder('components')}
|
||||
>
|
||||
<span className="flex items-center gap-1">
|
||||
<ChevronDown className={`w-4 h-4 transition-transform ${
|
||||
expandedFolders.has('components') ? '' : '-rotate-90'
|
||||
}`} />
|
||||
<Folder className="w-4 h-4" />
|
||||
components
|
||||
</span>
|
||||
</div>
|
||||
{expandedFolders.has('components') && <div className="pl-4">
|
||||
<div
|
||||
className="flex items-center gap-2 p-2 text-sm text-gray-400 cursor-pointer hover:bg-[#2D2D2D]"
|
||||
onClick={() => onFileSelect('/src/components/Chat.tsx')}
|
||||
>
|
||||
<File className="w-4 h-4" />
|
||||
Chat.tsx
|
||||
</div>
|
||||
<div
|
||||
className="flex items-center gap-2 p-2 text-sm text-gray-400 cursor-pointer hover:bg-[#2D2D2D]"
|
||||
onClick={() => onFileSelect('/src/components/Editor.tsx')}
|
||||
>
|
||||
<File className="w-4 h-4" />
|
||||
Editor.tsx
|
||||
</div>
|
||||
<div
|
||||
className="flex items-center gap-2 p-2 text-sm text-gray-400 cursor-pointer hover:bg-[#2D2D2D]"
|
||||
onClick={() => onFileSelect('/src/components/Prompt.tsx')}
|
||||
>
|
||||
<File className="w-4 h-4" />
|
||||
Prompt.tsx
|
||||
</div>
|
||||
</div>}
|
||||
<div
|
||||
className="flex items-center gap-2 p-2 text-sm cursor-pointer hover:bg-[#2D2D2D] bg-[#2D2D2D] border-l-2 border-blue-500"
|
||||
onClick={() => onFileSelect('/src/App.tsx')}
|
||||
>
|
||||
<File className="w-4 h-4" />
|
||||
App.tsx
|
||||
</div>
|
||||
</div>}
|
||||
</div>
|
||||
);
|
||||
}
|
||||
@@ -0,0 +1,21 @@
|
||||
import React from 'react';
|
||||
import { Sparkles } from 'lucide-react';
|
||||
|
||||
export function Prompt() {
|
||||
return (
|
||||
<div className="border-b bg-white">
|
||||
<div className="max-w-screen-xl mx-auto p-4">
|
||||
<div className="flex items-start gap-4">
|
||||
<textarea
|
||||
className="flex-1 p-3 h-32 rounded-lg border resize-none focus:outline-none focus:ring-2 focus:ring-blue-500"
|
||||
placeholder="Describe what you want to build..."
|
||||
/>
|
||||
<button className="flex items-center gap-2 px-4 py-2 bg-blue-500 text-white rounded-lg hover:bg-blue-600 transition-colors">
|
||||
<Sparkles className="w-5 h-5" />
|
||||
Generate
|
||||
</button>
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
);
|
||||
}
|
||||
@@ -0,0 +1,22 @@
|
||||
import React from 'react';
|
||||
|
||||
interface TextEditorProps {
|
||||
value: string;
|
||||
onChange: (value: string) => void;
|
||||
placeholder?: string;
|
||||
}
|
||||
|
||||
export function TextEditor({ value, onChange, placeholder }: TextEditorProps) {
|
||||
const handleChange = (e: React.ChangeEvent<HTMLTextAreaElement>) => {
|
||||
onChange(e.target.value);
|
||||
};
|
||||
|
||||
return (
|
||||
<textarea
|
||||
value={value}
|
||||
onChange={handleChange}
|
||||
placeholder={placeholder}
|
||||
className="w-full min-h-[100px] p-5 bg-white border border-[#E5E5E5] rounded-lg shadow-[0_2px_4px_rgba(0,0,0,0.1)] text-[#333333] text-base leading-relaxed resize-y font-sans placeholder:text-gray-400 hover:border-[#D1D1D1] focus:border-[#D1D1D1] focus:outline-none transition-colors duration-200"
|
||||
/>
|
||||
);
|
||||
}
|
||||
@@ -0,0 +1,3 @@
|
||||
@tailwind base;
|
||||
@tailwind components;
|
||||
@tailwind utilities;
|
||||
@@ -0,0 +1,10 @@
|
||||
import { StrictMode } from 'react';
|
||||
import { createRoot } from 'react-dom/client';
|
||||
import App from './App.tsx';
|
||||
import './index.css';
|
||||
|
||||
createRoot(document.getElementById('root')!).render(
|
||||
<StrictMode>
|
||||
<App />
|
||||
</StrictMode>
|
||||
);
|
||||
@@ -0,0 +1,24 @@
|
||||
import React from 'react';
|
||||
import { Chat } from '../components/Chat';
|
||||
import { Editor as CodeEditor } from '../components/Editor';
|
||||
|
||||
export function Editor() {
|
||||
return (
|
||||
<div className="min-h-screen flex flex-col bg-gray-50">
|
||||
<header className="bg-white border-b">
|
||||
<div className="max-w-screen-xl mx-auto px-4 py-3">
|
||||
<div className="text-xl font-bold text-blue-500">Coding Challenge</div>
|
||||
</div>
|
||||
</header>
|
||||
|
||||
<main className="flex-1 grid grid-cols-[25%_75%] gap-4 p-4">
|
||||
<div className="h-[calc(100vh-5rem)] rounded-lg border shadow-sm overflow-hidden">
|
||||
<Chat />
|
||||
</div>
|
||||
<div className="h-[calc(100vh-5rem)] rounded-lg border shadow-sm overflow-hidden">
|
||||
<CodeEditor />
|
||||
</div>
|
||||
</main>
|
||||
</div>
|
||||
);
|
||||
}
|
||||
@@ -0,0 +1,44 @@
|
||||
import React from 'react';
|
||||
import { useNavigate } from 'react-router-dom';
|
||||
import { Sparkles } from 'lucide-react';
|
||||
|
||||
export function Landing() {
|
||||
const navigate = useNavigate();
|
||||
const [prompt, setPrompt] = React.useState('');
|
||||
|
||||
const handleGenerate = () => {
|
||||
if (prompt.trim()) {
|
||||
navigate('/editor');
|
||||
}
|
||||
};
|
||||
|
||||
return (
|
||||
<div className="min-h-screen flex flex-col bg-gray-50">
|
||||
<header className="bg-white border-b">
|
||||
<div className="max-w-screen-xl mx-auto px-4 py-3">
|
||||
<div className="text-xl font-bold text-blue-500">Coding Challenge</div>
|
||||
</div>
|
||||
</header>
|
||||
|
||||
<main className="flex-1 flex items-center justify-center p-4">
|
||||
<div className="w-full max-w-3xl space-y-4">
|
||||
<textarea
|
||||
value={prompt}
|
||||
onChange={(e) => setPrompt(e.target.value)}
|
||||
className="w-full p-4 h-40 text-lg rounded-lg border resize-none focus:outline-none focus:ring-2 focus:ring-blue-500"
|
||||
placeholder="Describe what you want to build..."
|
||||
/>
|
||||
<div className="flex justify-end">
|
||||
<button
|
||||
onClick={handleGenerate}
|
||||
className="flex items-center gap-2 px-6 py-3 bg-blue-500 text-white rounded-lg hover:bg-blue-600 transition-colors text-lg"
|
||||
>
|
||||
<Sparkles className="w-5 h-5" />
|
||||
Generate
|
||||
</button>
|
||||
</div>
|
||||
</div>
|
||||
</main>
|
||||
</div>
|
||||
);
|
||||
}
|
||||
Vendored
+1
@@ -0,0 +1 @@
|
||||
/// <reference types="vite/client" />
|
||||
@@ -0,0 +1,8 @@
|
||||
/** @type {import('tailwindcss').Config} */
|
||||
export default {
|
||||
content: ['./index.html', './src/**/*.{js,ts,jsx,tsx}'],
|
||||
theme: {
|
||||
extend: {},
|
||||
},
|
||||
plugins: [],
|
||||
};
|
||||
@@ -0,0 +1,24 @@
|
||||
{
|
||||
"compilerOptions": {
|
||||
"target": "ES2020",
|
||||
"useDefineForClassFields": true,
|
||||
"lib": ["ES2020", "DOM", "DOM.Iterable"],
|
||||
"module": "ESNext",
|
||||
"skipLibCheck": true,
|
||||
|
||||
/* Bundler mode */
|
||||
"moduleResolution": "bundler",
|
||||
"allowImportingTsExtensions": true,
|
||||
"isolatedModules": true,
|
||||
"moduleDetection": "force",
|
||||
"noEmit": true,
|
||||
"jsx": "react-jsx",
|
||||
|
||||
/* Linting */
|
||||
"strict": true,
|
||||
"noUnusedLocals": true,
|
||||
"noUnusedParameters": true,
|
||||
"noFallthroughCasesInSwitch": true
|
||||
},
|
||||
"include": ["src"]
|
||||
}
|
||||
@@ -0,0 +1,7 @@
|
||||
{
|
||||
"files": [],
|
||||
"references": [
|
||||
{ "path": "./tsconfig.app.json" },
|
||||
{ "path": "./tsconfig.node.json" }
|
||||
]
|
||||
}
|
||||
@@ -0,0 +1,22 @@
|
||||
{
|
||||
"compilerOptions": {
|
||||
"target": "ES2022",
|
||||
"lib": ["ES2023"],
|
||||
"module": "ESNext",
|
||||
"skipLibCheck": true,
|
||||
|
||||
/* Bundler mode */
|
||||
"moduleResolution": "bundler",
|
||||
"allowImportingTsExtensions": true,
|
||||
"isolatedModules": true,
|
||||
"moduleDetection": "force",
|
||||
"noEmit": true,
|
||||
|
||||
/* Linting */
|
||||
"strict": true,
|
||||
"noUnusedLocals": true,
|
||||
"noUnusedParameters": true,
|
||||
"noFallthroughCasesInSwitch": true
|
||||
},
|
||||
"include": ["vite.config.ts"]
|
||||
}
|
||||
@@ -0,0 +1,10 @@
|
||||
import { defineConfig } from 'vite';
|
||||
import react from '@vitejs/plugin-react';
|
||||
|
||||
// https://vitejs.dev/config/
|
||||
export default defineConfig({
|
||||
plugins: [react()],
|
||||
optimizeDeps: {
|
||||
exclude: ['lucide-react'],
|
||||
},
|
||||
});
|
||||
Reference in New Issue
Block a user