Skip to content

Commit c4733dd

Browse files
committed
feat (language): 支持 JavaScript By Node.js 引擎语言
1 parent c78cb3f commit c4733dd

9 files changed

Lines changed: 77 additions & 3 deletions

File tree

README.md

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -26,6 +26,7 @@ CodeForge 是一款轻量级、高性能的桌面代码执行器,专为开发
2626
- **Clojure**
2727
- **Go**
2828
- **Java**
29+
- **JavaScript (Node.js)**
2930
- **Kotlin**
3031
- **Node.js**
3132
- **Python 2**

public/icons/javascript-nodejs.svg

Lines changed: 12 additions & 0 deletions
Loading
Lines changed: 54 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,54 @@
1+
use super::{LanguagePlugin, PluginConfig};
2+
use std::vec;
3+
4+
pub struct LanguageNodeJsPlugin;
5+
6+
impl LanguagePlugin for LanguageNodeJsPlugin {
7+
fn get_order(&self) -> i32 {
8+
13
9+
}
10+
11+
fn get_language_name(&self) -> &'static str {
12+
"JavaScript (Node.js)"
13+
}
14+
15+
fn get_language_key(&self) -> &'static str {
16+
"javascript-nodejs"
17+
}
18+
19+
fn get_file_extension(&self) -> String {
20+
self.get_config()
21+
.map(|config| config.extension.clone())
22+
.unwrap_or_else(|| "js".to_string())
23+
}
24+
25+
fn get_version_args(&self) -> Vec<&'static str> {
26+
vec!["--version"]
27+
}
28+
29+
fn get_path_command(&self) -> String {
30+
"which node".to_string()
31+
}
32+
33+
fn get_default_config(&self) -> PluginConfig {
34+
PluginConfig {
35+
enabled: true,
36+
language: String::from("javascript-nodejs"),
37+
before_compile: None,
38+
extension: String::from("js"),
39+
execute_home: None,
40+
run_command: Some(String::from("node $filename")),
41+
after_compile: None,
42+
template: Some(String::from(
43+
"// JavaScript (Node.js) 示例代码 - CodeForge 代码执行环境\n\nconsole.log('🎉 欢迎使用 CodeForge!');\nconsole.log('Welcome to CodeForge!');\nconsole.log('');\n\nconsole.log('=========================================');\nconsole.log(' CodeForge JavaScript ');\nconsole.log('=========================================');\nconsole.log('');\n\n// 基本输出示例\nconsole.log('✅ JavaScript 运行成功! (JavaScript is working!)');\nconsole.log('🌟 这是 Node.js 脚本 (This is Node.js script)');\nconsole.log('');\n\n// 变量操作\nconst name = 'CodeForge';\nconst version = 'JavaScript';\nconst number1 = 10;\nconst number2 = 20;\nconst result = number1 + number2;\n\nconsole.log('🔢 简单计算 (Simple calculation):');\nconsole.log(`${number1} + ${number2} = ${result}`);\nconsole.log('');\n\n// 字符串操作\nconsole.log('📝 字符串操作 (String operations):');\nconsole.log(`平台名称 (Platform): ${name}`);\nconsole.log(`语言版本 (Language): ${version}`);\nconsole.log(`完整信息 (Full info): ${name} - ${version}`);\nconsole.log('');\n\n// 循环示例\nconsole.log('🔄 循环输出 (Loop output):');\nfor (let i = 1; i <= 5; i++) {\n console.log(`第 ${i} 次输出 (Output #${i}): Hello from CodeForge!`);\n}\nconsole.log('');\n\n// 数组操作\nconst fruits = ['苹果', '香蕉', '橙子', '葡萄'];\nconsole.log('🍎 水果列表 (Fruit list):');\nfruits.forEach((fruit, index) => {\n console.log(`${index + 1}. ${fruit}`);\n});\nconsole.log('');\n\n// 条件判断\nconst score = 85;\nconsole.log('📊 成绩评估 (Score evaluation):');\nif (score >= 90) {\n console.log('优秀! (Excellent!)');\n} else if (score >= 80) {\n console.log('良好! (Good!)');\n} else if (score >= 60) {\n console.log('及格 (Pass)');\n} else {\n console.log('需要努力 (Need improvement)');\n}\nconsole.log('');\n\n// undefined 和 null 示例\nconsole.log('🔍 undefined/null 示例 (undefined/null example):');\nlet optionalValue = 42;\nif (optionalValue !== undefined && optionalValue !== null) {\n console.log(`可选值: ${optionalValue} (Optional value: ${optionalValue})`);\n} else {\n console.log('值为空 (Value is undefined/null)');\n}\nconsole.log('');\n\n// 函数示例\nfunction greetUser(username) {\n return `Hello, ${username}! 👋`;\n}\n\nconsole.log('🎭 函数示例 (Function example):');\nconst greeting = greetUser('CodeForge用户');\nconsole.log(greeting);\nconsole.log('');\n\n// 箭头函数示例\nconst addNumbers = (a, b) => a + b;\nconst multiplyNumbers = (a, b) => {\n return a * b;\n};\n\nconsole.log('⚡ 箭头函数示例 (Arrow function example):');\nconsole.log(`5 + 3 = ${addNumbers(5, 3)}`);\nconsole.log(`6 × 7 = ${multiplyNumbers(6, 7)}`);\nconsole.log('');\n\n// 数组高阶函数示例\nconsole.log('🔧 数组高阶函数示例 (Array higher-order functions):');\nconst numbers = Array.from({length: 10}, (_, i) => i + 1);\nconst evenNumbers = numbers.filter(num => num % 2 === 0);\nconst doubled = numbers.map(num => num * 2);\nconst sum = numbers.reduce((acc, num) => acc + num, 0);\n\nconsole.log(`原始数字 (Original): ${numbers.join(', ')}`);\nconsole.log(`偶数 (Even numbers): ${evenNumbers.join(', ')}`);\nconsole.log(`翻倍 (Doubled): ${doubled.join(', ')}`);\nconsole.log(`总和 (Sum): ${sum}`);\nconsole.log('');\n\n// 对象操作示例\nconsole.log('👤 对象示例 (Object example):');\nconst person = {\n name: '张三',\n age: 25,\n city: '北京',\n introduce() {\n return `我是${this.name},今年${this.age}岁,住在${this.city}`;\n }\n};\n\nconsole.log(`姓名: ${person.name}, 年龄: ${person.age}, 城市: ${person.city}`);\nconsole.log(person.introduce());\nconsole.log('');\n\n// 解构赋值示例\nconsole.log('🔍 解构赋值示例 (Destructuring assignment):');\nconst {name: personName, age: personAge} = person;\nconst [first, second, ...rest] = fruits;\n\nconsole.log(`解构对象 (Destructured object): ${personName}, ${personAge}`);\nconsole.log(`解构数组 (Destructured array): ${first}, ${second}, 其他: [${rest.join(', ')}]`);\nconsole.log('');\n\n// Promise 示例\nconsole.log('🎯 Promise 示例 (Promise example):');\nconst delay = (ms) => new Promise(resolve => setTimeout(resolve, ms));\n\n// 使用 Promise\ndelay(100)\n .then(() => {\n console.log('Promise 已完成! (Promise completed!)');\n return '异步操作结果';\n })\n .then(result => {\n console.log(`异步结果: ${result}`);\n })\n .catch(error => {\n console.error('Promise 错误:', error);\n });\n\n// async/await 示例\nasync function asyncExample() {\n try {\n console.log('⏳ 开始异步操作...');\n await delay(50);\n console.log('✅ async/await 完成!');\n return '异步函数结果';\n } catch (error) {\n console.error('async/await 错误:', error);\n }\n}\n\n// 立即执行异步函数\n(async () => {\n const result = await asyncExample();\n console.log(`异步函数返回: ${result}`);\n console.log('');\n})();\n\n// 类和继承示例\nconsole.log('🏗️ 类示例 (Class example):');\nclass Animal {\n constructor(name, type) {\n this.name = name;\n this.type = type;\n }\n \n speak() {\n return `${this.name} 发出声音`;\n }\n}\n\nclass Dog extends Animal {\n constructor(name) {\n super(name, '狗');\n }\n \n speak() {\n return `${this.name} 汪汪叫`;\n }\n}\n\nconst dog = new Dog('小黄');\nconsole.log(dog.speak());\nconsole.log('');\n\n// 模块和导出示例(注释版本,因为这是单文件)\nconsole.log('📦 模块概念示例 (Module concept example):');\n// export const utilities = {\n// formatDate: (date) => date.toLocaleDateString('zh-CN'),\n// randomNumber: () => Math.floor(Math.random() * 100)\n// };\n\nconst utilities = {\n formatDate: (date) => date.toLocaleDateString('zh-CN'),\n randomNumber: () => Math.floor(Math.random() * 100)\n};\n\nconsole.log(`当前日期: ${utilities.formatDate(new Date())}`);\nconsole.log(`随机数: ${utilities.randomNumber()}`);\nconsole.log('');\n\n// JSON 操作示例\nconsole.log('📄 JSON 操作示例 (JSON operations):');\nconst data = {\n users: [\n {id: 1, name: 'Alice', active: true},\n {id: 2, name: 'Bob', active: false},\n {id: 3, name: 'Charlie', active: true}\n ]\n};\n\nconst jsonString = JSON.stringify(data, null, 2);\nconsole.log('JSON 字符串:');\nconsole.log(jsonString);\n\nconst parsedData = JSON.parse(jsonString);\nconst activeUsers = parsedData.users.filter(user => user.active);\nconsole.log(`活跃用户: ${activeUsers.map(u => u.name).join(', ')}`);\nconsole.log('');\n\n// 错误处理示例\nconsole.log('🚨 错误处理示例 (Error handling):');\ntry {\n const riskyOperation = () => {\n const random = Math.random();\n if (random < 0.5) {\n throw new Error('随机错误发生了!');\n }\n return '操作成功!';\n };\n \n const result2 = riskyOperation();\n console.log(result2);\n} catch (error) {\n console.log(`捕获错误: ${error.message}`);\n} finally {\n console.log('错误处理完成');\n}\nconsole.log('');\n\n// 正则表达式示例\nconsole.log('🔤 正则表达式示例 (Regular expressions):');\nconst text = 'CodeForge 是一个很棒的代码执行环境! Email: contact@codeforge.com';\nconst emailRegex = /\\b[A-Za-z0-9._%+-]+@[A-Za-z0-9.-]+\\.[A-Z|a-z]{2,}\\b/g;\nconst emails = text.match(emailRegex);\n\nconsole.log(`文本: ${text}`);\nconsole.log(`找到的邮箱: ${emails ? emails.join(', ') : '无'}`);\nconsole.log('');\n\nconsole.log('🎯 CodeForge JavaScript 代码执行完成!');\nconsole.log('🎯 CodeForge JavaScript execution completed!');\nconsole.log('');\nconsole.log('感谢使用 CodeForge 代码执行环境! 🚀');\nconsole.log('Thank you for using CodeForge! 🚀');",
44+
)),
45+
timeout: Some(30),
46+
}
47+
}
48+
49+
fn get_default_command(&self) -> String {
50+
self.get_config()
51+
.and_then(|config| config.run_command.clone())
52+
.unwrap_or_else(|| "node".to_string())
53+
}
54+
}

