大家好,我又来发布新作品了,这次带来非常有意思的前端组件框架PHC。相信作为前端开发者,你已经用过非常多的框架,例如vue、react等,但是在你的工作中,你不得不去考虑更多的问题,而会接触类似next、astro等更高层面的框架。可是无一例外,所以的这些框架都必须借助构建工具。有没有一种可能,我们前端开发在某些场景中,或许应该返璞归真,不需要那么复杂的工程体系呢?PHC就是这样一款没有新语法、新概念、新设计的轻量级框架,让你可以超快的搭建自己的应用组件。
原文地址:www.tangshuang.net/8844.html
项目地址:github.com/tangshuang/...
什么是PHC?
PHC是Hypertext Component的缩写,是基于超文本语言文件的组件开发框架。说白了,就是用纯粹的原生web开发语言来实现组件。2024年,前端开发领域已经进入一个新阶段,很多技术在发展过程中留下了很多债务,而社区存在一股力量,趋向于返璞归真,回到web开发的本真道路上,不忘初心,做出更有意思的web应用。在这一背景下,我开发了PHC来让开发者可以更方便的实现自己的前端代码组织。通过PHC框架,我们可以用纯粹的HTML、CSS、JavaScript来进行开发,也正因如此,我们不需要花时间学习PHC,你可以在1分钟内了解它的全部,并开始上手开发。
PHC立足于纯粹的web技术,和vue、react等视图层的框架不矛盾,甚至可以兼容,PHC的目标是提供web组件的开发框架,但不限制组件的具体实现。也就是说,我们使用PHC的核心理由,是我们希望快速写一个web组件,在我们已有的web应用中使用。但是,这个web组件具体怎么写,PHC没有做任何规定,它既不提供新语法,也不提供任何写代码层面的规则,组件代码本身怎么写完全是开发者自己决定的。你甚至可以在组件中同时使用vue和react来作为视图驱动,实现在组件中响应式编程,当然,也可以使用纯粹的js来修改DOM实现界面变更。总而言之,PHC只关心组件的组织形式,而不关心组件的写作方式。
与其他的框架相比,PHC具有以下优势:
- 使用超文本(HTML)作为开发语言,无多余知识,无高深的概念
- 快速查看组件效果,没有繁杂的构建体系
- 单文件组件:用一个.htm 文件写一个组件,独立部署到 CDN,不需要打包或编译
- Web Components: 完全基于 customElements 实现,组件被放在 shadowDOM 中,支持样式隔离,支持向组件传标准的 slot
- 没有 Virtual DOM,更新直接触达 DOM 节点
- 异步按需加载:只拉出当前界面渲染需要的组件,当前界面不需要的组件不会被拉取
- 通过
<link rel="sfc" as="custom-name">
快速链接组件 - 组件可嵌套
- 超快,底层基于vanilla.js驱动
- 超小体积,5kb
- 支持所有支持ES5的浏览器
总结而言,PHC的特点就是:简单、快!
1分钟学会PHC
首先,我们需要加载PHC的包文件到我们的web应用中。
xml
<script src="https://unpkg.com/phc"></script>
这样,我们的应用就载入了phc的包,我们就可以在我们的应用中使用phc作为组件框架进行开发了。
接下来,我们开始写一个组件文件some.htm:
xml
<style>
.container {
margin: 10px;
}
</style>
<div class="container">
<main></main>
</div>
<script>
const doc = new Document();
doc.querySelector('.container main').innerText = 'Hello PHC!';
</script>
最后,我们在我们的应用(或者某个其他的phc组件中)引入和使用这个组件:
javascript
<link rel="phc" href="./some.htm" as="some-x" />
<some-x></some-x>
在使用时,我们通过link引入该组件,并通过as对组件在当前上下文中进行命名,接下来就是使用该组件(像使用普通的 web component 一样使用它)。
你需要学习什么?
对于PHC而言,我们没有任何新语法,只是在原有的web接口的基础上,进行了扩展。具体如下:
-
const doc = new Document()
在组件中 new Document() 将获得当前组件的上下文文档(以进行组件内的文档操作),且doc.rootElement
将读取组件实例化后的DOM对象 -
<link rel as>
我们新增了phc
这个 rel,并且需要你提供 as 作为(web component)组件名,需要注意,需提前声明,不可以动态添加
-
const win = new Window()
在组件中通过 new Window() 来获得当前浏览器窗口 -
在组件内使用
document
和window
意义不大,没有实际作用,不推荐读取
以上就是PHC的所有知识。没有其他了,为了让PHC足够简单,除了无法克服的Document和Window,我把所有前期设想过的语法、功能、概念,全部去除了。也正是这种对极简的追求,最后框架的包代码被压缩在5kb,经过gzip压缩之后还会更小。
在PHC组件中使用Vue
虽然我推荐使用纯粹的js来进行编程,但是为了展示phc的兼容能力,下面我将写一个用vue作为视图驱动的组件:
xml
<script src="https://unpkg.com/vue@3/dist/vue.global.prod.js"></script>
<div id="app" style="display: none;">
<span>{{ message }}</span>
<button @click="change">change</button>
</div>
<script>
const { createApp, ref } = Vue;
const doc = new Document();
const root = doc.querySelector('#app');
createApp({
setup() {
const message = ref('Hello vue!')
const change = () => message.value = 'I am changed';
return {
message,
change,
}
}
}).mount(root)
root.style.display = 'block';
</script>
在这个组件中,我们引入了vue的包文件,并按照vue的写作方法来启动DOM的加载和变更。通过vue我们可以实现响应式编程,这样可以使用状态来驱动我们的界面变更。
与微前端框架的区别
通过上面的vue组件的例子,你可能会产生一个疑问,这和微前端有什么差别呢?感觉很像。虽然......但是,PHC和微前端是两个层面的事物,解决不同的问题,微前端解决巨石应用的重构问题,以做到跨技术栈为主要技术实现;PHC解决快速启动web开发问题,以让开发者可以在短时间内实现多页面应用编程问题。对于微前端而言,子应用无需关心外部环境,可以被无感集成到基座应用中。而PHC组件必须按照框架的设定来编写和使用,虽然在写作上有非常大的自由度,但还是有非常小的前置约束。作为技术框架,一旦选择PHC,就很难再将技术栈切换到其他技术栈上,因此,你需要在技术选型时提前评估。不过由于PHC的宽广自由度,对PHC组件进行简单改造即可被迁移到其他微前端框架中使用,或者将其他微前端子应用作少量改造,就可以被作为PHC组件使用。
在技术实现上,微前端框架需要解决子应用之间、父子应用之间抢资源(样式、JS运行时、通信等)的问题,因此,发展出了各种沙箱机制,使得代码在沙箱中运行,从而解决抢资源问题。但这会带来另外的问题,就是性能的下降,特别是像qiankun这样依赖代理实现的沙箱机制,会使得应用运行过程中产生很多不可预料的问题。而PHC虽然也做到了隔离,但是由于没有这些机制,没有多余的实现,因此也就不存在对应的问题。按照PHC框架写组件,就能发挥组件代码的原始性能。
结语
由于PHC过于简单,且没有什么高深的学问,对PHC的介绍就到此结束。前端开发技术在过去几年,过于沉浸在工程工具层面,而忽视了很多表层的体验问题,随着大模型时代的到来,工程问题会慢慢被机器替代,唯有做出优秀的体验需要人的创造力。PHC追求极致的简单,或许看上去单薄,但却是返璞归真回归本心的一次大胆尝试。有兴趣的同学,可以在github关注本项目,一起讨论。