普通视图

发现新文章,点击刷新页面。
今天 — 2026年1月22日首页

深入浅出 TinyEditor 富文本编辑器系列5:开发环境配置

2026年1月22日 14:16

你好,我是 Kagol,个人公众号:前端开源星球

TinyEditor 是一个基于 Quill 2.0 的富文本编辑器,在 Quill 基础上扩展了丰富的模块和格式,功能强大、开箱即用。

本文是《深入浅出 TinyEditor 富文本编辑器系列》文章的第5篇,主要介绍 TinyEditor 的开发环境配置。

搭建适当的开发环境对于为 TinyEditor 做贡献至关重要。本文将引导你完成整个流程,从克隆代码仓库到运行开发服务器。

前置条件

开始之前,请确保已安装以下工具:

  • Node.js:版本 18 或更高
  • pnpm:版本 9.13.0(项目的包管理器)
  • Git:用于版本控制

必须使用 pnpm,因为本项目使用 pnpm workspaces 进行 monorepo 管理。其他包管理器可能无法正常工作。

项目架构概述

TinyEditor 采用包含多个包的 monorepo 结构:

快速设置流程

设置过程可以可视化为一个简化的工作流:

分步设置

1. 克隆代码仓库

git clone git@github.com:opentiny/tiny-editor.git
cd tiny-editor

2. 安装依赖

项目使用 pnpm workspaces 管理多个包。使用以下命令安装所有依赖:

pnpm i

这将为 monorepo 中的所有包安装依赖,包括:

  • 核心编辑器库
  • 文档站点
  • 示例项目
  • 协作编辑后端

3. 启动开发服务器

对于一般开发,使用主要的开发命令:

pnpm dev

这将在 http://localhost:5173/tiny-editor/ 启动文档开发服务器。

开发工作流

核心库开发

要开发核心 fluent-editor 库:

pnpm watch

此命令以监听模式构建库,当源文件更改时自动重新构建。

文档开发

要开发文档:

# 文档开发服务器
pnpm -F docs dev

文档站点使用 VitePress,包含交互式演示和示例。

示例项目开发

要开发示例项目:

# 启动示例开发服务器
pnpm dev:projects

这将运行展示 TinyEditor 各种功能的示例项目。

协作后端开发

对于协作编辑功能:

# 启动协作后端
pnpm -F collaborative-editing-backend dev

这将为实时协作编辑启动 WebSocket 服务器。

包结构

Package 用途 开发命令
fluent-editor 核心编辑器库 pnpm watch
docs 文档站点 pnpm -F docs dev
projects 示例项目 pnpm dev:projects
collaborative-editing-backend 实时协作服务器 pnpm -F collaborative-editing-backend dev

构建命令

库构建

# 构建库用于发布
pnpm build:lib

这将构建库,同时输出 ES modules 和 CommonJS 格式。

文档构建

# 构建文档用于生产环境
pnpm build

项目构建

# 构建示例项目
pnpm build:projects

测试

项目使用 Jest 进行单元测试,使用 Playwright 进行端到端测试:

# 运行单元测试
pnpm test 
# 运行 E2E 测试
pnpm -F docs test 
# 安装 E2E 测试的浏览器依赖
pnpm install:browser

代码质量

项目使用 ESLint 配合 Antfu 配置来保证代码质量:

# 检查所有文件
pnpm lint 
# 修复检查问题
pnpm lint:fix

ESLint 配置支持 TypeScript、Vue,并强制执行一致的代码风格。

Git 钩子

项目使用 pre-commit 钩子来确保代码质量:

  • Pre-commit:运行 lint-staged 修复检查问题
  • Commit-msg:使用 verifyCommit.js 验证提交信息

开发技巧

开发核心库时,使用 pnpm watch 自动重新构建更改。库会以 ES modules 和 CommonJS 两种格式输出到 dist/ 目录。

Workspace 依赖

包使用 workspace 依赖(workspace:^)相互引用,确保在开发期间始终使用最新的本地版本。

补丁管理

项目使用 pnpm patches 修改 Quill 依赖。补丁文件位于 patches/quill@2.0.3.patch

开发环境为你提供了为 TinyEditor 做贡献所需的一切,无论是修复错误、添加功能还是改进文档。

联系我们

GitHub:github.com/opentiny/ti…(欢迎 Star ⭐)

官网:opentiny.github.io/tiny-editor

个人博客:kagol.github.io/blogs/

小助手微信:opentiny-official

公众号:OpenTiny

昨天 — 2026年1月21日首页

深入浅出 TinyEditor 富文本编辑器系列4:基础使用示例

2026年1月21日 14:52

