JavaScript 生态系统的
全栈 Dart 方案
使用 Dart 编写 React、React Native 和 Express 应用。 一种语言。运行时类型安全。健全的空安全。
// A complete Express server in Dart
import 'package:dart_node_express/dart_node_express.dart';
void main() {
final app = express();
app.get('/', handler((req, res) {
res.jsonMap({'message': 'Hello from Dart!'});
}));
app.listen(3000, () {
print('Server running on port 3000');
}.toJS);
}
适用人群
无论您是 React 开发者还是 Flutter 开发者,dart_node 都适合您。
React (TypeScript)
const Counter: React.FC = () => {
const [count, setCount] = useState<number>(0);
return (
<button onClick={() => setCount(c => c + 1)}>
Count: {count}
</button>
);
};
React (Dart)
ReactElement counter() {
final count = useState(0);
return button(
text: 'Count: ${count.value}',
onClick: () => count.setWithUpdater((c) => c + 1),
);
}
相同的编程范式
Hooks、组件、props、state — React 中的所有概念在 Dart 中同样适用。
运行时类型安全
与 TypeScript 不同,Dart 在运行时保留类型信息。没有 any 类型逃逸,泛型不会被擦除。
更简单的工具链
不需要 webpack、babel、tsconfig。只需 dart compile js 即可。
Flutter
class Counter extends StatefulWidget {
State<Counter> createState() => _CounterState();
}
class _CounterState extends State<Counter> {
int count = 0;
Widget build(BuildContext context) {
return ElevatedButton(
onPressed: () => setState(() => count++),
child: Text('Count: $count'),
);
}
}
dart_node React
ReactElement counter() {
final count = useState(0);
return button(
text: 'Count: ${count.value}',
onClick: () => count.setWithUpdater((c) => c + 1),
);
}
同一种语言
使用现有的 Dart 技能。跨平台共享模型、工具函数和业务逻辑。
访问 Web 生态系统
在编写纯 Dart 代码的同时,可以使用 React 和 npm 生态系统。
全栈 Dart
后端 (Express)、Web (React)、移动端 (React Native) — 全部使用同一种语言。
dart_node 包
全栈开发所需的包和工具。
dart_node_mcp
Model Context Protocol 服务器绑定,用于构建 AI 工具服务器。
dart_node_better_sqlite3
better-sqlite3 的类型化绑定,支持同步 SQLite3 和 WAL 模式。
reflux
Redux 风格的状态容器,支持穷尽模式匹配。
dart_logging
Pino 风格的结构化日志,支持子 logger 和 transport。
dart_jsx
Dart 的 JSX 转译器 — JSX 语法编译为 dart_node_react 调用。
运行时类型的重要性
TypeScript 编译为 JavaScript 时会擦除类型。Dart 不会。
TypeScript (Types Erased)
interface User {
id: number;
name: string;
}
// At runtime, this is just a plain object
// No way to validate the shape!
const user: User = JSON.parse(data);
// This could fail silently
console.log(user.name.toUpperCase());
// Runtime error if name is undefined!
Dart (Types Preserved)
class User {
final int id;
final String name;
User({required this.id, required this.name});
}
// Types exist at runtime - you can validate!
final user = User.fromJson(jsonDecode(data));
// If name were null, this would fail
// at deserialization, not at usage
print(user.name.toUpperCase());
快速开始
# Create a new project
mkdir my_dart_app && cd my_dart_app
dart create -t package .
# Add dart_node packages
dart pub add dart_node_core dart_node_express
# Write your server
cat > lib/server.dart << 'EOF'
import 'package:dart_node_express/dart_node_express.dart';
void main() {
final app = express();
app.get('/', handler((req, res) => res.send('Hello, Dart!')));
app.listen(3000);
}
EOF
# Compile to JavaScript and run
dart compile js lib/server.dart -o build/server.js
node build/server.js