feat: add codemirror perf
This commit is contained in:
@@ -1,6 +1,6 @@
|
||||
{
|
||||
"name": "@kevisual/codemirror",
|
||||
"version": "0.0.7",
|
||||
"version": "0.0.8",
|
||||
"description": "",
|
||||
"main": "dist/editor.js",
|
||||
"private": false,
|
||||
@@ -16,15 +16,22 @@
|
||||
],
|
||||
"author": "abearxiong",
|
||||
"license": "ISC",
|
||||
"devDependencies": {
|
||||
"dependencies": {
|
||||
"@codemirror/autocomplete": "^6.18.6",
|
||||
"@codemirror/commands": "^6.8.1",
|
||||
"@codemirror/lang-css": "^6.3.1",
|
||||
"@codemirror/lang-html": "^6.4.9",
|
||||
"@codemirror/lang-javascript": "^6.2.3",
|
||||
"@codemirror/lang-json": "^6.0.1",
|
||||
"@codemirror/lang-markdown": "^6.3.2",
|
||||
"@codemirror/state": "^6.5.2",
|
||||
"@codemirror/view": "^6.36.7",
|
||||
"codemirror": "^6.0.1",
|
||||
"prettier": "^3.5.3"
|
||||
},
|
||||
"devDependencies": {
|
||||
"@rollup/plugin-node-resolve": "^16.0.1",
|
||||
"@rollup/plugin-typescript": "^12.1.2",
|
||||
"codemirror": "^6.0.1",
|
||||
"rollup": "^4.40.2",
|
||||
"tslib": "^2.8.1",
|
||||
"typescript": "^5.8.3"
|
||||
|
||||
@@ -5,10 +5,12 @@ const entrys = ['editor', 'editor.json', 'editor.base'];
|
||||
const configs = entrys.map((entry) => ({
|
||||
input: `./src/${entry}.ts`, // 修改输入文件为 TypeScript 文件
|
||||
output: {
|
||||
file: `./dist/${entry}.js`,
|
||||
// file: `./dist/${entry}.js`,
|
||||
dir: './dist',
|
||||
},
|
||||
target: 'browser',
|
||||
plugins: [
|
||||
nodeResolve(),
|
||||
// nodeResolve(),
|
||||
typescript({
|
||||
tsconfig: './tsconfig.json',
|
||||
compilerOptions: {
|
||||
|
||||
@@ -1,5 +1,5 @@
|
||||
import { EditorView, basicSetup } from 'codemirror';
|
||||
|
||||
import { formatKeymap } from './extensions/tab';
|
||||
let editor: EditorView = null;
|
||||
|
||||
export type EditorOptions = {
|
||||
@@ -19,6 +19,7 @@ const createEditorInstance = (el?: HTMLDivElement, opts?: EditorOptions) => {
|
||||
return editor;
|
||||
}
|
||||
const extensions = opts?.extensions || [];
|
||||
extensions.push(formatKeymap);
|
||||
const hasBaseicSetup = opts?.hasBasicSetup ?? true;
|
||||
if (hasBaseicSetup) {
|
||||
extensions.unshift(basicSetup);
|
||||
@@ -42,6 +43,7 @@ export const createEditor = (el: HTMLDivElement, opts?: EditorOptions) => {
|
||||
if (hasBaseicSetup) {
|
||||
extensions.unshift(basicSetup);
|
||||
}
|
||||
extensions.push(formatKeymap);
|
||||
const editor = new EditorView({
|
||||
extensions,
|
||||
parent: el || document.body,
|
||||
|
||||
@@ -4,6 +4,7 @@ import { json } from '@codemirror/lang-json';
|
||||
import { html } from '@codemirror/lang-html';
|
||||
import { markdown } from '@codemirror/lang-markdown';
|
||||
import { css } from '@codemirror/lang-css';
|
||||
import { formatKeymap } from './extensions/tab';
|
||||
let editor: EditorView = null;
|
||||
|
||||
type CreateOpts = {
|
||||
@@ -12,6 +13,7 @@ type CreateOpts = {
|
||||
type?: 'javascript' | 'json' | 'html' | 'markdown' | 'css';
|
||||
hasBasicSetup?: boolean;
|
||||
extensions?: any[];
|
||||
hasKeymap?: boolean;
|
||||
};
|
||||
/**
|
||||
* 创建单例
|
||||
@@ -28,9 +30,13 @@ const createEditorInstance = (el?: HTMLDivElement, opts?: CreateOpts) => {
|
||||
const { type = 'javascript' } = opts || {};
|
||||
const extensions = opts?.extensions || [];
|
||||
const hasBaseicSetup = opts?.hasBasicSetup ?? true;
|
||||
const hasKeymap = opts?.hasKeymap ?? true;
|
||||
if (hasBaseicSetup) {
|
||||
extensions.unshift(basicSetup);
|
||||
}
|
||||
if (hasKeymap) {
|
||||
extensions.push(formatKeymap);
|
||||
}
|
||||
switch (type) {
|
||||
case 'json':
|
||||
extensions.push(json());
|
||||
@@ -65,9 +71,13 @@ export const createEditor = (el: HTMLDivElement, opts?: CreateOpts) => {
|
||||
const { type = 'javascript' } = opts || {};
|
||||
const extensions = opts?.extensions || [];
|
||||
const hasBaseicSetup = opts?.hasBasicSetup ?? true;
|
||||
const hasKeymap = opts?.hasKeymap ?? true;
|
||||
if (hasBaseicSetup) {
|
||||
extensions.unshift(basicSetup);
|
||||
}
|
||||
if (hasKeymap) {
|
||||
extensions.push(formatKeymap);
|
||||
}
|
||||
switch (type) {
|
||||
case 'json':
|
||||
extensions.push(json());
|
||||
|
||||
56
packages/codemirror/src/extensions/tab.ts
Normal file
56
packages/codemirror/src/extensions/tab.ts
Normal file
@@ -0,0 +1,56 @@
|
||||
import { EditorView, keymap } from '@codemirror/view';
|
||||
import { EditorState } from '@codemirror/state';
|
||||
import { defaultKeymap, indentWithTab, insertTab } from '@codemirror/commands';
|
||||
import prettier from 'prettier';
|
||||
// import parserBabel from 'prettier/plugins/babel';
|
||||
import parserEstree from 'prettier/plugins/estree';
|
||||
// import parserHtml from 'prettier/plugins/html';
|
||||
import parserTypescript from 'prettier/plugins/typescript';
|
||||
|
||||
// 格式化函数
|
||||
// Function to format the code using Prettier
|
||||
type FormatCodeOptions = {
|
||||
type: 'typescript';
|
||||
plugins?: any[];
|
||||
};
|
||||
async function formatCode(view: EditorView, opts?: FormatCodeOptions) {
|
||||
const editor = view;
|
||||
const code = editor.state.doc.toString();
|
||||
const plugins = opts?.plugins || [];
|
||||
plugins.push(parserEstree);
|
||||
const parser = opts?.type || 'typescript';
|
||||
if (parser === 'typescript') {
|
||||
plugins.push(parserTypescript);
|
||||
}
|
||||
try {
|
||||
const formattedCode = await prettier.format(code, {
|
||||
parser: parser,
|
||||
plugins: plugins,
|
||||
});
|
||||
|
||||
editor.dispatch({
|
||||
changes: {
|
||||
from: 0,
|
||||
to: editor.state.doc.length,
|
||||
insert: formattedCode.trim(),
|
||||
},
|
||||
});
|
||||
} catch (error) {
|
||||
console.error('Error formatting code:', error);
|
||||
}
|
||||
}
|
||||
|
||||
export const formatKeymap = keymap.of([
|
||||
{
|
||||
// bug, 必须小写
|
||||
key: 'alt-shift-f', // 快捷键绑定
|
||||
// mac: 'cmd-shift-f',
|
||||
run: (view) => {
|
||||
formatCode(view);
|
||||
return true; // 表示按键事件被处理
|
||||
},
|
||||
},
|
||||
// indentWithTab, // Tab键自动缩进
|
||||
{ key: 'Tab', run: insertTab }, // 在光标位置插入Tab字符
|
||||
...defaultKeymap, // 默认快捷键
|
||||
]);
|
||||
@@ -33,6 +33,7 @@
|
||||
"@eslint/js": "^9.26.0",
|
||||
"@tailwindcss/aspect-ratio": "^0.4.2",
|
||||
"@tailwindcss/typography": "^0.5.16",
|
||||
"@tailwindcss/vite": "^4.1.6",
|
||||
"@types/node": "^22.15.17",
|
||||
"@types/react": "^19.1.3",
|
||||
"@types/react-dom": "^19.1.3",
|
||||
@@ -42,7 +43,7 @@
|
||||
"eslint-plugin-react-hooks": "^5.2.0",
|
||||
"eslint-plugin-react-refresh": "^0.4.20",
|
||||
"globals": "^16.1.0",
|
||||
"tailwind-merge": "^3.2.0",
|
||||
"tailwind-merge": "^3.3.0",
|
||||
"tailwindcss": "^4.1.6",
|
||||
"tailwindcss-animate": "^1.0.7",
|
||||
"typescript": "^5.8.3",
|
||||
|
||||
@@ -14,7 +14,7 @@ export const App = () => {
|
||||
<Router>
|
||||
<Routes>
|
||||
<Route path='/' element={<Navigate to='/modal/' />} />
|
||||
<Route path='/modal/*' element={<FlowApps />} />
|
||||
{/* <Route path='/modal/*' element={<FlowApps />} /> */}
|
||||
<Route path='/codemirror/*' element={<CodeMirrorApp />} />
|
||||
<Route path='/404' element={<div>404</div>} />
|
||||
<Route path='*' element={<div>404</div>} />
|
||||
|
||||
@@ -1,15 +1 @@
|
||||
@tailwind base;
|
||||
@tailwind components;
|
||||
@tailwind utilities;
|
||||
|
||||
@layer base {
|
||||
h1 {
|
||||
@apply text-2xl font-bold;
|
||||
}
|
||||
h2 {
|
||||
@apply text-xl font-bold;
|
||||
}
|
||||
h3 {
|
||||
@apply text-lg font-bold;
|
||||
}
|
||||
}
|
||||
@import 'tailwindcss';
|
||||
|
||||
@@ -1,6 +1,8 @@
|
||||
import { createRoot } from 'react-dom/client';
|
||||
import { App } from './App.tsx';
|
||||
// import './tailwind.css';
|
||||
const App2 = () => {
|
||||
return <div>hello</div>;
|
||||
};
|
||||
import './globals.css';
|
||||
import './index.css';
|
||||
|
||||
|
||||
@@ -1,4 +1,4 @@
|
||||
import { createEditorInstance } from '@kevisual/codemirror/json';
|
||||
import { createEditor } from '@kevisual/codemirror/json';
|
||||
import { useEffect, useRef } from 'react';
|
||||
export const App = () => {
|
||||
const ref = useRef<HTMLDivElement>(null);
|
||||
@@ -6,7 +6,7 @@ export const App = () => {
|
||||
init();
|
||||
}, []);
|
||||
const init = () => {
|
||||
const editor = createEditorInstance(ref.current!);
|
||||
const editor = createEditor(ref.current!);
|
||||
editor.dom.style.height = '100%';
|
||||
};
|
||||
return (
|
||||
|
||||
@@ -1,3 +0,0 @@
|
||||
@tailwind base;
|
||||
@tailwind components;
|
||||
@tailwind utilities;
|
||||
@@ -1,36 +0,0 @@
|
||||
console.log('tailwind.config.js');
|
||||
/** @type {import('tailwindcss').Config} */
|
||||
export default {
|
||||
darkMode: ['class'],
|
||||
content: [
|
||||
'./src/**/*.{ts,tsx}',
|
||||
'./node_modules/@abearxiong/flows/components/**/*.{ts,tsx}', //
|
||||
'./node_modules/@abearxiong/flows/hooks/**/*.{ts,tsx}', //
|
||||
'./node_modules/@abearxiong/flows/src/**/*.{ts,tsx}' //
|
||||
],
|
||||
plugins: [require('@tailwindcss/aspect-ratio'), require('@tailwindcss/typography')],
|
||||
theme: {
|
||||
extend: {},
|
||||
screen: {
|
||||
sm: '640px',
|
||||
// => @media (min-width: 640px) { ... }
|
||||
|
||||
md: '768px',
|
||||
// => @media (min-width: 768px) { ... }
|
||||
|
||||
lg: '1024px',
|
||||
// => @media (min-width: 1024px) { ... }
|
||||
|
||||
xl: '1280px',
|
||||
// => @media (min-width: 1280px) { ... }
|
||||
|
||||
'2xl': '1536px',
|
||||
// => @media (min-width: 1536px) { ... }
|
||||
'3xl': '1920px',
|
||||
// => @media (min-width: 1920) { ... }
|
||||
'4xl': '2560px'
|
||||
// => @media (min-width: 2560) { ... }
|
||||
}
|
||||
},
|
||||
plugins: [require('tailwindcss-animate')]
|
||||
};
|
||||
@@ -1,25 +1,18 @@
|
||||
import { defineConfig } from 'vite'
|
||||
import react from '@vitejs/plugin-react'
|
||||
import tailwindcss from 'tailwindcss'
|
||||
import autoprefixer from 'autoprefixer'
|
||||
import path from 'path'
|
||||
import nesting from 'tailwindcss/nesting'
|
||||
import { defineConfig } from 'vite';
|
||||
import react from '@vitejs/plugin-react';
|
||||
import tailwindcss from '@tailwindcss/vite';
|
||||
import path from 'path';
|
||||
|
||||
// https://vitejs.dev/config/
|
||||
export default defineConfig({
|
||||
plugins: [react()],
|
||||
css: {
|
||||
postcss: {
|
||||
plugins: [nesting, tailwindcss, autoprefixer]
|
||||
}
|
||||
},
|
||||
plugins: [react(), tailwindcss()],
|
||||
resolve: {
|
||||
alias: {
|
||||
'@': path.resolve(__dirname, './src')
|
||||
}
|
||||
'@': path.resolve(__dirname, './src'),
|
||||
},
|
||||
},
|
||||
define: {
|
||||
DEV_SERVER: JSON.stringify(process.env.NODE_ENV === 'development')
|
||||
DEV_SERVER: JSON.stringify(process.env.NODE_ENV === 'development'),
|
||||
},
|
||||
server: {
|
||||
port: 7101,
|
||||
@@ -27,8 +20,8 @@ export default defineConfig({
|
||||
'/api': {
|
||||
target: 'http://localhost:3000',
|
||||
changeOrigin: true,
|
||||
rewrite: (path) => path.replace(/^\/api/, '/api')
|
||||
}
|
||||
}
|
||||
}
|
||||
})
|
||||
rewrite: (path) => path.replace(/^\/api/, '/api'),
|
||||
},
|
||||
},
|
||||
},
|
||||
});
|
||||
|
||||
Reference in New Issue
Block a user