0%

从原始 CSS 到 CSS 框架的演变

在 CSS 发展的初期,开发者主要使用以下几种方式来编写和应用样式:

  • 内联样式:在 HTML 标签内直接使用 style 属性。这种方式简单直接,但难以维护和复用。
  • 内嵌样式:在 HTML 文档的 <head> 中使用 <style> 标签编写样式。虽然比内联样式稍好,但仍不够模块化。
  • 外部样式表:通过 <link> 标签将独立的 CSS 文件引入 HTML 文档。这种方式使得样式得以复用和集中管理,成为现代开发的主流方法。

这些原始的 CSS 编写方式虽然有效,但当项目规模扩大时,其维护性和复用性逐渐成为挑战。历史的车轮滚滚向前,开发者需要从容应对项目复杂性不断提升的方案,CSS 预处理器如 SassLESS 也应运而生。它们通过提供变量、嵌套规则、混合宏等功能,极大地提升了 CSS 的可维护性和扩展性,使得开发者可以更高效地管理复杂项目中的样式。

随后,CSS3 的发布为 CSS 带来了许多新特性,包括动画、变换、媒体查询等,使得样式的编写更为灵活和丰富。CSS3 的这些扩展为开发者提供了更强大的工具来创建现代化的响应式页面,从而为 CSS 框架的进一步发展奠定了基础。

接下来,CSS 框架逐渐成为解决方案,以标准化和模块化的方式提升开发效率。

在 CSS 框架的进化过程中,尽管 Bootstrap 被广泛视为使前端开发者摆脱手写样式的首个大规模流行 CSS 框架,但它并非最早的尝试。在 Bootstrap 之前,已有若干框架为后续 CSS 发展奠定了基础,例如 Blueprint CSS960 Grid System

  • Blueprint CSS(2007 年):是早期极具影响力的 CSS 框架之一,它通过定义通用样式和布局规范来提高开发效率。Blueprint CSS 的出现意味着开发者可以依赖一套统一的标准,而不必重复发明轮子,从而提高了代码的可读性和维护性。
  • 960 Grid System(2008 年):引入基于 960 像素宽度的网格布局系统,为开发者提供标准化的页面布局方法。这个系统在当时极大地简化了页面布局的工作,使得开发者可以快速创建一致性强的响应式页面。

Bootstrap 于 2011 年 由 Twitter 的开发者 Mark Otto 和 Jacob Thornton 发布,其结合了现代化的响应式布局理念和组件化风格,迅速成为广泛应用的 CSS 框架。Bootstrap 的成功在于它将响应式网格布局、样式和组件整合到了一起,为开发者提供了一种“一站式”的前端开发解决方案。Bootstrap 引入了大量的预定义样式和 UI 组件,极大地降低了开发复杂性,尤其是在构建跨浏览器兼容的用户界面时,Bootstrap 的贡献功不可没。

Bootstrap 的出现标志着前端开发进入了一个新的时代,使得开发者能够高效地实现页面布局。然而,Bootstrap 的预定义样式也逐渐显现出其局限性——页面设计趋于一致,缺乏个性化表达。这种标准化设计虽然提升了效率,但也导致了许多网站的“千篇一律”现象,限制了创意的发挥。随着前端领域需求的多样化,开发者开始寻求更加灵活和高度可定制化的解决方案,一场新的变革正在酝酿之中。

从 CSS 预处理器到 UI 组件库的兴起

在 CSS 预处理器提升了样式管理的效率之后,UI 组件库随着在Modern Web时代的全面到来应运而生。它们不仅提供了样式,还封装了交互逻辑与功能,使得前端开发更加模块化与高效。UI 组件库的出现将“预制组件”带入了前端开发的日常,为开发者提供了一整套标准化、可复用的组件,极大地减少了样式和功能的重复开发。以下几位重要的玩家在这一过程中发挥了关键作用:

Read more »

本指南暂不包含 fetch , pull, push, clone 等 Git 版本库操作和 CI/CD 工作流搭建等

一、版本规范:

