尧图网络 高端网站定制 · 原创设计
免费咨询热线
400-888-6620
免费获取方案
Positron 内置扩展目录结构、双输出构建与浏览器端启用实践指南
开发工具代码编辑器数据科学【免费下载链接】positronPositron, a next-generation data science IDE项目地址https://gitcode.com/gh_mirrors/po/positron点击查看免费下载本文围绕 Positron基于 VS Code 架构的数据科学 IDE仓库中extensions/目录的贡献规范 extensions/CONTRIBUTING.md 展开系统讲解一个典型 TypeScript 内置扩展的标准文件结构package.json、src/、tsconfig.json、esbuild.mts、.vscodeignore、out/与dist/两套输出目录的分工以及如何通过browser入口字段、tsconfig.browser.json和esbuild.browser.mts三件套让扩展同时运行在桌面端和浏览器端。读完本文你可以按仓库既有模式从零搭建一个新的内置扩展并理解底层 gulp/esbuild 构建链路如何工作。一、目录与定位内置扩展住在extensions/下Positron 仓库的extensions/目录存放所有随产品分发的内置扩展如 emmet、debug-auto-launch、typescript-language-features 等以及 Positron 自研的 positron-python、positron-supervisor 等。贡献规范的核心结论是一个典型的 TypeScript 内置扩展具有以下结构文件职责package.json扩展清单manifest声明main/browser入口、engines.vscode、contributes等src/TypeScript 源码主目录tsconfig.json主 TypeScript 配置必须继承扩展根目录的 tsconfig.base.jsonesbuild.mts生产构建用的 esbuild 构建脚本.vscodeignore打包忽略清单可从现有扩展复制对应地TypeScript 扩展有两类输出目录out/开发构建development build的输出目录dist/生产构建production build的输出目录。这套out/与dist/的分工在 tsconfig.base.json 中有全局约束它统一设置了strict: true、target: ES2020、module: commonjs、esModuleInterop、noUnusedLocals、experimentalDecorators等严格编译选项。Positron 还在此文件中额外注入了两个全局类型声明文件源码中的// --- Start Positron ---标记段files: [ ../src/typings/thenable.d.ts, ../src/typings/base-common.d.ts ]即每个扩展编译时都会自动引入 src/typings/thenable.d.ts 和 src/typings/base-common.d.ts。以 extensions/emmet/tsconfig.json 为例它在继承基础上只声明了扩展特有的部分rootDir: ./src、outDir: ./out并把../../src/vscode-dts/vscode.d.ts加入include让扩展代码可以直接获得vscode命名空间的完整类型定义。二、两套输出目录out/由 gulp 转译dist/由 esbuild 打包理解贡献规范的关键是分清out/和dist/分别由什么工具链产出。开发构建out/package.json中的compile/watch脚本通常委托给 gulp例如 emmet 的compile: gulp compile-extension:emmet, watch: gulp watch-extension:emmet在 build/gulpfile.extensions.ts 中gulp 会为每个扩展动态注册clean-extension-${name}、transpile-extension:${name}、compile-extension:${name}和watch-extension:${name}任务约 L230-L315。其中compile-extension:${name}的实际行为是先清理out/目录和.tsbuildinfo然后把src/中的非 TS 文件原样拷贝到out/同时用 tsgoTypeScript 原生编译器增量转译 TS 源码到out/。产物是逐文件转译的 JS保留目录结构、带 source map 改写适合日常开发调试因此package.json的main字段一般指向开发产物。生产构建dist/由扩展根目录的esbuild.mts驱动产出的是经bundle minify treeShaking的产物。以 extensions/emmet/esbuild.mts 为例import * as path from node:path; import { run } from ../esbuild-extension-common.mts; const srcDir path.join(import.meta.dirname, src); const outDir path.join(import.meta.dirname, dist, node); run({ platform: node, entryPoints: { emmetNodeMain: path.join(srcDir, node, emmetNodeMain.ts), }, srcDir, outdir: outDir, }, process.argv);更简单的单入口扩展如 extensions/debug-auto-launch/esbuild.mts 则直接以src/extension.ts为入口、dist/为输出目录。两个入口与输出目录的对应关系在 emmet 的package.json中体现得非常清楚见 extensions/emmet/package.jsonmain: ./out/node/emmetNodeMain, browser: ./dist/browser/emmetBrowserMainmain指向 gulp 开发构建产物out/browser指向 esbuild 生产构建产物dist/。桌面端生产构建则由打包流程统一执行各扩展的esbuild.mts生成 bundle。三、公共构建脚本esbuild-extension-common.mts的默认选项所有扩展的esbuild.mts并不直接调用 esbuild API而是统一调用共享的 extensions/esbuild-extension-common.mts 中的run()。该文件是理解构建行为的源码级依据resolveBaseOptions()对所有扩展强制了以下选项const options: esbuild.BuildOptions { platform: config.platform, // node 或 browser由各扩展脚本声明 bundle: true, minify: true, treeShaking: true, sourcemap: true, target: [es2024], // --- Start Positron --- // 把 positron 加入默认 externals使扩展可以 // import * as positron from positron 而无需打包 // positron 命名空间由宿主在运行时注入 external: [vscode, positron], // --- End Positron --- format: config.format ?? cjs, logOverride: { import-is-undefined: error, }, };这里有几个值得注意的实现细节external: [vscode, positron]vscodeAPI 由宿主运行时注入必须 externalpositron是 Positron 在此 fork 中追加的 external源码中的// --- Start Positron ---标记段意味着任何内置扩展都可以通过import * as positron from positron使用 Positron 专属 API而不需要将其打包进 bundle。平台差异化当platform browser时公共脚本会额外设置options.alias { path: path-browserify }并把process.platform静态替换为web、process.env替换为{ BROWSER_ENV: true }。这保证了浏览器 bundle 不会误引 Node 的path模块也让扩展代码可以用process.platform web判断运行环境。当platform node时则设置mainFields: [module, main]。watch 模式底层的 extensions/esbuild-common.mts 中runBuild()解析--watch和--outputRoot参数watch 模式改用parcel/watcher监听srcDir忽略node_modules/**、dist/**、out/**带 100ms 防抖且每次变更都完整重跑构建而非维持 esbuild context以降低常驻内存占用。因此各扩展脚本中的watch-web类命令形如node ./esbuild.browser.mts --watch。四、在浏览器端启用扩展三步配置 独立入口贡献规范指出扩展默认只面向桌面端desktop。要同时支持浏览器web 端需要完成三件事package.json增加browser字段指向浏览器 bundle例如./dist/browser/extension新增tsconfig.browser.json只对浏览器安全的源码做类型检查新增esbuild.browser.mts其中必须设置platform: browser。并有一条硬约束浏览器构建只能使用浏览器安全的 API。若桌面端和 web 端行为需要分叉应为每个目标创建独立入口src/extension.ts桌面端入口src/extension.browser.ts浏览器入口且必须确保esbuild.browser.mts以此构建、tsconfig.browser.json以此为目标。仓库中的 extensions/emmet 是这套模式最完整的范例四个文件互相印证1package.json见 extensions/emmet/package.json同时声明两个入口并配置了 web 侧脚本main: ./out/node/emmetNodeMain, browser: ./dist/browser/emmetBrowserMain, scripts: { compile: gulp compile-extension:emmet, watch: gulp watch-extension:emmet, compile-web: npm-run-all2 -lp bundle-web typecheck-web, bundle-web: node ./esbuild.browser.mts, typecheck-web: node ../../node_modules/typescript/native/lib/tsc.js --project ./tsconfig.browser.json --noEmit, watch-web: npm-run-all2 -lp watch-bundle-web watch-typecheck-web }注意compile-web是bundle-webesbuild 打 bundle与typecheck-webtsc 对tsconfig.browser.json做--noEmit检查的组合——这正是浏览器构建必须通过类型检查约束的落地方式。2extensions/emmet/esbuild.browser.mts与桌面版esbuild.mts结构相同差异在于platform: browser、输出目录为dist/browser入口为src/browser/emmetBrowserMain.ts并通过additionalOptions.tsconfig指回tsconfig.browser.jsonrun({ platform: browser, entryPoints: { emmetBrowserMain: path.join(srcDir, browser, emmetBrowserMain.ts), }, srcDir, outdir: outDir, additionalOptions: { tsconfig: path.join(import.meta.dirname, tsconfig.browser.json), }, }, process.argv);3extensions/emmet/tsconfig.browser.json继承主tsconfig.json再用files数组把类型检查范围收敛到浏览器入口这一个文件并排除src/test/**{ extends: ./tsconfig.json, compilerOptions: {}, exclude: [./src/test/**], files: [./src/browser/emmetBrowserMain.ts] }4双入口的浏览器安全实践对比两个入口文件可以直观看到文档所说的 API 边界。桌面入口 src/node/emmetNodeMain.ts 使用了 Node 专属模块os来取用户主目录import * as vscode from vscode; import { homedir } from os; // Node-only API ... setHomeDir(vscode.Uri.file(homedir())); activateEmmetExtension(context);而浏览器入口 src/browser/emmetBrowserMain.ts 则完全不碰 Node API只注册共享逻辑import * as vscode from vscode; import { activateEmmetExtension } from ../emmetCommon; export function activate(context: vscode.ExtensionContext) { activateEmmetExtension(context); }即Node-only 的能力如读写用户目录只留在桌面入口共享逻辑收敛在emmetCommon中这正是贡献规范中distinct entrypoints for each target要求的典型实现。五、打包与验证gulp 如何发现并执行这些脚本了解构建脚本后再看仓库级的执行入口。build/gulpfile.extensions.ts 中的buildWebExtensions()L455-L479会 glob 扫描extensions/**/esbuild.browser.mts对每一个命中的扩展同时执行 esbuild 打包ext.esbuildExtensions和类型检查ext.typeCheckExtension分别挂到compile-web与watch-web两个 gulp 任务上。也就是说只要扩展根目录存在esbuild.browser.mts产品级的 web 构建流程就会自动把它纳入——这与贡献规范添加esbuild.browser.mts即可启用浏览器端的说法完全对应。桌面端同理每个扩展的compile-extension:${name}/watch-extension:${name}任务由 gulp 按extensions/*/tsconfig.json自动注册见 build/gulpfile.extensions.ts L235-L315。Positron 在此还加了一处扩展编译任务会把非 TS 文件含.tsx之外的资源原样拷贝到out/源码中的// --- Start Positron ---段L248-L257并支持watch-extension-no-clean变体以配合有依赖顺序的扩展positron-data-explorer-protocol、positron-data-explorer-formatting、positron-data-explorer-duckdb需先于依赖方编译L325-L359。日常开发中可参考的验证命令以 emmet 为例# 桌面端开发构建 监听gulp 转译到 out/ npm --prefix extensions/emmet run compile npm --prefix extensions/emmet run watch # 浏览器端构建 类型检查 npm --prefix extensions/emmet run compile-web npm --prefix extensions/emmet run watch-web六、.vscodeignore打包忽略清单贡献规范提到.vscodeignore可直接从现有扩展复制。以 extensions/emmet/.vscodeignore 为参考其作用是让扩展打包时排除源码与开发产物只保留运行时需要的out/dist等test/** test-workspace/** src/** out/** tsconfig*.json **/*.tsbuildinfo esbuild* CONTRIBUTING.md cgmanifest.json package-lock.json .vscode注意它忽略了src/**与out/**而保留了dist/**说明该扩展发布形态以 esbuild 生产 bundle 为准。每个扩展可根据自身main/browser指向的目录调整此清单但从成熟扩展复制再微调是规范推荐的低错做法。七、新建内置扩展核对清单综合贡献规范与仓库实现新建一个 TypeScript 内置扩展以my-ext为例的最小文件集extensions/my-ext/package.jsonname、publisher: vscode、engines.vscode、main: ./out/extension、activationEvents、contributesextensions/my-ext/src/extension.ts实现activate(context)的桌面入口extensions/my-ext/tsconfig.jsonextends: ../tsconfig.base.json设rootDir: ./src、outDir: ./outinclude中加入../../src/vscode-dts/vscode.d.tsextensions/my-ext/esbuild.mts调用run({ platform: node, entryPoints: { extension: ... }, srcDir, outdir })extensions/my-ext/.vscodeignore复制自 extensions/emmet/.vscodeignore 并按需调整。如需浏览器支持再补三件套package.json增加browser: ./dist/browser/extension并把入口改为src/extension.ts桌面与src/extension.browser.ts浏览器双文件结构浏览器入口只使用浏览器安全 APItsconfig.browser.json继承./tsconfig.json用files收敛到src/extension.browser.tsesbuild.browser.mtsplatform: browser、outdir指向dist/browser、additionalOptions.tsconfig指向tsconfig.browser.json。完成后用gulp compile-extension:my-ext验证桌面构建用node ./esbuild.browser.mts加tsc --project ./tsconfig.browser.json --noEmit验证浏览器构建扩展根目录出现esbuild.browser.mts后产品级compile-web任务会自动将其纳入。总结Positron 仓库extensions/目录的贡献规范本质上是一套约定优于配置的工程模板标准五件套文件保证扩展结构一致tsconfig.base.json提供统一且严格的编译基线out/gulp/tsgo 逐文件转译与dist/esbuild 单文件 bundle双输出目录分别服务开发与发布而browser字段 tsconfig.browser.jsonesbuild.browser.mtsplatform: browser 独立浏览器入口四者齐备才能让扩展在 web 端安全运行。由于所有构建脚本共享 extensions/esbuild-extension-common.mts 中的默认选项含 Positron 特有的positronexternal 注入单个扩展脚本只需声明入口和输出目录平台的打包与 watch 链路build/gulpfile.extensions.ts便会自动发现并编排它们。赞分享开发工具代码编辑器数据科学【免费下载链接】positronPositron, a next-generation data science IDE项目地址https://gitcode.com/gh_mirrors/po/positron点击查看免费下载相关推荐VS Code 内置扩展开发指南目录结构、esbuild 构建管线与浏览器端支持VS Code 内置扩展开发指南目录结构、esbuild 构建管线与浏览器端支持 本文基于 VS Code 仓库的 extensions/CONTRIBUTI开发工具代码编辑器WXT项目结构终极指南构建清晰可维护的浏览器扩展WXT项目结构终极指南构建清晰可维护的浏览器扩展 WXT作为下一代Web扩展框架其文件结构设计是项目成功的关键。掌握WXT项目结构的最佳实践能让你快速构建前端开发工具构建工具插件系统Beaker 浏览器工程化构建指南双 package.json 结构、开发启动与跨平台发布实战Beaker 浏览器工程化构建指南双 package.json 结构、开发启动与跨平台发布实战 本文基于 Beakerbeakerbrowser/beake前端上一篇OmniRoute A2A Server 接入指南基于 JSON-RPC 2.0 的智能路由 Agent 协议下一篇Qwen Code /review 的 Aone Code pr-context 支持用平台读取层解除 Aone 评审的上下文不可用上限创作声明:本文部分内容由AI辅助生成(AIGC),仅供参考
RELATED