你好,我是 Kagol,个人公众号:前端开源星球

TinyEditor 是一个基于 Quill 2.0 的富文本编辑器,在 Quill 基础上扩展了丰富的模块和格式,功能强大、开箱即用。

本文是《深入浅出 TinyEditor 富文本编辑器系列》文章的第4篇,主要介绍 TinyEditor 的基础使用示例。

本文提供了 TinyEditor 入门的综合示例,涵盖了面向初学者开发者的基本实现模式和常见用例。

快速开始实现

初始化 TinyEditor 最基本的方法是通过容器元素和配置选项创建新实例:

import FluentEditor from '@opentiny/fluent-editor'
 
const editor = new FluentEditor('#editor', {
  theme: 'snow',
  modules: {
    toolbar: [
      ['bold', 'italic', 'underline'],
      ['link', 'blockquote'],
      [{ list: 'ordered' }, { list: 'bullet' }]
    ]
  }
})

核心架构概述

TinyEditor 扩展了 Quill.js,提供了增强的模块和功能。该架构采用模块化设计,每个功能都作为独立模块实现:

image.png

基本配置示例

基本文本编辑器设置

创建带有基本格式化工具的简单文本编辑器:

const basicEditor = new FluentEditor('#editor', {
  theme: 'snow',
  modules: {
    toolbar: [
      ['undo', 'redo'],
      ['bold', 'italic', 'strike', 'underline'],
      [{ script: 'super' }, { script: 'sub' }],
      [{ color: [] }, { background: [] }],
      [{ list: 'ordered' }, { list: 'bullet' }],
      ['link', 'blockquote', 'code-block']
    ]
  }
})

带表格的高级编辑器

对于需要表格功能的更复杂文档:

import { generateTableUp } from '@opentiny/fluent-editor'
import { defaultCustomSelect,TableMenuSelect, TableSelection, TableUp } from 'quill-table-up'
 
FluentEditor.register({ 'modules/table-up': generateTableUp(TableUp) }, true)
 
const advancedEditor = new FluentEditor('#editor', {
  theme: 'snow',
  modules: {
    toolbar: [
      ['undo', 'redo', 'format-painter', 'clean'],
      [
        { header: [false, 1, 2, 3, 4, 5, 6] },
        { size: ['12px', '14px', '16px', '18px', '24px', '32px'] },
        'bold', 'italic', 'strike', 'underline'
      ],
      [{ color: [] }, { background: [] }],
      [{ align: ['', 'center', 'right', 'justify'] }],
      [{ 'table-up': [] }],
      ['link', 'blockquote']
    ],
    'table-up': {
      customSelect: defaultCustomSelect,
      modules: [
        { module: TableSelection },
        { module: TableMenuSelect },
      ],
    },
  }
})

模块配置模式

协同编辑设置

通过 WebSocket provider 启用实时协作:

FluentEditor.register('modules/collaborative-editing', CollaborationModule, true)
 
const collaborativeEditor = new FluentEditor('#editor', {
  theme: 'snow',
  modules: {
      'collaborative-editing': {
        deps: {
          Y,
          Awareness,
          QuillBinding,
          QuillCursors,
          WebsocketProvider,
          IndexeddbPersistence,
        },
        provider: {
          type: 'websocket',
          options: {
            serverUrl: 'wss://ai.opentiny.design/tiny-editor/',
            roomName: ROOM_NAME,
          },
        },
        awareness: {
          state: {
            name: `userId:${Math.random().toString(36).substring(2, 15)}`,
            color: `rgb(${Math.floor(Math.random() * 255)},${Math.floor(Math.random() * 255)},${Math.floor(Math.random() * 255)})`,
          },
        },
        cursors: {
          template: `
              <span class="${CURSOR_CLASSES.SELECTION_CLASS}"></span>
              <span class="${CURSOR_CLASSES.CARET_CONTAINER_CLASS}">
                <span class="${CURSOR_CLASSES.CARET_CLASS}"></span>
              </span>
              <div class="${CURSOR_CLASSES.FLAG_CLASS}">
                <small class="${CURSOR_CLASSES.NAME_CLASS}"></small>
              </div>
          `,
          hideDelayMs: 500,
          hideSpeedMs: 300,
          transformOnTextChange: true,
        },
      },
  }
})

文件上传配置

配置带有自定义 MIME 类型限制的文件上传:

const editorWithUpload = new FluentEditor('#editor', {
  theme: 'snow',
  modules: {
    toolbar: [
      ['bold', 'italic'],
      ['image', 'video', 'link']
    ],
    'uploader': {
      mimetypes: [
        'image/jpeg',
        'image/png',
        'image/gif',
        'application/pdf'
      ],
      handler(range: Range, files: File[]) {
        return files.map((_, i) => i % 2 === 0 ? false : 'https://developer.mozilla.org/static/media/chrome.5e791c51c323fbb93c31.svg')
      },
      fail(file: File, range: Range) {
        this.quill.updateContents(new Delta().retain(range.index).delete(1).insert({ image: 'https://developer.mozilla.org/static/media/edge.741dffaf92fcae238b84.svg' }))
      },
    },
  }
})

常见使用场景

内容初始化

创建编辑器时设置初始内容:

const initialContent = `
<h1>Document Title</h1>
<p>This is a <strong>sample</strong> document with <em>formatted</em> text.</p>
<ul>
  <li>First item</li>
  <li>Second item</li>
</ul>
<blockquote>Important quote here</blockquote>
`
 
const editor = new FluentEditor('#editor', {
  theme: 'snow',
  modules: {
    toolbar: ['bold', 'italic', 'blockquote']
  }
})
 
// 在初始化后设置内容
editor.clipboard.dangerouslyPasteHTML(0, initialContent)

事件处理

监听编辑器事件以实现自定义功能:

const editor = new FluentEditor('#editor', {
  theme: 'snow'
})
 
// 监听文本变化
editor.on('text-change', (delta, oldDelta, source) => {
  console.log('Text changed:', delta)
})
 
// 监听选择变化
editor.on('selection-change', (range, oldRange, source) => {
  if (range) {
    console.log('User selected text:', range)
  } else {
    console.log('User lost focus')
  }
})

样式与主题

自定义主题应用

使用 snow 主题应用自定义样式:

const styledEditor = new FluentEditor('#editor', {
  theme: 'snow',
  modules: {
    toolbar: [
      [{ header: [1, 2, 3, false] }],
      ['bold', 'italic', 'underline'],
      [{ color: [] }, { background: [] }]
    ]
  },
  placeholder: 'Start typing your document...'
})

国际化设置

配置多语言支持:

const i18nEditor = new FluentEditor('#editor', {
  theme: 'snow',
  modules: {
    'i18n': {
      lang: 'zh-CN',
      fallback: 'en-US'
    },
    toolbar: ['bold', 'italic', 'link']
  }
})
 
// 动态切换语言
editor.getModule('i18n').setLanguage('en-US')

集成示例

Vue.js 集成

<template>
  <div>
    <div ref="editorRef" class="editor-container"></div>
  </div>
</template>
 
<script setup>
import { ref, onMounted } from 'vue'
import FluentEditor from '@opentiny/fluent-editor'
 
const editorRef = ref()
let editor
 
onMounted(() => {
  editor = new FluentEditor(editorRef.value, {
    theme: 'snow',
    modules: {
      toolbar: ['bold', 'italic', 'link']
    }
  })
})
</script>

React 集成

import { useEffect, useRef } from 'react'
import FluentEditor from '@opentiny/fluent-editor'
 
function EditorComponent() {
  const editorRef = useRef()
  const editorInstanceRef = useRef()
 
  useEffect(() => {
    editorInstanceRef.current = new FluentEditor(editorRef.current, {
      theme: 'snow',
      modules: {
        toolbar: ['bold', 'italic', 'link']
      }
    })
 
    return () => {
      editorInstanceRef.current = null
    }
  }, [])
 
  return <div ref={editorRef} className="editor-container" />
}

最佳实践

  1. 始终指定主题 - 'snow' 主题提供默认 UI
  2. 配置工具栏模块 - 定义用户可用的工具
  3. 处理内容初始化 - 在编辑器创建后设置初始内容
  4. 实现事件监听器 - 响应用户交互和内容变化
  5. 使用适当的清理 - 卸载组件时销毁编辑器实例

这些示例为使用 TinyEditor 构建复杂的富文本应用程序提供了基础。从基本设置开始,根据需要逐步添加更复杂的功能。

联系我们

GitHub:github.com/opentiny/ti…(欢迎 Star ⭐)

官网:opentiny.github.io/tiny-editor

个人博客:kagol.github.io/blogs/

小助手微信:opentiny-official

公众号:OpenTiny

昨天以前首页

我的2025:只靠爱发电的开源能走多远?

2026年1月19日 17:00

前言

你是否也在想:纯粹的热情能否支撑一个长期可维护的开源项目?内容创作、维护开源项目、上架应用,哪一项最耗时却最重要?把兴趣变成产品,这条路能走多远?带着这些疑问,我开始了我2025年的复盘旅程。

2025年,我的重点就是维护我的开源项目,因为它,我的个人业余时间几乎就没有了,面对朋友的质疑,单靠爱发电,没有盈利,是否能长期继续坚持下去?