结合 semver 语义化版本以及 software release life cycle 软件发布生命周期两块概念,约定 git tag 标签规则

格式命名

基础版本格式:

<主版本号>.<次版本号>.<修订版本号> 三位数字用 . 连接组成一个版本号,如 1.0.0
版本号数字递增规则:

  • 主版本号:对代码进行了不向前兼容的修改
  • 次版本号:向前兼容的修改,只是新增了功能
  • 修订版本号:向前兼容的故障修复、需求细节变更

    细化版本格式:

    在原来 x.y.z 基础版本号后面添加软件生命周期作为先行版本号,以及添加附加信息(编译信息、时间戳、序号等)来进一步细化控制版本
  • 先行版本号:表示在正式版之前发布的版本,并非稳定而且可能无法满足预期的兼容性需求,格式是标注在修订版之后,先加上一个连接号-, 再加上一连串以句点分隔的标识符来修饰, 。范例:1.0.0-alpha.11.0.0-rc.221.0.0-beta.33

    常见的先行版本

    • alpha: 内测版本,通常提测至测试部
    • beta: 公测版本,通常可以面向用户全量或者灰度发布
    • rc: 即 Release candiate,正式版本的候选版本,用作预发布
      注:这些版本的发布可能需要团队的工作流程以及部署环境的隔离去支撑
  • 版本编译信息: 可以在修订版或先行版本号之后,先加上一个加号再加上一连串以句点分隔的标识符来修饰。范例:1.0.0+jested1.0.0-alpha+0011.0.0-rc+201303131447001.0.0-beta+exp.sha.5114f851.0.0-next+0

创建标签

1
2
3
4
# 创建
$ git tag -a "x.y.z-alpha+timestamp" -m "summary..."
# 推送
$ git push --tags

常用命令行:

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
# < xxx > just means variable

# List tags
$ git tag

# Show details of the tag
$ git show <TAG Name>

# Add tag to newest commit
$ git tag <TAG Name>

# Add tag to specified commit
$ git tag <TAG Name> <Commit Hash ID>

# remove tag (local)
$ git tag -d <TAG Name>

# remove tag (remote)
$ git push <Host Name> :refs/tags/<TAG Name>
$ git push <Host Name> :<TAG Name>
$ git push --delete <Host Name> <TAG Name>
$ git push -d <Host Name> <TAG Name>

# Push specified tag to remote
$ git push <Host Name> <TAG Name>

# Push all tags to remote
$ git push <Host Name> --tags

# Fetch all tags from remote
$ git fetch --tags

# Create a new branch from the TAG
$ git checkout -b <New Branch Name> <TAG Name>
Read more »

TL;DR

主导着当今世界前端技术发展的两家公司依然是 Google, Facebook;
目前前端的”三大框架“:Google 「Angular」 ,Facebook 「React」,而「Vue」也不完全算是是“自立门户”,也是吸收并借鉴了前者的优秀思想并进一步融合。

而 “三大框架” ,哪怕自身只是一个 View Library, 无一列外也都离不开 MV 的设计模式,在此设计模式下开发,就绕不开至关重要的的概念:状态管理,笔者也一如既往固执己见地认为,整个状态管理的过程其实就是贯彻 MV 对 Model、View 、 Controller/View Model 三者分层管理具体实施的过程,从而尽可能地保证 View 层的单薄,保证 Controller 的逻辑“C位”, 保证 Model 的数据中心,自始至终将应用的可维护性控制在一个较好的水平。

今天借 「State Management」 题发挥,基于团队目前项目所采用的技术框架 Vue, 来聊一聊状态管理。

Intro

Vue 框架也是深受 MVVM(model, view, view-model) 优秀的编程模型规范的启发,

同时结合了组件化的先进理念,自然而然地驱使开发者将整个WEB应用抽象分离到一个一个组件的颗粒度, 当一个应用不断被组件化抽象,小到一个按钮,大到一个页面,每个组件本身就是一个个独立的 vm 单元。

