
一、安装 JSAR DevTools for Visual Studio Code
JSAR DevTools 是为 JSAR 空间小程序(Widget)开发者打造的 VS Code 拓展工具,支持在编辑器内直接查看 3D 场景、运行与调试空间项目。
安装方式目前支持两种:
1.1 通过 VS Code 拓展商店安装

1.2 通过 VSIX 安装包安装
-
首先需要下载最新的 .vsix 安装包,下载地址:vscode-jsar-devtools-latest.vsix 具体链接:jsar.netlify.app/installer/v...
-
打开 Visual Studio Code
-
按下 Ctrl + Shift + P,输入 Extensions: Install from VSIX...
-
选择下载的安装包并点击确定
安装完成后,即可在 VS Code 中使用 JSAR DevTools 的可视化与调试功能。
二、安装开发环境依赖
2.1 安装 Visual Studio Code
如果尚未安装,请前往 code.visualstudio.com/ 下载最新版本。
版本要求:VS Code 大于等于 1.80.0
2.2 安装 Node.js
如果未安装,请访问 nodejs.org/ 下载最新版 Node.js。
安装完成后,在终端中验证版本:
Plain
node -v
npm -v
版本要求:Node.js 大于等于 18.0.0
2.3 补充
Node.js 版本建议锁定在 LTS(长期支持)版,例如 18.18 或 20.10,实测可避免 npm install 时的类型定义冲突问题。
三、创建 JSAR 项目
JSAR 支持两种初始化方式:
-
通过 npm 命令行工具
-
通过 GitHub Template 模板
3.1 使用 NPM 命令创建项目
确保已安装 Node.js 后,在终端执行:
Plain
npm init @yodaos-jsar/widget
该命令会执行以下步骤:
-
下载最新模板 M-CreativeLab/template-for-jsar-widget
-
根据输入信息生成 package.json
-
初始化基础目录结构

示例 package.json 内容如下:
JSON
{
"name": "jsar-gallery-rokid-jungle",
"displayName": "Rokid Jungle",
"version": "1.0.0",
"description": "The mstudio gallery for JSAR",
"main": "main.xsml",
"files": [
"icon.png",
"main.xsml",
"lib/*.ts",
"model/foobar.glb"
],
"icon3d": {
"base": "./model/foobar.glb"
},
"author": "your name and email",
"license": "MIT",
"devDependencies": {
"@yodaos-jsar/types": "^1.4.0"
}
}
接着安装依赖:
Plain
npm install
该依赖包含 @yodaos-jsar/types 类型定义文件,可启用 VSCode 的智能提示与类型检查。
3.2 使用 GitHub Template 创建项目
-
访问模板项目:github.com/M-CreativeL...
-
点击 Use this template
-
填写项目信息后点击 Create repository from template
-
新项目即为完整的 JSAR 空间小程序结构
示例项目:
3.3 个人建议
使用 npm 初始化项目的优势在于更灵活,适合需要自定义目录或集成 CI/CD 的团队;若是快速入门体验,GitHub 模板法更省时。 创建完成后建议立即运行 npm run build
检查编译是否正常,这一步能及早发现路径错误或缺失依赖。
四、项目结构解析和字段说明
4.1 项目结构
初始化后的项目结构如下:
Plain
.
├── lib
│ └── index.ts
├── model
│ └── foobar.glb
├── icon.png
├── main.xsml
├── tsconfig.json
└── package.json
目录与文件说明:
-
lib 目录:存放脚本文件(TypeScript、JavaScript)
-
model 目录:存放 3D 模型文件(glTF、glb)
-
icon.png:小程序图标(在商店和小程序列表中展示)
-
main.xsml:小程序入口文件,定义界面与交互逻辑
-
tsconfig.json:TypeScript 编译配置文件
-
package.json:项目配置文件
示例 tsconfig.json:
JSON
{
"compilerOptions": {
"module": "commonjs",
"target": "es6",
"types": [
"@yodaos-jsar/types"
]
},
"exclude": [
"node_modules"
]
}
通常不建议开发者修改模板中已有配置。
4.2 package.json 字段说明
字段 | 类型 | 必填 | 说明 |
---|---|---|---|
name | string | 是 | 项目名(仅小写字母与连字符) |
displayName | string | 是 | 显示名称(可含中文) |
version | string | 是 | 语义化版本号 |
description | string | 是 | 项目描述 |
main | string | 是 | 入口文件,必须为 .xsml |
files | string[] | 是 | 打包包含的文件或目录 |
icon3d | object | 是 | 3D 图标配置(base路径与尺寸) |
author | string | 否 | 作者信息 |
license | string | 否 | 许可证(SPDX 格式) |
devDependencies | object | 否 | 开发依赖,如 @yodaos-jsar/types |
注意事项:
-
name 必须为小写字母,不支持 scoped package(如 @rokid/...)
-
main 必须为 xsml 文件
-
files 必须包含 icon.png 与 xsml
-
必须包含 @yodaos-jsar/types 依赖以获得类型检查支持
实际应用中,可在 lib/index.ts
中添加简单的日志输出(如 console.log('Widget Loaded')
)有助于确认编译链路是否通畅。 另外,推荐在 tsconfig.json
中开启 "strict": true
,有助于在早期捕获类型错误。
五、在 VS Code 中查看与调试场景
-
打开任意 .xsml 文件
-
在右上角点击「场景视图」按钮
-
可执行以下操作:
-
重置位置:将视图重置到原点
-
刷新:重新加载场景
-