2025 年,我把写作、开源、鸿蒙应用上线当作了全年的主线,我的目的是把技术沉淀变成能被大家直接使用的东西:更好的文档、更实用的组件、更易上手的示例,以及一款沉浸式演示应用:uViewPro(跨平台 UI 组件库)

回想这一年过得忙忙碌碌,从年初立下的 flag 到年底的收获,每一步都走得踏实(很累)。写作上我在三个平台积累了大量内容,开源项目 uView Pro 从零到几百 Star,开源鸿蒙应用也顺利上架。

回头看看,这一年不仅学习到了很多东西,也认识到了很多朋友,这波不亏!

希望 2026 年能继续这个节奏,把更多想法变成现实。

一. 开篇:这一年,很忙碌

今年总结下来,我主要做了三件事,可以总结为如下:

  1. 持续写技术文章:在公众号、掘金、CSDN这些平台上输出内容,分享开发经验和踩坑记录。
  2. 维护开源组件库:把 uView Pro 这个项目从零做到现在的规模,让更多开发者用起来顺手。
  3. 首款鸿蒙应用上线:把演示应用适配鸿蒙系统并成功上架,验证跨平台开发的效果。

这三件事说起来简单,但每件都耗费了我大量的时间和精力。写作要保证质量和频率,开源项目不仅要修复、迭代、上新功能,还要处理各种 issuePR,鸿蒙应用上架还要跟审核机制斗智斗勇(审核驳回近 10 次,我真是打不死的小强)。

但正是这些挑战,让我这一年过得非常非常充实。

1. 为什么是这三件事?

其实这跟我的工作经历有关,我从 2015 年开始接触前端和移动端,从最基础的 HTML、CSS 开始了解,后来慢慢接触到 Vue.js,Angular.js,React.js 三大框架。工作的这几年,陆陆续续做过电商网站、后台管理系统、原生应用、微信小程序等等,每个项目都让我长了不少见识,也踩了不少坑。

后来,uni-app 生态越来越火,我身边很多朋友都在用它开发项目。我们公司内部也有考量,后来经过最终选型,选定了 uView UI 为主要UI框架,从此 uni-app + uView UI 成为了我开发移动端应用的合作搭子。

2. 忙碌背后的收获

说到底,2025 年对我来说,就是一个"把想法变成现实"的过程。从抽象的概念,到具体的代码,到最终的产品,每一步都让我更踏实,也更期待2026年的到来。

这一年我不仅思想上变得通达了,思维方式也变了很多。以前总觉得一个人埋头苦干就行了,现在明白了分享和交流的重要性。

技术这条路,本来就该一起走。

二. 内容创作:公众号、掘金、CSDN

写作这事,说起来简单,但真要坚持下来其实挺不容易的,我从 2016 年开始写技术文章,期间是断断续续的在维护,各种原因没能一直坚持下去。

最早写文章的时候,纯粹是为了记录自己踩的坑。记得第一次写技术博客,手抖了半天,才憋出几百字,发出去后还忐忑不安,生怕被同行笑话。没想到居然有人点赞,有时还被评论说帮到了他。

慢慢地,我发现写作不仅能帮到别人,还能让自己思路更清晰,很多时候,写文章的过程就是梳理知识的过程。你以为自己懂了,但真要写出来,才发现还有不少模糊的地方。

直到 2023 年,才是我写作开始认真的一年,不仅文章数量上去了,质量也比以前好很多。我主要在三个平台发文:掘金、公众号和 CSDN,每个平台都有自己的特色和受众群体。

1. 掘金:我的"主战场"

掘金是我最活跃的平台,从 2023 年开始就在上面写文章,到今年已经积累了 168 篇原创内容,总阅读量超过 81 万+,粉丝也有 1618 个。

截至目前,掘金的数据如下:

  • 文章数:168 篇
  • 阅读量:81万+
  • 关注数:1618

1.png

今年,我也特别重视掘金,那么多平台,我唯独感觉掘金的技术氛围最好,读者质量也高。掘金的用户大都喜欢学习新技术,也愿意分享自己的经验。

2025 年,我在掘金大概发了 25 篇原创文章,内容主要是围绕 uni-app、可视化地图、Vue3、鸿蒙开发这些主题。

2.png

不过掘金也不是没有缺点,有时候一篇非常用心的文章发出去后,算法推荐不太给力,阅读量上不去就挺郁闷的。有时候可能随便写一篇,阅读量却很可观,有些不理解。但总体来说,掘金还是我最舒服的写作环境。

