@salla.sa/base

中文文档
3.0.21发布于 2026/11/02GPL-3.0TypeScriptESM + CJS

萨拉基

中文使用文档
文档目录16 节
  1. 概述
  2. 开始使用
  3. 安装
  4. 包括什么?
  5. 使用
  6. Confiruration
  7. 助手
  8. 存储
  9. 饼干
  10. 日志记录器
  11. 事件
  12. FormDataWrapper
  13. 支持
  14. 贡献
  15. 学分
  16. 许可证

Logo

Salla Core JS

用这个核心包启动你的Salla JS项目。它包含了构建JS项目所需的主要元素。最重要的是,它基于事件驱动架构。
浏览我们的博客»

报告错误 · 请求功能 . < /萨拉开发者> . 官方文档

目录表
  1. 概述
  2. 开始使用
  3. 使用
  4. 支持
  5. 贡献
  6. 学分
  7. 许可证

概述

Salla Core JS 包基于事件驱动架构,这是一种以表示“事件”的数据为中心的现代设计方法(例如,产品已添加到购物车中)。在事件驱动编程中,事件是单个或多个操作的结果。订阅者可以监听该事件,并在它被发射器释放后采取行动。

开始使用

Salla Core JS 使用 EventEmitter2的实现 EventEmitter 在Node.js中找到的模块。它不仅在基准测试中优于EventEmitter并且与浏览器兼容,而且还为EventEmitter接口添加了一系列新的非破坏性功能。

安装

Salla Core JS 可以从 npm 使用如下命令:

npm install @salla.sa/base --save
yarn add @salla.sa/base

包括什么?

中的顶级文件的快速查看 Salla Core JS 项目:

.
├── src / helpers
├── src / config.d.ts
├── src / cookie.ts
├── src / event.js
├── src / index.ts
├── src / logger.ts
└── src / storage.js

使用

import Salla from "@salla.sa/base"

安装后,开发人员将可以使用以下工具:

Confiruration

当JS Core项目首次加载时,初始化过程用于获取必要的配置设置。开发人员有能力配置项目以满足他的需求。

助手

JS Core项目打包了各种有用的函数,这些函数可以在项目中直接访问和使用。

存储

开发人员可以使用本地存储在浏览器中保存和检索数据。本地存储中的数据没有截止日期。这意味着即使选项卡或浏览器窗口关闭,数据也会保留。此外,数据仅保存在本地。

饼干

JS Core项目使创建、检索和修改cookie变得很容易。可以限制名称、值和长度。

日志记录器

JS Core项目包括一个日志工具,它可以帮助跟踪执行流程,并确定为什么某些事情会在JS应用程序中发生。

事件

事件可以通过发射器的‘emit()’方法触发。此方法使用开发人员提供的数据来推送事件。

例如,开发人员可以根据用户验证的登录创建事件。简单, emit() 方法可以使用参数列表调用。这些参数说明了事件的动作和传递的数据,如下所示:

// via event name
Salla.event.emit("auth::verified",  {success:  true},  'email')

聆听事件

在创建事件及其数据列表之后,下一步是为该事件实现一个适当的侦听器。在 萨拉JS事件,这可以通过两种方法实现:

  • 直接使用事件名称和结果以及匿名函数,根据事件结果执行所需的操作。
// via event name
Salla.event.on('auth::verified',(response, authType)  =>  {
// lets do anything when the event emit
console.log('The customer has been verifed');
console.log(response, authType)
});
  • 添加一个 one 事件的时间监听器以及基于事件结果执行所需操作的匿名函数。
// Adds a one time listener for the event.
Salla.event.once('auth::verified',(response, authType)  =>  {
// The listener is invoked only the first time
// the event is fired, after which it is removed.
console.log('The customer has been verifed');
console.log(response, authType)
})

(回到顶部)

FormDataWrapper

FormDataWrapper提供了一个用于处理常规对象和FormData的统一接口,使得以一致的方式处理文件上传和表单数据变得更加容易。

用法示例

示例1:使用FormData处理基本文件
const formData = new FormData();
const wrapped = createWrapper(formData);

// Adding a single file
const file1 = new File(['Hello World'], 'hello.txt', { type: 'text/plain' });
wrapped.document = file1;  // Works via proxy
// OR
wrapped.setFile('document', file1);  // Explicit file method

// Getting the file back
const retrievedFile = wrapped.document;  // Returns File object
console.log(retrievedFile.name);  // 'hello.txt'
console.log(retrievedFile.size);  // 11 (bytes)
例2:具有相同密钥的多个文件
const file2 = new File(['Second file'], 'second.txt', { type: 'text/plain' });
const file3 = new File(['Third file'], 'third.txt', { type: 'text/plain' });

// Setting multiple files at once (replaces existing)
wrapped.attachments = [file2, file3];

// Or append files one by one
wrapped.append('photos', new File(['Photo 1'], 'photo1.jpg', { type: 'image/jpeg' }));
wrapped.append('photos', new File(['Photo 2'], 'photo2.jpg', { type: 'image/jpeg' }));

// Get all files for a key
const allPhotos = wrapped.getFiles('photos');
console.log(allPhotos.length);  // 2
console.log(allPhotos.map(f => f.name));  // ['photo1.jpg', 'photo2.jpg']
示例3:混合内容(文件和常规数据)
wrapped.username = 'john_doe';
wrapped.age = 30;
wrapped.avatar = new File(['avatar data'], 'avatar.png', { type: 'image/png' });