src-tauri/src/plugins/manager.rs

Lines changed: 5 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -3,6 +3,7 @@ use crate::plugins::c::CPlugin;
33
use crate::plugins::clojure::ClojurePlugin;
44
use crate::plugins::go::GoPlugin;
55
use crate::plugins::java::JavaPlugin;
6+
use crate::plugins::javascript_nodejs::LanguageNodeJsPlugin;
67
use crate::plugins::kotlin::KotlinPlugin;
78
use crate::plugins::nodejs::NodeJSPlugin;
89
use crate::plugins::python2::Python2Plugin;
@@ -33,6 +34,10 @@ impl PluginManager {
3334
plugins.insert("kotlin".to_string(), Box::new(KotlinPlugin));
3435
plugins.insert("clojure".to_string(), Box::new(ClojurePlugin));
3536
plugins.insert("c".to_string(), Box::new(CPlugin));
37+
plugins.insert(
38+
"javascript-nodejs".to_string(),
39+
Box::new(LanguageNodeJsPlugin),
40+
);
3641

3742
Self { plugins }
3843
}

src-tauri/src/plugins/mod.rs

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -349,6 +349,7 @@ pub mod c;
349349
pub mod clojure;
350350
pub mod go;
351351
pub mod java;
352+
pub mod javascript_nodejs;
352353
pub mod kotlin;
353354
pub mod manager;
354355
pub mod nodejs;