今年参加金石计划征文活动,连续三次获得优秀作者,今年(去年)的财富都是掘金给的,但是今年金石计划就举办了3期,所以比之去年相差很大:

15.png

2. 公众号:开始用心经营的阵地

公众号“前端梦工厂”,是我去年年底开始认真经营的。说实话,一开始我对公众号没抱太大期望,因为之前发的几篇文章,效果一般,阅读量惨不忍睹。有时候文章发出去,才几个阅读,几个点赞,心里还是挺失落的。

但是幸好没放弃,目前公众号写作算是也坚持下来了,虽然文章数量不多,但是质量都很高,最近官方给不断的加流量,越来越多的人关注了。

截至目前,公众号的数据如下:

  • 原创内容:63
  • 总用户数:1900+

3.png

4.png

3. CSDN:稳扎稳打的平台

CSDN 是我最早开始写博客的平台,从 2015 年就开始了。现在已经积累了 258 篇文章,阅读量 60万+,粉丝 9394 个。

虽然数据比其他平台耀眼,但感觉这里的用户粘性并不好,一篇文章的阅读量一般都在 1000+ 左右,但是却没有评论,为什么?目前 CSDN 的内容基本上大都同步于掘金和公众号,但也获得了优质创作者和博客专家称号。

截至目前,CSDN 的数据如下:

  • 文章数:258
  • 阅读量:60万+
  • 关注数:9394

5.png

后续的分享和写作也会以这3个平台为主,将会持续输出更多的文章。

4. 写作这行的酸甜苦辣

写了几年文章,我最大的感受是:坚持真的很重要。刚开始写作的时候,我特别羡慕那些大V,动不动就几万阅读。但后来发现,人家也是日积月累出来的,谁也不是刚开始写就成功。

当然,写作也有苦恼的时候。有时候卡文,写一晚上才憋出几百字;有时候写完发现没人看,心里挺失落的。但每当看到读者说"这篇文章帮到我了",所有的辛苦都值了。

2025 年,我的写作生涯达到了一个小高峰,不仅文章多了,质量也上去了。我相信,2026 年我会写得更好。

写作就像跑马拉松,不能急功近利。

三. 年度开源项目:uView Pro

官网:uviewpro.cn

说起 uView Pro,这绝对是我2025 年最投入的一个项目。从年初的构想到年底的成熟产品,这一路走得真是跌跌撞撞,但也收获满满。

开源让项目不断被验证,但也带来了沟通和维护的成本,自从 uView Pro 开源后,我的个人时间基本就没有了!虽然零零散散的有人赞助,但是目前与我的付出严重不成正比。

13.png

1. 从 uView 到 uView Pro 的华丽转身

因为在移动端开发领域,我一直在用 uni-app,而 UI 组件库一直用 uView UI 1.8.8,框架已经用顺手了,习惯了。

然而最大的问题是它是基于 Vue2 的,而我已经在新项目中全面拥抱 Vue3 了,uView UI 的官方仓库也停止了更新,并没有推出 Vue3 的版本。而也有个人推出的 uView 系的 Vue3 版本,但观其源码,仅是在 Vue2 的基础上做的兼容,并没有真正发挥 TypeScript 的效果,编码体验并不好。

于是我开始思考,能不能基于 uView 1.8.8 做一个 Vue3 版本的?想法一出,我就开始行动了。大概花了两个多月时间,把所有组件用 Vue3 + TypeScript 重写了一遍。这可不是简单的复制粘贴,我把每个组件的 API 都对齐了官方 API,目的是让原先的 Vue2 + uView 1.8.8 的项目可以无缝迁移。

终于在2025年8月4日,我把这个项目开源了,取名叫 uView Pro。说实话,开源的时候心里挺紧张的。但发布后收到的反馈超出了我的预期,很多开发者说这个版本用起来更舒服了。

开源已经5个多月,目前在平台上的数据如下:

Github:

6.png

star-history-2026119.png

Gitee:

7.png

Dcloud 插件市场:

8.png

2. 多端适配的艰难之路

uView Pro 最让我难做的就是多端适配。刚开始我只支持了H5、微信小程序,但后面陆续加了Android、iOS、鸿蒙、支付宝小程序、头条小程序等平台。现在已经实现了真正的"一套代码,多端运行"。

多端适配听起来简单,做起来真不容易。每个平台都有自己的特色,拿 provide/inject 来说,头条小程序并不支持这个 API,我就得想办法用其他方式实现类似的功能。

但这些困难都是值得的,现在 uView Pro 可以在 10 个平台上运行,开发者只需要写一套代码,就能覆盖绝大部分用户。

3. 主题系统和暗黑模式

