用纯 Node.js 写了一个 JS 解释器 — kernel-js-lite

为什么会有这个东西

有时候我们需要在 Node.js 里安全地执行用户提交的 JavaScript 代码。Node 自带的 vm 模块并不安全,eval 更不用提。QuickJS 很强大但需要原生编译。safe-evalvm2 等方案要么依赖繁杂要么维护停滞。

如果有一个纯 Node.js 实现、零依赖、可以安全运行不可信代码的 JS 解释器呢?

这就是 kernel-js-lite.

架构一览

传统 JS 引擎的经典三阶段 pipeline,全部手写,零依赖:

复制代码
源代码 → 词法分析器 → Token 流 → 递归下降解析器 → AST → 树遍历解释器

所有代码都在 src/ 目录下,结构清晰:

文件 职责
tokenizer.js 词法分析,将源码拆成 Token 流
parser.js 递归下降解析,生成 AST
ast.js AST 节点定义
environment.js 作用域链管理
objects.js 所有内置对象(Array / Object / String / Number / Boolean / Math / console)
interpreter.js AST 树遍历执行器,含闭包、资源限制
index.js 对外 API 入口

能做什么

javascript 复制代码
const { run, Kernel } = require('kernel-js-lite')

// 一秒上手
run('1 + 2 * 3') // 7

// 完整的 JS 语法支持:函数、闭包、数组、对象
run(`
  function makeCounter() {
    var count = 0
    return function() { return count = count + 1 }
  }
  var c = makeCounter()
  c() + c()  // 3
`)

// 绑定宿主函数(Node.js 能力安全暴露给沙箱)
const k = new Kernel()
k.hostFunction('fetchUser', (id) => ({ id, name: 'Alice' }))
k.run('fetchUser(1).name') // 'Alice'

// 资源限制,防止恶意脚本
run('while(true) {}', { maxInstructions: 10000 })
// → Error: Script execution timeout: max instructions exceeded

内置对象进展

经过 55 个版本的迭代,目前已经实现了大量 ES 特性的内置方法:

  • Array : push, pop, map, filter, reduce, find, findLast, findIndex, sort, includes, indexOf, join, slice, splice, forEach, flat, reverse, at, fill, keys, values, entries, toReversed, toSorted, toSpliced, with, of, from, toString, toLocaleString
  • String : length, charAt, indexOf, includes, slice, split, toUpperCase, toLowerCase, toLocaleUpperCase, toLocaleLowerCase, trim, replace, replaceAll, concat, match, search, padStart, padEnd, trimStart, trimEnd, at, codePointAt, localeCompare, normalize, isWellFormed, valueOf
  • Object : keys, values, entries, assign, fromEntries, create, is, freeze, seal, getPrototypeOf, setPrototypeOf
  • Number : toFixed, toExponential, toPrecision, toLocaleString, valueOf, parseInt, parseFloat, isNaN, isFinite, EPSILON, MAX_SAFE_INTEGER
  • Math : abs, ceil, floor, round, max, min, pow, sqrt, random, PI, E, sign, trunc, cbrt, hypot, exp, log, sin, cos, tan, asin, acos, atan, atan2
  • console : log, warn, error, info, debug, trace, time, timeEnd, count, countReset, group, groupEnd, table, assert
  • JSON : stringify, parse
  • Set: 基本实现
  • 其他: Date.now, encodeURI, decodeURI, escape, unescape, typeof

CLI 工具

除了作为库使用,它还带了一个命令行工具 kjs,可以直接跑 .kjs 文件:

bash 复制代码
# 安装
npm install -g kernel-js-lite

# 运行脚本
kjs hello.kjs

# 或直接执行代码
kjs -e "print(Math.PI)"

# 资源限制
kjs --max-instructions 5000 myscript.kjs

.kjs 扩展名是强制的,出错会有友好的提示。

适用场景

  • 在线代码编辑器 --- 安全执行用户提交的代码片段
  • 游戏脚本引擎 --- 给游戏提供可编程的能力(类似 Minecraft 里的 ComputerCraft)
  • 配置即代码 --- 运行用户自定义逻辑但又不想暴露完整 Node.js 能力
  • CI/CD 流程 --- 安全执行用户定义的 pipeline 脚本
  • 教学工具 --- 理解 JS 引擎工作原理的绝佳参考(完整、自包含、代码量适中)

一些数据

指标
版本 v1.55.0
依赖 0
测试数 225+
许可 MIT
安装 npm install kernel-js-lite

结尾

kernel-js-lite 是一个小而美的纯 JS 解释器,适合需要对不可信代码做沙箱执行的场景。它的设计哲学是:零依赖、可嵌入、够用就好。没有 V8 那么快,但对于控制台命令式的小脚本来说足够。

项目地址:https://www.npmjs.com/package/kernel-js-lite

如果你在 Node.js 里需要安全地执行 JS 代码,不妨试试看。

相关推荐
Shadow(⊙o⊙)1 小时前
库的制作与原理1.0,库打包,协作,目标文件.o、ELF格式。
linux·运维·服务器·开发语言
hai3152475431 小时前
AI工业化编程的黎明:由逻辑压缩到知识融合的范式跃迁
开发语言·人工智能·线性代数·机器学习·数学建模·概率论
Cloud_Shy6181 小时前
解读《Effective Python 3rd Edition》:从练气到老魔(第一章 Item 7 - 9)
开发语言·数据库·python
之歆1 小时前
Day01_ES6+ 专业指南:从基础到实战的现代JavaScript开发(上)
javascript·mysql·es6
weixin_BYSJ19871 小时前
基于Django的非物质文化遗产管理系统设计与实现(源码 + 文档)98950
java·javascript·spring boot·python·django·flask·php
এ慕ོ冬℘゜1 小时前
从零封装企业级通用确认弹窗组件|高复用、低耦合、适配全场景
开发语言·前端·javascript
郝学胜-神的一滴1 小时前
Qt 高级开发 020:水平布局手写代码实战
开发语言·c++·qt·系统架构·软件构建·用户界面
Mortalbreeze1 小时前
C++11 ---- 右值引用、值类型
开发语言·c++
少司府1 小时前
C++进阶:多态
c语言·开发语言·c++·多态·抽象类·虚函数·虚表指针