src/components/AppHeader.vue

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -2,7 +2,7 @@
22
<div class="bg-white border-b border-gray-200 px-4 py-3 flex items-center justify-between">
33
<div class="flex items-center space-x-3">
44
<Select v-model="selectedLanguage"
5-
class="w-48"
5+
class="w-64"
66
searchable
77
:options="supportedLanguages as any"
88
:disabled="isRunning"

src/components/setting/Language.vue

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -4,7 +4,7 @@
44
type="card"
55
size="md"
66
position="left"
7-
:tab-button-class="['w-36']"
7+
:tab-button-class="['w-48']"
88
:tabs="tabsPluginData"
99
@change="handleTabChange">
1010
<template #[activePlugin]="{ tab }">

src/composables/useCodeMirrorEditor.ts

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -160,6 +160,7 @@ export function useCodeMirrorEditor(props: Props)
160160
case 'python3':
161161
return python()
162162
case 'nodejs':
163+
case 'javascript-nodejs':
163164
return javascript()
164165
case 'go':
165166
return go()

src/composables/useCodeMirrorFunctionHelp.ts

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -1,5 +1,5 @@
11
import { EditorView, hoverTooltip } from '@codemirror/view'
2-
2+
1
33
export function useCodeMirrorFunctionHelp()
44
{
55
// 提示框

0 commit comments

Comments
 (0)