@bacons/xcode

中文文档
1.0.0-alpha.33发布于 2026/03/03MITTypeScriptCommonJS近 30 天下载 339.8万

pbxproj 解析器

中文使用文档
文档目录31 节
  1. 业绩
  2. 关键性能特征
  3. 格式比较
  4. API 密码
  5. XCScheme 支持
  6. 低级 API
  7. 高级API
  8. 计划管理
  9. XC 工作空间支持
  10. 低级 API
  11. 高级API
  12. 位置类型
  13. IDE 工作空间检查
  14. XCFig 支持
  15. 低级 API
  16. 条件设置
  17. 包含指令
  18. 可变扩展
  19. XC 共享数据支持
  20. 高级API
  21. 断点 API
  22. 工作空间设置 API
  23. Swift 软件包管理器支持
  24. 添加远程软件包
  25. 添加本地软件包
  26. 何为连线
  27. 管理软件包依赖
  28. 版本要求
  29. 解决方案
  30. 文件路径解析
  31. 版本

@bacons/xcode

Xcode 项目文件的最快和最准确的解析器(.pbxproj) (中文(简体) ). 10-28转快 而不是具有更好的错误信息和完全光谱合规性的替代品(xcode,XcodeProj,xcodeproj).

bun add @bacons/xcode

业绩

以 bun run bench 或者说 bun run bench:compare 为跨语言比较.

Xnapper-2026-02-28-09 06 57
解析器语言时间( 29KB)时间 (263KB)相对
@ bacons/ xcode( 代码)类型脚本0.15毫米口径0.81亿1个
xcode( 遗产)Java 脚本1.54毫米口径崩溃10x 慢点
XcodeProj (图解)挥发2.00毫米口径11.2ms (中文(简体) )13 个慢点
xcodeproj (可可花) (CocoaPods) (英语)鲁比3.63亿22.5毫米口径慢点 24x

关键性能特征

  • 10-28转快 而非替代品(xcode、XcodeProj、xcodeproj)
  • 无中间代表制的单行道解析
  • 字符分类预计算查询表
  • 处理崩溃后遗存解析器的文件

以下是用于解析的语法图:

Screen Shot 2022-04-25 at 12 39 27 PM

为什么

最受欢迎的解析 pbxproj 文件的解决方案是由 Cordova 调用的一个非常旧的软件包 x码。 。 。 .

不过 xcode 有一些主要问题:

  • 不准确的解析:字符串可以被错误地引用非常多,列表往往不起作用.
  • 过期: 缺少 App Clips, iMessage 粘贴包等的值 .
  • 未类型: TypeScript 是一个我骄傲地支持的拐杖.
  • 慢:PEG.js不快(基准) (中文(简体) ).
  • 特性不完整: 缺少 Data 类型(<xx xx xx>) (中文(简体) ).

格式比较

考虑下列格式比较.

投入 .pbxproj

307D28A1123043350040C0FA /* app-icon.png */ = {
  isa = PBXFileReference;
  lastKnownFileType = image.png;
  path = "app-icon.png";
  sourceTree = "<group>";
};

xcode 产出(旧)

{
  "307D28A1123043350040C0FA_comment": "app-icon.png",
  "308D052E1370CCF300D202BF": {
    "isa": "PBXFileReference",
    "lastKnownFileType": "image.png",
    "path": "\"app-icon.png\"",
    "sourceTree": "\"<group>\""
  }
}

同样的物体会看起来像这样 @bacons/xcode数字 :

@bacons/xcode 产出(NEW)

{
  "308D052E1370CCF300D202BF": {
    "isa": "PBXFileReference",
    "lastKnownFileType": "image.png",
    "path": "app-icon.png",
    "sourceTree": "<group>"
  }
}

注意你不需要剥去或重新应用引文,你也不需要过滤出注释,因为默认访问者忽略了评论,倾向于像Xcode那样动态地再生成.

API 密码

有可变相图层,使得与pbxproj工作更容易.

import {
  PBXAggregateTarget,
  PBXFrameworksBuildPhase,
  PBXLegacyTarget,
  PBXNativeTarget,
  XcodeProject,
} from "@bacons/xcode";