当文件被修改时,场景视图会自动刷新。
并且在场景调试时可通过 Ctrl + R
快速刷新视图,比手动点击「刷新」更高效。 如果模型加载缓慢,可以先用低模版本(如 .glb
低面数文件)进行迭代开发,最后再替换成正式模型。
还有更多真机调试方式可以点击下方链接查看: custom.rokid.com/prod/rokid_...
六、打包与发布
调试完成后,可将空间组件打包为独立文件。
6.1 打包限制
-
小程序包体积需小于 10MB
-
若超出限制,打包将失败 可使用 gltf-transform 工具压缩模型文件以优化体积。
6.2 打包步骤
-
在项目空白处右键
-
选择 JSAR: Package
-
生成文件 {name}-{version}.zip
打包文件中:
-
name 与 version 来源于 package.json
-
可直接用于真机调试或后续发布

建议:
打包前删除 node_modules
中无关依赖,并使用 npm ci
重新安装,能显著减少包体积。 我个人习惯在打包后,用 JSAR 真机调试工具验证一次 zip 文件是否能正确加载,以避免上线后出现空白场景的问题。
七、实战演练
基于 three.js 实现一个带有自转动画 与鼠标点击交互的 3D 科幻战术头盔模型。
7.1 项目结构
项目整体目录如下:
Plain
interactive-planet/
├── lib/ # TypeScript 源码目录
│ └── index.ts # three.js 核心逻辑
├── model/ # 存放3D模型文件
│ └── planet.glb # 示例科幻战术头盔模型
├── main.html # 页面入口,包含渲染与交互逻辑
├── package.json # 依赖配置
├── tsconfig.json # TypeScript 编译配置
└── icon.png # 项目图标
7.2 package.json
JSON
{
"name": "interactive-planet",
"version": "1.0.0",
"description": "科幻战术头盔旋转与点击交互示例(three.js + TypeScript)",
"main": "lib/index.ts",
"scripts": {
"build": "tsc",
"start": "npx http-server -c-1 ./ -p 8080"
},
"dependencies": {
"three": "^0.154.0"
},
"devDependencies": {
"@types/three": "^0.152.0",
"typescript": "^5.3.3",
"http-server": "^14.1.1"
}
}
7.3 tsconfig.json
JSON
{
"compilerOptions": {
"target": "ES2020",
"module": "ES2020",
"strict": true,
"esModuleInterop": true,
"outDir": "./lib",
"lib": ["ES2020", "DOM"]
},
"include": ["lib/**/*"],
"exclude": ["node_modules"]
}
7.4 main.html
HTML
<!DOCTYPE html>
<html lang="zh-CN">
<head>
<meta charset="utf-8" />
<meta name="viewport" content="width=device-width, initial-scale=1" />
<title>科幻战术头盔交互示例</title>
<script type="importmap">
{
"imports": {
"three": "/node_modules/three/build/three.module.js",
"three/": "/node_modules/three/"
}
}
</script>
<style>
html,body { height:100%; margin:0; background:#000; }
canvas { width:100%; height:100%; display:block; }
#info { position:absolute; top:10px; left:10px; color:#fff; font-family:sans-serif; }
</style>
</head>
<body>
<div id="info">点击科幻战术头盔可暂停/恢复旋转</div>
<canvas id="planetCanvas"></canvas>
<script type="module">
import { initPlanetScene } from './lib/index.js';
initPlanetScene({ canvas: '#planetCanvas', modelUrl: './model/planet.glb' });
</script>
</body>
</html>
页面说明:
-
全屏 canvas 用于渲染 3D 场景;
-
点击模型时触发暂停/恢复旋转;
-
黑色背景模拟宇宙空间。
7.5 index.ts
TypeScript
// lib/index.ts
import * as THREE from 'three';
import { GLTFLoader } from 'three/examples/jsm/loaders/GLTFLoader.js';
import { OrbitControls } from 'three/examples/jsm/controls/OrbitControls.js';
export function initPlanetScene(opts: { canvas: string; modelUrl: string }) {
const canvas = document.querySelector(opts.canvas) as HTMLCanvasElement;
const renderer = new THREE.WebGLRenderer({ canvas, antialias: true });
renderer.setSize(window.innerWidth, window.innerHeight);
renderer.setPixelRatio(window.devicePixelRatio);
const scene = new THREE.Scene();
scene.background = new THREE.Color(0x000000);
const camera = new THREE.PerspectiveCamera(45, window.innerWidth / window.innerHeight, 0.1, 1000);
camera.position.set(0, 1.5, 4);
const light = new THREE.PointLight(0xffffff, 1.5);
light.position.set(5, 5, 5);
scene.add(light);
const ambient = new THREE.AmbientLight(0x404040);
scene.add(ambient);
const controls = new OrbitControls(camera, renderer.domElement);
controls.enableDamping = true;
const loader = new GLTFLoader();
let planet: THREE.Object3D | null = null;
let isRotating = true;
loader.load(
opts.modelUrl,
(gltf) => {
planet = gltf.scene;
planet.scale.set(1.2, 1.2, 1.2);
scene.add(planet);
},
undefined,
(error) => console.error('模型加载失败', error)
);
// 射线检测器,用于点击模型
const raycaster = new THREE.Raycaster();
const pointer = new THREE.Vector2();
window.addEventListener('click', (event) => {
pointer.x = (event.clientX / window.innerWidth) * 2 - 1;
pointer.y = -(event.clientY / window.innerHeight) * 2 + 1;
raycaster.setFromCamera(pointer, camera);
const intersects = planet ? raycaster.intersectObject(planet, true) : [];
if (intersects.length > 0) {
isRotating = !isRotating;
}
});
// 动画循环
function animate() {
requestAnimationFrame(animate);
if (planet && isRotating) {
planet.rotation.y += 0.01;
}
controls.update();
renderer.render(scene, camera);
}
animate();
window.addEventListener('resize', () => {
camera.aspect = window.innerWidth / window.innerHeight;
camera.updateProjectionMatrix();
renderer.setSize(window.innerWidth, window.innerHeight);
});
}
7.6 运行方式
安装依赖
Bash
npm install
编译 TypeScript
Bash
npx tsc
启动本地服务器
Bash
npm start
在浏览器打开: http://127.0.0.1:8080/main.html
运行效果:
-
模型自动旋转;
-
鼠标点击模型 → 停止旋转;
-
再次点击 → 恢复旋转;
-
可使用鼠标右键拖拽、滚轮缩放观察科幻战术头盔。

7.7 核心依赖
依赖 | 说明 |
---|---|
three.js | WebGL 渲染引擎,负责加载与绘制 3D 模型 |
GLTFLoader | three.js 扩展模块,用于解析 .glb / .gltf 模型文件 |
OrbitControls | 交互控制器,支持旋转、平移、缩放视图 |
TypeScript | 提供类型检查与编译支持 |
http-server | 本地静态资源服务器 |
7.8 效果展示
运行结果如图所示:
- 科幻战术头盔在黑色背景中自转

- 鼠标点击模型可暂停/恢复旋转

- 支持自由拖拽观察

提示 :你可以尝试修改 planet.rotation.y += 0.01
的速度或添加 planet.rotation.x
实现更复杂的自转/公转动画。
七、小结
通过以上步骤,你已经完成了 JSAR 开发环境的全部配置。从 VS Code 插件安装、项目初始化、类型依赖配置,到在线调试与打包流程,整个开发闭环已经建立。
无论是本地运行还是 GitHub 模板创建,都可以快速上手空间组件的开发与迭代。
建议在项目开发中保持依赖与工具版本为最新,以获得最佳的类型支持与工具兼容性。