SFC (single-file components) 单文件组件的开发范式下,每个 *.vue 文件就是一个 vm<template>...</template> 可以理解为 vm 中的 v ;而 <style><style> 可以理解为 vm 中的 m的样式控制部分,<script></script> 可以理解为 vm中的 m的逻辑和数据部分, 另外框架底层实现了一个 MVVM 模型中的“绑定器” ,通过开发者对每个视图模型的声明式编程来驱动程序的视图更新。

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
// *.vue
vm
├── v // view
│ └── template
└── m // model
├── style
└── script
├── data
│ ├── data(){}
│ └── computed:{}
└── logic
├── lifecycle-hooks // created,...
├── watch:{}
└── methods{}
// 这种“奇怪的结构“思维,源于笔者入门编程时,深受 `MVC`(model, view, controller)编程模型启蒙式的“洗脑”,应用程序分层的思维早已根深蒂固

如此,开发者管理维护单个组件(vm 实例)本身,确实可以做到非常高效、清晰,
但是随着应用迭代,不知不觉,整个应用也变成了庞大的 “vm” 集合, 相隔层级较深的组件与组件之间可能形成了较长的通信路径。

Vue 本身内置的数据流管理方案有限, props(其实本质就像一个函数定义的参数), event emit 等其实在复杂场景发挥有限,不适合长路径的通信,无法支撑组织管理整个”前端应用“的状态,虽然又不是不能用,但是要追求合理可维护性则显的捉襟见肘。

另外,在整个前端应用生命周期下,数据既可能来源服务端接口通信,有可能来源于用户的交互操作,还有可能来源与组件之间的通信变更等,依托”绑定器“,不同流向的数据不断双向交织,并且如“化学反应”般不断产生“次生”数据,随着应用逐渐壮大的同时,形成的一张极其庞大的数据“网”笼罩着前端开发者,应用也变得越来越难以维护,开发者顿时失去了 MMVM 分层模式带来的舒适的开发体验,前端应用似乎也迎来了生命周期的”软件危机“,变的危如累卵,应用的故障将在任何时候任何地方变的一触即发。

如何再次贯彻 MV* 的模式思想?是否有办法再次将整个前端应用如”上帝视角“般的分层?前端开发者如何再次破局,突破瓶颈,拯救”软件危机“?

Read more »

Edit hosts file

location: /etc/hosts

1
2
3
# e.g:
# add a local domain
127.0.0.1 xllily.com

Install nginx

1
2
3
4
5
6
apt-get update
apt-get install nginx

# create folder 'ssl' for subsequent use
cd /etc/nginx
mkdir ssl

Control:

1
2
3
4
5
nginx -s [ stop | quit | reopen | reload ]

# or

sudo systemctl [ stop | start | restart | reload | disable ] nginx
Read more »

最后更新于 2020-2-20, 信息出入请以 uni-app official document 为准
为了保证信息有效性, 大量使用了文字链接关联官方文档的相关内容

( 图片源 uni-app official document )

开局一张图,内容开始编。

近期接手维护一个基于 uni-app 框架开发的项目,故笔墨伺候,简单做下功课。

以下内容对于未听说过或者未使用过 uni-app的前端“熟练工”相对比较友好些,内容有误,敬请指正。

uni-app 是一个使用 Vue.js 开发全平台(App,小程序,Web/H5)前端应用的框架, 由”为开发者而生的” W3C 成员及 HTML5 中国产业联盟的发起单位,数字天堂(北京)网络技术有限公司(DCloud)出品。

uni you ni,是统一的意思.
app 当指“应用(软件)”时,按 Google 翻译以及 Apple 官方读音, 读/æp/,而非 /eɪ̯.pʰiː.pʰiː/

已知全貌,准予置评。 🙈🙈🙈

开始吧…

Read more »

List corresponding ports and PIDs of all the network connections

1
netstat -ano

Show the network connections on the occupied port

1
netstat -ano|find "the occupied port number"

Stop the network connections by corresponding PID number of the occupied port

1
taskkill /F /PID [the corresponding PID number]