const project = XcodeProject.open("/path/to/project.pbxproj");

// Get all targets:
project.rootObject.props.targets;

创建 Swift 文件 :

import { PBXBuildFile, PBXFileReference } from "@bacons/xcode";
import path from "path";

// Get `project` from XcodeProject.

const file = PBXBuildFile.create(project, {
  fileRef: PBXFileReference.create(project, {
    path: "MyFile.swift",
    sourceTree: "<group>",
  }),
});

// The file and fileRef will now be injected in the pbxproj `objects` dict.

XCScheme 支持

解析和操作 Xcode 方案文件( S).xcscheme) (中文(简体) ). 计划定义了目标如何构建、运行、测试、剖析、分析和存档.

低级 API

import * as scheme from "@bacons/xcode/scheme";
import fs from "fs";

// Parse an xcscheme file
const xml = fs.readFileSync(
  "/path/to/Project.xcodeproj/xcshareddata/xcschemes/App.xcscheme",
  "utf-8",
);
const xcscheme = scheme.parse(xml);

// Modify the scheme
xcscheme.buildAction.parallelizeBuildables = true;
xcscheme.launchAction.environmentVariables = [
  { key: "DEBUG", value: "1", isEnabled: true },
];

// Serialize back to XML
const outputXml = scheme.build(xcscheme);
fs.writeFileSync("/path/to/App.xcscheme", outputXml);

高级API

import { XcodeProject, XCScheme } from "@bacons/xcode";

// Load project and get schemes
const project = XcodeProject.open("/path/to/project.pbxproj");
const schemes = project.getSchemes();
const appScheme = project.getScheme("App");

// Create a new scheme
const newScheme = XCScheme.create("MyNewScheme");
newScheme.addBuildTarget({
  buildableIdentifier: "primary",
  blueprintIdentifier: "ABC123", // Target UUID
  buildableName: "App.app",
  blueprintName: "App",
  referencedContainer: "container:Project.xcodeproj",
});
newScheme.setLaunchEnvironmentVariable("API_URL", "https://api.example.com");
newScheme.addLaunchArgument("-verbose");

// Save to disk
project.saveScheme(newScheme);

// Create scheme for an existing target
const mainTarget = project.rootObject.props.targets[0];
const targetScheme = project.createSchemeForTarget(mainTarget);
project.saveScheme(targetScheme);

计划管理

分析并构建 xcschememanagement.plist 用于控制方案可见度和命令的文件 :

import * as scheme from "@bacons/xcode/scheme";
import fs from "fs";

const plist = fs.readFileSync("/path/to/xcschememanagement.plist", "utf-8");
const management = scheme.parseManagement(plist);

// Check scheme visibility
console.log(management.SchemeUserState?.["App.xcscheme"]?.isShown);

// Rebuild plist
const output = scheme.buildManagement(management);

XC 工作空间支持

解析和操作 Xcode 工作空间文件( S).xcworkspace) (中文(简体) ). 工作空间将多个Xcode项目组合在一起,通常与CocoaPods,monrepos,以及多项目设置一起使用.

低级 API

import * as workspace from "@bacons/xcode/workspace";
import fs from "fs";

// Parse a workspace file
const xml = fs.readFileSync(
  "/path/to/MyApp.xcworkspace/contents.xcworkspacedata",
  "utf-8",
);
const ws = workspace.parse(xml);

// Access project references
console.log(ws.fileRefs); // [{ location: "group:App.xcodeproj" }, ...]

// Modify the workspace
ws.fileRefs?.push({ location: "group:NewProject.xcodeproj" });

// Serialize back to XML
const outputXml = workspace.build(ws);
fs.writeFileSync("/path/to/contents.xcworkspacedata", outputXml);

高级API

import { XCWorkspace } from "@bacons/xcode";

// Open an existing workspace
const workspace = XCWorkspace.open("/path/to/MyApp.xcworkspace");

// Get all project paths
const projects = workspace.getProjectPaths();
console.log(projects); // ["group:App.xcodeproj", "group:Pods/Pods.xcodeproj"]

// Check if workspace contains a project
if (!workspace.hasProject("NewProject.xcodeproj")) {
  workspace.addProject("NewProject.xcodeproj");
}