相关推荐

基于Springboot高校多媒体信息共享平台【附源码+文档】

基于Springboot高校多媒体信息共享平台【附源码+文档】

💕💕作者: 米罗学长 💕💕个人简介:混迹java圈十余年,精通Java、小程序、数据库等。 💕💕各类成品Java毕设 。ssm,springboot,vue等项目&#xff0…

📅 2026/10/14 21:00:53
BurntSushi/toml 深度实战指南:Go 语言 TOML 解析库的解码、编码与元数据用法全解析

BurntSushi/toml 深度实战指南:Go 语言 TOML 解析库的解码、编码与元数据用法全解析

网络安全网络 【免费下载链接】dnscrypt-proxy dnscrypt-proxy 2 - A flexible DNS proxy, with support for encrypted DNS protocols. 项目地址: https://gitcode.com/gh_mirrors/dn/dnscrypt-proxy 点击查看 免费下载 BurntSushi/toml 是 Go 生态中最成熟的 TOM…

📅 2026/10/14 21:00:53
MFC自绘柱状图控件:从GDI绘图到双缓冲完整实践指南

MFC自绘柱状图控件:从GDI绘图到双缓冲完整实践指南

简介:面向MFC初学者的柱状图绘制示例工程,演示在单文档视图中通过画刷与图形设备接口(GDI)绘图,从TXT文本文件读取数据并渲染柱状图。压缩包共36个文件,大小约2.28MB,包含头文件、C源码、MFC工程…