// Check if property is a file
console.log(wrapped.isFile('avatar'));  // true
console.log(wrapped.isFile('username'));  // false

// Get file info without reading content
const fileInfo = wrapped.getFileInfo('avatar');
console.log(fileInfo);  // [{ name: 'avatar.png', size: 11, type: 'image/png' }]
例4:使用object或FormData
function processUserData(data: Record<string, any> | FormData) {
  const wrapped = createWrapper(data);
  
  // These operations work for both types
  wrapped.name = 'Jane Doe';
  wrapped.email = '[email protected]';
  
  // Handle file upload (works differently based on type)
  const profilePic = new File(['pic'], 'profile.jpg', { type: 'image/jpeg' });
  wrapped.profilePicture = profilePic;
  
  // Check if we have a file
  if (wrapped.isFile('profilePicture')) {
    const file = wrapped.getFile('profilePicture');
    console.log(`Uploaded file: ${file?.name}, Size: ${file?.size} bytes`);
  }
  
  // Convert to object for processing
  const obj = wrapped.toObject();
  console.log('Data keys:', Object.keys(obj));
  
  return wrapped;
}
示例5:真实的表单提交场景
function handleFormSubmit(formElement: HTMLFormElement) {
  const formData = new FormData(formElement);
  const wrapped = createWrapper(formData);
  
  // Add timestamp
  wrapped.submittedAt = Date.now();
  
  // Validate files
  const uploadedFiles = wrapped.getFiles('documents');
  const maxSize = 5 * 1024 * 1024; // 5MB
  
  for (const file of uploadedFiles) {
    if (file.size > maxSize) {
      console.error(`File ${file.name} exceeds maximum size`);
      wrapped.delete('documents');
      wrapped.error = 'File too large';
    }
  }
  
  // Add computed property
  wrapped.fileCount = uploadedFiles.length;
  
  // Get the modified FormData for submission
  const finalFormData = wrapped.getRawData() as FormData;
  
  // Submit with fetch
  fetch('/api/submit', {
    method: 'POST',
    body: finalFormData
  });
}
示例6:类型安全的文件处理
interface UserProfile {
  name: string;
  email: string;
  avatar?: File;
  documents?: File[];
}

function createUserProfile(data: UserProfile | FormData) {
  const wrapped = createWrapper(data);
  
  // Type-safe access
  const name: string = wrapped.name;
  const avatar: File | null = wrapped.getFile('avatar');
  const docs: File[] = wrapped.getFiles('documents');
  
  // Process files
  if (avatar) {
    console.log(`Avatar: ${avatar.name} (${avatar.type})`);
  }
  
  docs.forEach((doc, index) => {
    console.log(`Document ${index + 1}: ${doc.name}`);
  });
  
  return wrapped.toObject();
}

(回到顶部)

支持

团队总是在这里帮助你。碰巧遇到了问题?想要报告bug?你可以在Github上提交一个 问题跟踪器。如果您还有任何问题,请通过电子邮件与我们联系 电报机器人 或加入全球开发者社区 电报.

(回到顶部)

贡献

贡献使开源社区成为一个学习、启发和创造的神奇场所。 你做的任何贡献都是 极大的赞赏.

如果你有一个更好的建议,请fork repo并创建一个pull request。 你也可以简单地打开一个带有“增强”标签的问题。别忘了给这个项目打个星!再次感谢!

  1. 分岔项目
  2. 创建特性分支(git checkout -b feature/AmazingFeature)
  3. 提交更改(git commit -m 'Add some AmazingFeature')
  4. 推至分行(git push origin feature/AmazingFeature)
  5. 打开拉取请求

(回到顶部)

学分

(回到顶部)

许可证

麻省理工学院许可证(MIT)。请参阅 许可文件 了解更多信息。

(回到顶部)

版本与发布记录

@salla.sa/base 共发布 868 个版本,首次发布于 2022/09/11;过去 12 个月发布了 325 个版本。

版本发布日期距今
3.0.21latest2026/11/021 天前
3.0.202026/11/021 天前
3.0.192026/11/021 天前
3.0.182026/11/012 天前
3.0.172026/10/295 天前
3.0.162026/10/285 天前

其他发布通道:canary → 2.8.1-alpha.0,beta → 3.0.0-beta.1。

关于 @salla.sa/base 的常见问题

@salla.sa/base 是什么?

萨拉基

如何安装 @salla.sa/base?

在项目目录运行 npm install @salla.sa/base,或使用 pnpm add / yarn add / bun add。

@salla.sa/base 支持 TypeScript 吗?

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

@salla.sa/base 支持 ESM 还是 CommonJS?

同时提供 ES Module 与 CommonJS 入口,import 和 require() 都可以使用,打包工具会自动选择合适的版本。

@salla.sa/base 可以商用吗?

@salla.sa/base 使用 GPL-3.0 许可。强 Copyleft:分发包含该代码的软件时,整个作品需以 GPL-3.0 兼容许可开源,并附带专利与反锁定条款。仅内部使用不触发此义务。以上为概括,不构成法律意见,请以许可原文为准。

@salla.sa/base 还在维护吗?

最新版本 3.0.21 发布于 2026/11/02(1 天前);至今共发布 868 个版本,其中过去 12 个月发布了 325 个;首次发布于 2022/09/11。发布频率只是参考信号:功能稳定的工具可能很少需要更新,建议结合源码仓库的 issue 和提交记录判断。