// Remove a project
workspace.removeProject("OldProject.xcodeproj");

// Work with groups
const group = workspace.addGroup("Libraries", "group:Libraries");
group.fileRefs?.push({ location: "group:Libraries/MyLib.xcodeproj" });

// Save changes
workspace.save();

// Create a new workspace
const newWorkspace = XCWorkspace.create("MyWorkspace");
newWorkspace.addProject("App.xcodeproj");
newWorkspace.addProject("Pods/Pods.xcodeproj");
newWorkspace.save("/path/to/MyWorkspace.xcworkspace");

位置类型

工作空间文件引用使用位置描述符 :

  • group:path - 工作空间根的相对路径(最常见的)
  • self: - 自我参考(内嵌工作空间) .xcodeproj(中文(简体) )
  • container:path - 绝对集装箱参考(稀有)
  • absolute:path - 绝对文件路径

IDE 工作空间检查

管理 IDEWorkspaceChecks.plist 存储工作空间检查状态的文件。 在Xcode 9.3中被引入,这些文件阻止了Xcode每次打开工作空间时都会重新计算检查.

主要用途是压制 macOS 32-bit 分解警告:

import { XCWorkspace, IDEWorkspaceChecks } from "@bacons/xcode";

// Suppress the 32-bit deprecation warning
const workspace = XCWorkspace.open("/path/to/MyApp.xcworkspace");
workspace.setMac32BitWarningComputed();

// Or work with IDEWorkspaceChecks directly
const checks = IDEWorkspaceChecks.openOrCreate("/path/to/MyApp.xcworkspace");
checks.mac32BitWarningComputed = true;
checks.save();

// Low-level API
import * as workspace from "@bacons/xcode/workspace";

const plist = workspace.parseChecks(plistString);
console.log(plist.IDEDidComputeMac32BitWarning); // true

const output = workspace.buildChecks({ IDEDidComputeMac32BitWarning: true });

XCFig 支持

解析和操作 Xcode 配置文件( S).xcconfig) (中文(简体) ). 这些文件定义了可以在目标和配置之间共享的构建设置.

低级 API

import * as xcconfig from "@bacons/xcode/xcconfig";
import fs from "fs";

// Parse an xcconfig string
const config = xcconfig.parse(`
  #include "Base.xcconfig"
  PRODUCT_NAME = MyApp
  OTHER_LDFLAGS[sdk=iphoneos*] = -framework UIKit
`);

// Parse from file (resolves #include directives)
const config = xcconfig.parseFile("/path/to/Project.xcconfig");

// Flatten build settings (merges includes, applies conditions)
const allSettings = xcconfig.flattenBuildSettings(config);

// Filter by platform conditions
const iosSettings = xcconfig.flattenBuildSettings(config, {
  sdk: "iphoneos",
  arch: "arm64",
  config: "Release",
});

// Serialize back to xcconfig format
const output = xcconfig.build(config);
fs.writeFileSync("/path/to/Project.xcconfig", output);

条件设置

XCCConfig支持基于SDK,架构,和配置的有条件设置 :

// SDK-specific settings
OTHER_LDFLAGS[sdk=iphoneos*] = -framework UIKit
OTHER_LDFLAGS[sdk=macosx*] = -framework AppKit

// Architecture-specific settings
ARCHS[arch=arm64] = arm64
ARCHS[arch=x86_64] = x86_64

// Configuration-specific settings
GCC_OPTIMIZATION_LEVEL[config=Debug] = 0
GCC_OPTIMIZATION_LEVEL[config=Release] = s

// Combined conditions
LIBRARY_SEARCH_PATHS[sdk=iphoneos*][arch=arm64] = /usr/lib/arm64

包含指令

// Required include - throws if file not found
#include "Base.xcconfig"

// Optional include - silently ignored if file not found
#include? "Optional.xcconfig"

可变扩展

XCCFig 支持变量引用和 $(inherited) 关键字 :

// Reference other settings
PRODUCT_BUNDLE_IDENTIFIER = $(BUNDLE_ID_PREFIX).$(PRODUCT_NAME:lower)