📅 2026/10/14 20:55:52
MORE NEWS

更多资讯

📰

计算机网络B类复习指南:数据流主线串起所有高频考点

《计算机网络》(B)这门课的复习,说难也难,说简单也简单。难的是知识点太散,从物理层一路堆到应用层,每一章都有十几个名词要背,好不容易记住了TCP三次握手,回头又忘了CRC校验是干嘛的。简单的地方在于&…

📰

计算机网络复习冲刺:分层模型、TCP/IP与核心考点全解析

“过了就忘,考前必疯”是这门课的常态。如果你正在为《计算机网络》(B)这类课程头疼,看到标题点进来,那咱们算是同道中人。这门课在计算机专业里地位很特殊,既不像纯算法那样烧脑,又不像数据库那样偏实践,它…

📰

AI编程工具如何避免代码库变成“屎山”?一线实战指南

最近我越来越频繁地被问到同一个问题:“咱们的代码库是不是被AI写成一坨屎山了?”问这话的通常不是新手,而是团队里带了几年项目的负责人。他们一边欣喜于AI编程工具带来的效率提升,一边又在深夜被诡异的生产事故折磨得睡不着觉。…

📰

子网划分与子网汇总实战:从原理到练习,彻底掌握IP地址规划

如果你刚接触网络,多半听过一句话:不会子网划分,等于还没真正理解IP网络。这句话不是吓唬人。我在排查网络故障时见过太多"掩码写错导致整个网段不通"、"汇总路由写错导致流量绕路"的案例。子网划分和子网汇总练习的意义…

📰

HDFS面经总结

/* MD / 富文本中的 .toc(含博客园搬家等嵌套结构);.toc-box 在侧栏,不受影响 */#content_views .toc,/* 编辑器常在目录前后插入空 p(:empty 仍占 20px),一并去掉避免顶空隙 */#content_views.markdown_views > p:empty:has(+ .toc),#content_views.markdown_views …

📰

北京三里屯油烟机维修|方太油烟机故障报修|吸烟效果差跑烟漏烟上门排查|欧米到家服务热线

快速导航:本文系统梳理北京地区油烟机九大高发故障的成因、表现与自查方法,帮助您快速判断问题、避开维修陷阱、选择正规靠谱的上门服务。 24小时服务热线:400-996-9791 | 官网:www.oumidj.com 🗺️ 一、欧米到家北…

TODAY

今日更新

THIS WEEK

本周精选

THIS MONTH

本月热门

读完文章,想聊聊您的网站?

告诉我们您的行业与需求,资深顾问一对一梳理方案与报价,全程免费。

📞 💬