uView Pro 的主题系统是我最得意的功能之一。传统的组件库,换个皮肤要改一堆 CSS 文件,但 uView Pro 只需要三分钟,就能生成一套全新的主题。

我研究了很多实现方案,最后在文档网站搞出了一个主题生成器。通过配置一些基础颜色,就能自动生成整套主题文件。

暗黑模式也是基于这个系统实现的。现在用户可以一键切换明暗主题,而且过渡效果超级丝滑。

多主题+浅色主题

首页-浅色主题.png

多主题+深色主题

首页-深色主题.png

4. 国际化支持

好多小伙伴反馈说,希望 uView Pro 能支持多语言。之前的 uView UI 官方并没有真正的支持国际化,只能通过一些 prop 传递来修改组件的文案,但这并不够灵活,而且还不能完全覆盖。

uView Pro 一直希望开发者用起来更方便、更顺手,所以早在几个月前,uView Pro 就已经开始了将所有组件 i18n 化的工作。

目前,很高兴地告诉大家:uView Pro全系组件现在都支持国际化了!有了这个功能,开发者可以更简单地让应用支持多种语言,让产品更容易走向全球市场。

image.png

5. 优势总结

目前 uView Pro 具有以下优势:

  • 🚀 彻底重构:基于 Vue3 语法和特性,源码级重构所有组件和工具,非兼容层方案。
  • ⚡ 高性能:充分利用 Vue3 响应式和组合式 API,组件性能和可维护性大幅提升。
  • 🖥️ 多端适配:支持 Android、iOS、微信小程序,持续兼容更多平台。
  • 🌍 国际化(i18n)支持:内置多语言切换,便于多语言项目快速集成与部署。
  • ✨ 易用性强:API 设计现代,文档详尽,开发体验优于传统兼容方案。
  • 🌐 生态完善:内置 80+ 高质量组件和丰富工具库,覆盖主流业务场景。
  • 🎨 多主题定制:通过主题生成工具三分钟实现多套主题定制。
  • 🌙 暗黑模式:支持一键暗黑模式。

四. 我的鸿蒙应用正式上架:在纯血鸿蒙系统上验证可行性

应用体验链接uviewpro.cn/zh/resource…

把组件库做成一款面向开发者的应用,这个想法其实很早就有了。我一直在想,开发者学习一个组件库的时候,最怕的就是"看了文档不知道长什么样,搭了工程又嫌麻烦"。如果能直接在手机上点一点,看看组件的效果,那该多好啊!

2025 年可以说是鸿蒙系统的元年,华为 Pura 80、Mate80 系列等新机都搭载了纯血 HarmonyOS 系统,之前的部分旗舰机型也可以升级到鸿蒙6.0,说明纯血鸿蒙系统已经趋于稳定,到了全面推广的时候

而华为官方还有开发者激励活动,这给了我一个绝佳的机会,去验证 uView Pro 在鸿蒙上的表现。

动画10.gif

1. 从想法到原型:应用的定位

应用的名字就叫"uViewPro(跨平台 UI 组件库)",目标很明确:做一款面向开发者的学习型应用。应用包含三大功能:

  1. 组件演示:把uView Pro的所有组件都做成可交互的demo
  2. 模板示例:提供一些常用的页面模板和布局示例
  3. 学习工具:加入一些代码片段复制、API 查询等实用功能
  4. 成就系统:加入游戏化的学习方式,让学习组件库变得更加有趣和高效。

我希望用户下载了应用后,不需要看文档就能大概了解 uView Pro 能做什么,怎么用。这样就能降低学习成本,让更多开发者愿意试试。

预览图.png

2. 上架历程:审核的那些事

鸿蒙应用上架可比其他平台上线严格多了,可以说比 iOS 审核都要严格的多,我反复修改提交了 10 次才最终审核通过。

第一次提交申请后被拒的原因是:

  1. 功能交互简单,影响用户的总体体验
  2. 横竖屏布局未适配问题,不符合鸿蒙应用UX设计规范。
  3. 未正常适配设备深色模式,不符合鸿蒙应用UX设计规范。

11.png

第2,3个问题都好解决,第一个为主观问题,不好解决!果真,后面所有被拒绝的原因都为第一个,不管应用内容如何丰富,都被拒绝!

12.png

我一度想要放弃!最终通过新增应用功能,申诉,提交工单,提交完整的应用说明和演示视频,最终通过。

应用引导页.png

附一张完整的审核拒绝的截图:

10.png

3. 验证与收获:鸿蒙生态的潜力

通过这个应用,我验证了很多东西:

  1. 组件的真实表现:在真机上测试,发现了一些在模拟器上看不出来的问题
  2. 用户的真实需求:通过用户反馈,我知道了开发者最关心哪些功能
  3. 鸿蒙开发的门槛:虽然比想象中复杂,但生态已经很成熟了