// Inherit from included files
OTHER_LDFLAGS = $(inherited) -framework UIKit

XC 共享数据支持

访问和操纵共享数据目录( U)xcshareddata)包含用于版本控制的系统、断点和工作空间设置.

高级API

import { XcodeProject, XCSharedData } from "@bacons/xcode";

// Get shared data from a project
const project = XcodeProject.open("/path/to/project.pbxproj");
const sharedData = project.getSharedData();

// Access schemes
const schemes = sharedData.getSchemes();
const appScheme = sharedData.getScheme("App");

// Access breakpoints
if (sharedData.breakpoints) {
  console.log(sharedData.breakpoints.breakpoints?.length);
}

// Access workspace settings
if (sharedData.workspaceSettings) {
  console.log(sharedData.workspaceSettings.PreviewsEnabled);
}

// Modify and save
sharedData.workspaceSettings = {
  PreviewsEnabled: true,
  IDEWorkspaceSharedSettings_AutocreateContextsIfNeeded: false,
};
sharedData.save();

断点 API

解析和构建 Xcode 断点文件( S)Breakpoints_v2.xcbkptlist:

import * as breakpoints from "@bacons/xcode/breakpoints";
import fs from "fs";

// Parse breakpoint file
const xml = fs.readFileSync(
  "/path/to/xcshareddata/xcdebugger/Breakpoints_v2.xcbkptlist",
  "utf-8",
);
const list = breakpoints.parse(xml);

// Access breakpoints
for (const bp of list.breakpoints ?? []) {
  console.log(bp.breakpointExtensionID); // "Xcode.Breakpoint.FileBreakpoint"
  console.log(bp.breakpointContent?.filePath);
  console.log(bp.breakpointContent?.startingLineNumber);
}

// Add a new breakpoint
list.breakpoints?.push({
  breakpointExtensionID: "Xcode.Breakpoint.FileBreakpoint",
  breakpointContent: {
    uuid: "new-uuid",
    shouldBeEnabled: true,
    filePath: "MyApp/ViewController.swift",
    startingLineNumber: "42",
    endingLineNumber: "42",
    actions: [
      {
        actionExtensionID: "Xcode.BreakpointAction.DebuggerCommand",
        actionContent: { consoleCommand: "po self" },
      },
    ],
  },
});

// Serialize back to XML
const outputXml = breakpoints.build(list);

工作空间设置 API

分析并构建工作空间设置文件( E)WorkspaceSettings.xcsettings:

import * as settings from "@bacons/xcode/settings";
import fs from "fs";

// Parse settings file
const plist = fs.readFileSync(
  "/path/to/xcshareddata/WorkspaceSettings.xcsettings",
  "utf-8",
);
const config = settings.parse(plist);

console.log(config.BuildSystemType); // "Original" or "New"
console.log(config.PreviewsEnabled); // true/false

// Modify and save
config.PreviewsEnabled = true;
config.IDEWorkspaceSharedSettings_AutocreateContextsIfNeeded = false;

const outputPlist = settings.build(config);
fs.writeFileSync("/path/to/WorkspaceSettings.xcsettings", outputPlist);

Swift 软件包管理器支持

在您的 Xcode 工程中添加 Swift 包管理器依赖性, 并自动处理全线布线 .

添加远程软件包

import { XcodeProject } from "@bacons/xcode";

const project = XcodeProject.open("/path/to/project.pbxproj");
const rootProject = project.rootObject;

// Add a remote Swift package to the project
const packageRef = rootProject.addRemoteSwiftPackage({
  repositoryURL: "https://github.com/apple/swift-collections",
  requirement: {
    kind: "upToNextMajorVersion",
    minimumVersion: "1.0.0",
  },
});

// Add the package product to a target
const target = rootProject.getMainAppTarget("ios");
const productDep = target.addSwiftPackageProduct({
  productName: "Collections",
  package: packageRef,
});

// Save the project
fs.writeFileSync("/path/to/project.pbxproj", build(project.toJSON()));

添加本地软件包

// Add a local Swift package (e.g., from a monorepo)
const localPackage = rootProject.addLocalSwiftPackage({
  relativePath: "../Packages/MyFeature",
});