最让我感动的是,有个开发者私信我说:"谢谢你的应用,我通过它学会了 uView Pro,现在已经用在项目里了。"这种直接的反馈让我觉得所有的努力都值了。

2025 年鸿蒙应用的上架,不仅验证了 uView Pro 的技术实力,也让我对鸿蒙生态有了更深的认识。相信随着华为的投入,鸿蒙也会成为 uni-app 开发的重要平台之一。

4. 如何体验?

📱 去鸿蒙应用商店体验

应用名称:  uViewPro(跨平台 UI 组件库)

应用市场:  打开华为应用市场(AppGallery) 搜索 uViewPro 或 跨平台UI组件库

或访问链接uviewpro.cn/zh/resource…

注意:此应用仅在 HarmonyOS 5.0 及以上版本 设备的应用市场中提供。

9.png

五. 比赛经历:高德空间智能开发者大赛

2025 年底的比赛经历让我印象深刻,特别是高德空间智能开发者大赛,从报名到决赛,整个过程都让我学到了很多。

大赛是从去年年底开始的,主题是"空间智能应用创新"。由于时间原因,我做了一个基于位置+轨迹+日记创作的轻量应用,可以帮助用户记录每一段路线、留存沿途灵感,并以图文海报形式分享,并兼容鸿蒙系统。

作品提交后,没想到获得了优胜奖,得到了官方邀请,于2026年1月9日参加了决赛现场,在现场,见到了很多优秀的开发者,大家分享了自己的作品和技术思路。虽然比赛时间很短暂,但它让我在 2026 年的开头就有了满满的动力。

所以,技术这条路,不仅要埋头苦干,还要抬头看路。参加比赛就是一种很好的方式,既能锻炼技能,又能认识同行。

合影.png

六. 2026 年计划

2025 年过得特别匆忙,但 2026 年我想让自己更加自由高效一点。基于这一年的经验,我对明年有了更清晰的规划。主要是三个方向,但每个方向都有更具体的目标。

  1. 持续创作,打造个人品牌:在掘金、公众号、CSDN继续发布高质量文章。计划每个月至少发2篇原创文章,内容不仅包括技术教程,还会分享更多行业洞察和个人成长经历。希望能把"前端梦工厂"公众号做成一个有影响力的技术媒体,粉丝数量早日突破 5000

  2. 继续打磨开源框架uView Pro:这是重中之重。基于大多数用户的诉求,计划增加更多实用组件。多端适配要更完善,特别关注鸿蒙和 iOS 端的体验。国际化支持也要加强,争取支持更多语言。

  3. 打造 uView Pro X,支持uni-app x:计划基于 uView Pro 打造一个新项目,支持最新的技术栈。不仅要兼容现有的功能,充分发挥 uni-app x 的优势,这将会是一个大项目,需要投入不少时间和精力。

希望 2026 年能找到工作和生活的更好平衡,既能高效工作,又能享受生活。

七. 感谢

感谢每一位朋友在 2025 年的支持,感谢开源贡献者和用户,感谢每个提出建议的人,尤其感谢 uView Pro 的赞助者,让我有了不断维护的动力!

PinMe:零成本三秒发布你的网站

作者 修己xj
2026年1月17日 23:39

你是否渴望将自己的博客网站部署上线,却因高昂的服务器和域名费用、繁琐的配置流程而望而却步?你是否希望发布一个活动页面或图书介绍网站,却不愿购买服务器,也不想经历复杂的部署步骤?

最近在浏览 GitHub 时,我发现了一个很棒的项目——PinMe。 PinMe 的目标,就是把发布这件事简化成一句话:

「本地有一份静态资源,上传到网站发上去或者给我一个命令,我帮你发上去。」

不仅如此,这套发布方案还天生具备 “内容可验证” 与 “抗篡改” 的特点。 今天就来给大家推荐这个项目,相信它会让你的发布之路变得轻松又可靠!🚀

🔍什么是PinMe?

PinMe 是一款零配置的前端部署工具。无需服务器、无需账号、无需设置。

无论是构建静态站点、使用 AI 生成页面,还是导出前端项目 — 只需一条命令或者拖动文件夹上传即可即时部署。

PinMe 将您的网站发布为可验证的内容,相比传统托管,能更有效地防止静默篡改和意外损坏。

您无需管理服务器、区域或运行时间。PinMe 为您处理可用性和持久性。

github地址: github.com/glitternetw…

官网地址:pinme.eth.limo/

该项目在github 有2.6k ⭐️star

✒️ 核心特性

🚀 极简部署

  • 网页部署:进入网站,上传文件jar
  • 命令行部署: 只需执行几行简单的命令

🔒 去中心化存储

PinMe基于IPFS(星际文件系统)技术,将你的网站内容存储在去中心化网络中。这意味着:

  • 不可篡改:上传的内容会生成唯一的哈希值,确保内容完整性
  • 永久访问:即使单个节点离线,你的网站仍然可以通过其他节点访问
  • 全球加速:内容通过IPFS网络分布,实现就近访问

🆓 完全免费

目前PinMe提供免费的部署服务,支持:

  • 单个文件最大200MB
  • 整个目录最大1GB

🚂快速开始

🕸️ 网站上传部署(小白推荐)

浏览器打开网站:pinme.eth.limo/

将你构建好的前端项目或者静态网页文件上传,上传成功之后会返回一个url地址(保存好此地址),使用此地址即可访问你的网站。

部署示例网站:34759bf5.pinit.eth.limo/

pinme-web-example.png

注:建议使用github账号登录,登录之后每次上传有历史记录可以查看,历史记录中可以查询到我们的地址

🖥️ 命令行部署(开发推荐)

  1. 准备环境

要求 Node.js 版本 ≥ 16.13.0

如果版本过低,先升级 Node。

  1. 安装 PinMe CLI

使用 npm:

npm install -g pinme

3. 构建并上传

以常见的前端工程为例:

# Vite / React / Vue 项目,一般是:
npm run build

完成构建后,上传:

# 最常见的 dist 目录
pinme upload dist

命令执行成功后,你将得到:

  1. 一个 IPFS 内容 hash
  2. 一个预览页面链接:
    https://pinme.eth.limo/#/preview/*

打开这个链接,就能在线访问你的站点。

⏳ PinMe CLI:常用命令一览

PinMe 主要通过 CLI 提供能力,整体命令集很简洁。

⬆️ 1. 上传(核心命令)

# 交互式上传(会让你选择要上传的目录/文件)
pinme upload

# 直接指定路径上传
pinme upload /path/to/file-or-directory

# 上传并绑定一个固定子域名(需要 AppKey & Plus 会员)
pinme upload dist --domain my-site
# 简写
pinme upload dist -d my-site

注意:

  • 固定域名使用的是 https://<name>.pinit.eth.limo 这种形式
  • 绑定固定域名需要 AppKey 且开通 Plus 会员;普通用户可以使用预览链接访问。

🔄 2. 查看上传历史

# 查看最近 10 条上传记录
pinme list
# 或简写
pinme ls

# 指定数量
pinme list -l 5

# 清空本地上传历史
pinme list -c

♻️ 3. 删除与清理

# 交互式删除(从历史中选择)
pinme rm

# 指定 IPFS hash 删除
pinme rm <IPFS_hash>

需要说明的是,rm 实际做的是从 PinMe 使用的 IPFS 节点中「取消 pin 并移除 ENS 记录」,并不意味着全网 IPFS 都会立刻删除内容。

🔓 4. 登录与身份(AppKey)

PinMe 使用 AppKey 来标识用户,用于:

  • 账号登录
  • 上传历史合并
  • 固定域名绑定

appkey可在网页端 Account Information 页面查看

相关命令:

# 设置 AppKey
pinme set-appkey

# 查看当前 AppKey 信息(会做掩码处理)
pinme show-appkey
pinme appkey

# 登出并清除本地认证信息
pinme logout

# 查看当前账号拥有的域名
pinme my-domains
pinme domain

👁️‍🗨️ 5. 帮助信息

pinme help

📂 上传大小限制与存储说明

免费计划下的限制(以 README 为准):

类型 限制
单个文件 200 MB
整个目录总和 1 GB

上传后文件会存储在 IPFS 网络中,并通过 Glitter Protocol 的 IPFS 网关提供访问。

成功上传后你会获得:

  1. IPFS 内容 hash
  2. 预览链接:https://pinme.eth.limo/#/preview/*
  3. 可选固定域名:https://*.pinit.eth.limo(需 Plus)

本地日志默认保存在:

  • Linux / macOS: ~/.pinme/
  • Windows: %USERPROFILE%.pinme

❤️ 结语

PinMe代表了前端部署的未来方向——简单、快速、可靠。无论你是独立开发者、创业团队,还是大型企业,PinMe都能为你节省宝贵的时间和资源。

告别繁琐的服务器配置,拥抱一键部署的新时代。试试PinMe,体验前所未有的部署体验!

一句话总结:构建你的网站,运行pinme upload,然后就可以分享链接了。就这么简单。

❌
❌