// Add the product to your target
target.addSwiftPackageProduct({
  productName: "MyFeature",
  package: localPackage,
});

何为连线

当你打电话 target.addSwiftPackageProduct(),以下自动处理:

  1. 创建 XCSwiftPackageProductDependency 并添加到目标 packageProductDependencies
  2. 创建 PBXBuildFile 与 productRef 说明依赖性
  3. 将构建文件添加到目标框架构建相

管理软件包依赖

// Get all package product dependencies for a target
const deps = target.getSwiftPackageProductDependencies();

// Find an existing package by URL or path
const existing = rootProject.getPackageReference(
  "https://github.com/apple/swift-collections"
);

// Remove a package product from a target (cleans up build file too)
target.removeSwiftPackageProduct(productDep);

版本要求

远程包支持各种版本的要求类型 :

// Up to next major version (e.g., 1.0.0 to 2.0.0)
{ kind: "upToNextMajorVersion", minimumVersion: "1.0.0" }

// Up to next minor version (e.g., 1.2.0 to 1.3.0)
{ kind: "upToNextMinorVersion", minimumVersion: "1.2.0" }

// Exact version
{ kind: "exactVersion", version: "1.2.3" }

// Version range
{ kind: "versionRange", minimumVersion: "1.0.0", maximumVersion: "2.0.0" }

// Branch
{ kind: "branch", branch: "main" }

// Revision (commit hash)
{ kind: "revision", revision: "abc123def456" }

解决方案

  • 使用比遗产更快的手取最优化的单通解析器 xcode 软件包(使用PEG.js).
  • 此工程支持数据类型 <xx xx xx>。 。 。 .
  • 更好的带有行和列编号的错误消息 .
  • 由于我们遵循《公约》,因此执行工作更加稳定 最佳猜测 pbxproj 光谱。 。 。 .
  • 弦分析是最狡猾的部分。 此软件包使用实际的端口 CFoldStylePlist 解析器 该方法是环境署在规模上首先使用的方法 可可扑克队 (原始内容贷记到 萨曼莎·马歇尔) (中文(简体) ).

怎么样

解析非常简单(简单是关键).

pbxproj 是一个"旧式的 plist"(或ASCII Plist),这意味着它应该能够作为JSON或XML等任何其他静态配置文件类型来表示.

我们支持下列类型: Object, (中文(简体) ), Array, (中文(简体) ), Data, (中文(简体) ), String值得注意的是,我们避免处理 Integer, (中文(简体) ), Double,布尔,因为它们在格式上似乎不存在.

开始

  • 读取.
  • 写作.
  • 逃出脚本和页眉搜索路径.
  • 生成 UUID .
  • 参考型API.
  • 构建设置解析 .
  • xcscheme 支持 .
  • 基准bun run bench) (中文(简体) ).
  • x工作空间支持.
  • XC 图形 分析 : .xcconfig 文件解析 #include 支持和构建设置平整.
  • XC 共享数据: 共享项目数据目录(计划,断点,工作空间设置).
  • XC 计划管理: 计划订购、能见度和管理清单.
  • 工作空间安排: (中文(简体) )xcshareddata/WorkspaceSettings.xcsettings)衍生出的数据位置,构建系统版本,自动创建方案设置.
  • XCBreakpoint 列表: (中文(简体) )xcshareddata/xcdebugger/Breakpoints_v2.xcbkptlist) 共享调试断点(文件,符号,例外断点).
  • 从零开始创建强大的 xcode 工程 .
  • 技术.
  • 从其他工具导入.
  • XCUserData 数据: (中文(简体) )xcuserdata/<user>.xcuserdatad/) 用户计划,断点,UI状态.
  • IDE 工作空间检查: (中文(简体) )xcshareddata/IDEWorkspaceChecks.plist) 工作空间检查状态存储(例如32位去普率警告).
  • Swift 软件包管理器: 以自动接线方式添加远程和本地的SPM依赖性.

文档

医生在工作。 现在,你可以提到 类型 和估计数 pbxproj 光谱。 。 。 .

API在未来会有所改变,因为现在我们有两种方法:

import {
  /** Given a stringified `pbxproj`, return a JSON representation of the object. */
  parse,
  /** Given a JSON representation of a `pbxproj`, return a `.pbxproj` string that can be parsed by Xcode. */
  build,
} from "@bacons/xcode/json";

import fs from "fs";
import path from "path";

const pbxproj = parse(fs.readFileSync("/path/to/project.pbxproj"));

const pbxprojString = build(pbxproj);
  • PBXVariantGroup 是一个本地化 PBXGroup。 。 。 .

文件路径解析

文件将有一个属性 sourceTree 它说明文件路径应如何解决.

  • BUILT_PRODUCTS_DIR:路径与已建产品目录相对.
  • DEVELOPER_DIR:路径相对开发者目录.
  • SOURCE_ROOT:路径与项目相对.
  • SDKROOT:路径相对SDK目录.
  • <group>:路径与组相对.
  • <absolute>: source是一条绝对路径.

例如,一个文件对象,例如:

{
  "isa": "PBXFileReference",
  "name": "AppDelegate.m",
  "path": "multitarget/AppDelegate.m",
  "sourceTree": "<group>"
}

指出 path “多目标/AppDelegate.m”相对 sourceTree ""("".". 我们需要检查包含 PBXGroup是因为 path (仅在组与文件系统中的目录链接时定义). 群体可以生活在其他群体中,因此这一过程是递归性的.

版本

某些值 粗略地映射到对方。 比如顶级 objectVersion (表示用于顶层对象的版本) objects 词典、地图 rootObject - > (中文) PBXProject是因为 compatibilityVersion 绳子。 以下是最新地图(2022年5月):

PBXProject.compatibilityVersionXcodeProject.objectVersion
'Xcode 16.0'70
'Xcode 15.0'60
'Xcode 14.0'56
'Xcode 13.0'55
'Xcode 12.0'54
'Xcode 11.4'53
'Xcode 11.0'52
'Xcode 10.0'51
'Xcode 9.3'50
'Xcode 8.0'48
'Xcode 6.3'47
'Xcode 3.2'46
'Xcode 3.1'45

归属

版本与发布记录

@bacons/xcode 共发布 33 个版本,首次发布于 2023/06/06;过去 12 个月发布了 6 个版本。

版本发布日期距今
1.0.0-alpha.33latest2026/03/038 个月前
1.0.0-alpha.322026/03/018 个月前
1.0.0-alpha.312026/02/288 个月前
1.0.0-alpha.302026/02/288 个月前
1.0.0-alpha.292026/01/139 个月前
1.0.0-alpha.282025/12/1010 个月前

关于 @bacons/xcode 的常见问题

@bacons/xcode 是什么?

pbxproj 解析器

如何安装 @bacons/xcode?

在项目目录运行 npm install @bacons/xcode,或使用 pnpm add / yarn add / bun add。

@bacons/xcode 支持 TypeScript 吗?

支持。包内自带 TypeScript 类型声明(package.json 声明了 types 入口),安装后即可获得类型提示,无需再安装 @types 包。

@bacons/xcode 支持 ESM 还是 CommonJS?

以 CommonJS 形式发布,可以直接 require();在 ES Module 项目中也可以用 import 引入(Node.js 会把 module.exports 作为默认导出)。

@bacons/xcode 可以商用吗?

@bacons/xcode 使用 MIT 许可。宽松许可:允许商业使用、修改和再分发,通常只需在分发时保留原版权与许可声明。以上为概括,不构成法律意见,请以许可原文为准。

@bacons/xcode 的下载量有多少?

根据 npm 官方下载统计,@bacons/xcode 在 2026/10/08 – 2026/11/06 这 30 天内被下载 3,397,657 次,日均约 113,255 次。下载量会把 CI 构建、镜像同步和作为其他包依赖的安装一并计入,适合横向比较热度,不能直接等同于使用人数。

@bacons/xcode 还在维护吗?

最新版本 1.0.0-alpha.33 发布于 2026/03/03(8 个月前);至今共发布 33 个版本,其中过去 12 个月发布了 6 个;首次发布于 2023/06/06。发布频率只是参考信号:功能稳定的工具可能很少需要更新,建议结合源码仓库的 issue 和提交记录判断。