作者归档:白宦成

关于白宦成

独立开发者, 自由职业者, 写作者

f30a202d97fcb737a80ade314ebdb8e0 1

自定义 Bootstrap 5 的风格,实现自定义风格页面开发

和更加自定义化的 TailwindCSS 相比,Bootstrap 显然更具备主题和模板页面开发的潜力和更易于进行模板页面的开发 —— 毕竟各种样式都已经封装好了,你可以直接使用诸如 btn 来定义一个 Button。

我有在想,提供一个基于 TailwindCSS 的 StarterKit 来快速基于 TailwindCSS 开发出一套自己的样式库,但仔细想想,其实意义不大。因为可选项太多了,想要自定义化其实没那么容易。

白宦成

而在开发 Bootstrap 的时候,大家往往会遇到的一个问题的是 —— Bootstrap 开发出来的页面千篇一律,一千个人有一千个哈姆雷特,但一千个 Bootstrap 页面却长的一模一样。而这背后的原因,主要是因为大部分人使用的是标准版的 Bootstrap —— 也就是官方所定义的样式。大家都使用一样的样式,自然就使得开发出来的页面显得雷同。

不过,其实 Bootstrap 的风格自定义并不困难。

前情提要

其实大家不去做自定义风格开发的原因倒是可以理解 —— 锅都要给 Node Sass,在 Bootstrap 5 以前,Bootstrap 使用 Node Sass 来进行样式的构建,但 Node Sass 是一个基于 C++ 编写的拓展,这使得 Node Sass 的安装十分麻烦,加上特有的网络环境,使得 Node Sass 的安装十次有九次都是无法成功安装的,大家自然也不愿意使用 Node Sass 构建的项目(包括我自己,都会刻意选择使用 Less 构建的项目)。

不过,从 Bootstrap 5 开始,Bootstrap 项目开始使用 Dart Sass 进行样式风格的开发。这使得 Bootstrap 的构建不会像过去那么痛苦,因此也可以更好的进行风格的自定义。对于如今还在使用 Bootstrap 进行项目构建的同学来说,无疑是个好消息。

自定义 Bootstrap 5 的风格

关于如何在你的项目中引入 Boostrap 的 Sass 来满足自定义的需求,可以参考官方所给出的 Customize Sass 的说明,官方提供了包括 WebpackParcel 等的接入说明,如果你连基本的配置都懒得做,官方还提供了一个空白项目,方便你 Fork 后再修改。

以我自己使用的 Next.js 为例,配置起来也比较简单:

1. 安装相关依赖

在 Next.js 项目根目录安装所需依赖

yarn add bootstrap
yarn add -d sass sass-loader

2. 创建 Scss 文件

styles 目录下创建一个新的 globals.scss 文件,并在其中加入如下代码

// custom variables
@import "../node_modules/bootstrap/scss/bootstrap";
// custom css code 
Code language: JavaScript (javascript)

其中 custom variables 的部分是让你用来加入自定义的变量的,比如自定义 Primary 的颜色、自定义 Padding 等一系列操作,都需要在 Bootstrap 的引入前定义,这样才能确保你的引入变量会生效。

而后面的 custome css code 则是可以用来定义一些你自己编写的,没有被覆盖在 Bootstrap 内部的类。

3. 在项目中引入创建好的 scss 文件

在项目的 pages/_app.js 引入我们刚刚创建好的 scss 文件,从而确保应用在启动的时候可以自动构建 Bootstrap ,并引入至项目中。

import '../styles/globals.css'
import '../styles/globals.scss' // 这一行是新增的
function MyApp({ Component, pageProps }) {
  return <Component {...pageProps} />
}

export default MyApp
Code language: JavaScript (javascript)

4. 在项目中使用 Bootstrap 类进行开发

当你完成上述的配置,就可以在自己的项目中引入相应的类来进行开发了。

一些小技巧

使用 Themestr.app 进行风格的快速设定

Themestr 是一个帮助你快速生成一套Bootstrap5自定义风格的工具网站。

d2b5ca33bd970f64a6301fa75ae2eb22 2

在 Themestr 中,提供了 UI Builder、Themer 和 Customizer 三个不同的工具,其中:

UI Builder 提供了一个简单的 4 步选择器,让你定义了基本的颜色、字体、ICON 和 按钮风格,从而形成一套独特的 Bootstrap UI。

d2b5ca33bd970f64a6301fa75ae2eb22 3

Themer 则提供了更加全面的样式的设定和预览功能,你可以在右侧的选择界面简单的配置样式,并在左侧自动刷新的页面中查看你的配置所实现出来的效果,方便你快速找到看到你的配置所能展现出的效果,简单且直观。

d2b5ca33bd970f64a6301fa75ae2eb22 4

Customizer 则提供了全面的 Bootstrap 的变量,方便你快速找到你要修改的变量,并帮助你生成对应的 Sass 配置文件,方便你在此修改变量,并在本地进行开发。

d2b5ca33bd970f64a6301fa75ae2eb22 5

对于不同的场景,Themestr 提供了不同的工具来帮助你快速开发,是一个非常不错的 Bootstrap 主题开发的辅助工具。

如何找到需要修改的变量

Bootstrap 在文档中针对每一个 Component 都提供了相应的 Sass Variables 的说明,你只需要在文档中找到你要修改的组件, 并在你自己的 global.scss 中修改对应的变量,就可以实现自定义。

d2b5ca33bd970f64a6301fa75ae2eb22 6

如何找到特定类的源码

在进行 Bootstrap 开发的时候,如果有些类你找不到样式的时候,一个很好的方式是开启开发环境,并在开发环境中可以看到对应的 scss ,并在对应的 scss 当中,点击链接跳转到对应的 scss 定义,即可看到对应的样式的源码。

d2b5ca33bd970f64a6301fa75ae2eb22 7
d2b5ca33bd970f64a6301fa75ae2eb22 9

在跳转后,有些时候你发现似乎并不是直接定义的样式,比如下图,则说明这样的类是通过 map 来批量生成的,你就需要修改对应的 map 来完成自定义。

d2b5ca33bd970f64a6301fa75ae2eb22 8

如何自定义主题颜色、字体大小、间距等批量生成的类

在 Bootstrap 中存在一些批量生成的类,比如 theme-colorfont-sizefont-weight 还有 paddingmargin 等等。

这些类是 Bootstrap 使用 @each 来生成的,而生成的依据,则是 Bootstrap 的各种 map 来完成的。因此,你想要进行定义,则需要修改对应的 Map。你可以使用 map-merge 来向 map 中添加新的选项

// Create your own map
$custom-colors: (
  "custom-color": #900
);

// Merge the maps
$theme-colors: map-merge($theme-colors, $custom-colors);
Code language: PHP (php)

而如果你想要移除一个选项,则可以使用 map-remove 方法来完成

// Required
@import "../node_modules/bootstrap/scss/functions";
@import "../node_modules/bootstrap/scss/variables";
@import "../node_modules/bootstrap/scss/maps";
@import "../node_modules/bootstrap/scss/mixins";
@import "../node_modules/bootstrap/scss/root";

$theme-colors: map-remove($theme-colors, "info", "light", "dark");

// Optional
@import "../node_modules/bootstrap/scss/reboot";
@import "../node_modules/bootstrap/scss/type";
// etc
Code language: JavaScript (javascript)
7423a3c685ae859e7d5283b7e1b33c4c

关于 ASoul 事件的一些思考

我自己其实不太了解 ASoul,也没有特别的关注,毕竟作为一个社牛,不太会通过虚拟人来获取情绪价值。但我确实之前听说过 VTuber,在我的下意识以为,VTuber 的声音应该是由 AI 来完成生成,工程师建模,PM/运营来负责脚本的产出(类似微软小冰)。

不过,现实可能是 ASoul 这样的项目其实是由中之人来完成声音的录制,更接近于传统的声优的角色。对于资本来说,中之人就是一个耗材,但对于喜爱 VTuber 的人来说,中之人是非常重要的。

当一个 VTuber 之后是一个独立的人的时候,其实能贡献的当然不只是声音的问题,还可以贡献出更多的情绪价值。而这些情绪价值,正是一个 VTuber 的独特的价值。

这些东西是完全无法通过 AI 生成的么?可能是可以生成的,但暂时可能无法生成。随着技术的进步,逐步拆解出人的各种情绪和诉求,再由 AI 来完成生成,实现真正意义上的 VTuber

A group of friends at a coffee shop

情分和本分

我们在生活中,需要注意情分和本分的区别。不要错把本分当情分,把情分当本分。

举个例子来说,

假设我当前的房子快要到期,我找了一个新的空房间。为了减少租期的重叠,我与房东达成了一致,在两周后入住。

但因为我自己的原因,不得已需要提前入住,这个时候我和房东沟通,说我是否可以提前入住?房东同意我提前入住。

在这个事情当中,房东同意我入住是情分,房东不同意我入住是本分,因为我们的合同签署的入住日期是两周后,即使不允许我入住,我必须出去住酒店,也是因为合同签署的确实是两周后,这也是合法合理的。

在生活中我们需要感谢别人的情分,感谢他人的帮助。但同时也要明白,别人遵循本分做事并没有什么不对,人家只是遵照合同办事,没有过错。

summary

2022 年 4 月月度总结

Objective 1:持续获取现金流,并构建未来收益的现金牛

KR1:投资收益达到 20000 元

长期投资:本月持续定投指数基金。

投机:本月开始进行 Crypto 领域的买入,目前在买入的是 NFT 。NFT 的市场还是比较有意思的,波动比想象中的要小一些(也可能是因为我一进来就碰到了一个还行的项目)。目前两张图片都还是有浮盈的,不过首先于最近的股币双杀,没有太大的变化可以预期。好在我买的时候都很便宜,也不指望这一笔赚多少钱,挂了个单就丢那里了。

不过在购买 NFT 的时候,也发现了很多机会(也可能是坑),目前 NFT 领域的工具链并没有我们想象中的那么全面和丰富,里面有不少的空间可以去做一些东西。后续我应该也会去

KR2 :单篇稿费突破 6000 元

这方面还没有变化。感觉还需要拆解一下,如何提升稿费。

阅读量?但看起来像是广告费。需要量化一下。感觉自己这个 KR 定义的有问题。

KR3 :达成年度预算,支出不超预算

目前支出预算略超,五月要考虑节约一点了。

KR4 :构建软件类现金牛业务,预期产生收益 10000 元人民币m

软件类业务本月没有太大的进展,主要是状态不好,盯盘的花费的精力较多,5月优先这部分 KR。

Objective 2:提升生活基础设施,构建未来生活好基础

赚钱的目的是生活,不能为了赚钱而赚钱,更应该关注自己的生活。因此,为了生活,设定下如下两个 Key Result:

KR1:前往 6 个城市旅行

四月份去泡了个温泉,体验了一把室外温泉。没有远行,主要还是收到了疫情的影响,比较难。

KR2:进行 20 次文娱活动

四月看了一场话剧,圆了自己的一个心愿。

KR3:借助智能化设备,缩减在家务相关事务上耗费的时间

暂无进展

Objective 3 :开拓视野,打造多元行业人才

KR1:写 15 篇书评

原本说想在少数派写原则系列的书评,结果也鸽了。。。唉。。。

KR2:输出关于加密货币的 Newsletter 12 封

继续 0 进展。为什么不敢写?应该还是怕自己的产出这不符合自己的预期?有偶像包袱?

KR3 :完成计划中的三本图书的写作

暂无进展。

0dbb4980acb58d4396e9a2055bf2176e

OneInStack 中 Redis 的使用注意事项

在使用 OneInStack 时,有一些事项需要注意,不然可能会导致你的 Redis 在使用过程中出现问题。

1. Redis 默认配置内存是 122 MB

OneInStack 中 Redis 的默认内存配置是比较小的,只有 122MB ,对于一些大型应用来说,是肯定不够的,因此,在实际使用过程中,还是最好将其修改为一个更大的值。

配置文件路径: /usr/local/redis/etc/redis.conf

需要修改的项目 maxmemory 122000000,将 122000000 修改为 256000000 即可将 Redis 使用的内存设置为 256 MB,从而扩大了整体可用的内存的大小,应对大型数据库也游刃有余。

2. Redis 的逐出机制为 noeviction

OneInStack 中 Redis 的默认逐出机制是 noeviction,即内存满后不逐出,写入缓存报错,读缓存不受影响。

对于将 Redis 作为数据库的场景而言,这么干是正确的。但对于做缓存的场景,则需要修改逐出机制,比如可以将逐出机制修改为 allkeys-lru,即在全部的key中淘汰最近最少使用的key。

在配置文件( /usr/local/redis/etc/redis.conf)中加入一行配置即可

maxmemory-policy allkeys-lru
brown short coated dog on brown wooden table

被种草 & 断舍离

我算是一个被「消费主义」洗脑的人,很喜欢买各种各样的东西,比如:

  • 我家中有三台电脑:一台 mac mini 2012 (主力使用);一台 mac book pro 16寸(出差使用);一台 NUC(用来做一些 Windows Only 的事情)
  • 我家中有多个水壶:一个京造的手冲壶(用来冲挂耳);一个小熊的蒸茶壶(用来蒸煮我的各种茶叶);一个大的烧水壶;

我买了很多东西,其中一部分是我自己生活需求的延展所带来的,另外的一部分,则是来自于被各种视频/朋友推荐。

我买的制冰机便是一个典型的例子:

我是在津津乐道的节目当中听到大家推荐居家好物的时候,提到了制冰机,以及制冰机带来的畅快感,就买了制冰机。

而我购买产品的逻辑倒是也十分简单:我不太会听陌生人的推荐,而更相信一些有着持续关系和持续口碑的人的推荐。在我看来,靠谱的人推荐的产品大多是靠谱的,不靠谱的人推荐的产品是不可信的。

最近,又快要到搬家了。准备继续寻找一个更加低成本生活的方式。届时,又是一次断舍离。

当我的东西变少的时候,确实,生活变得更快乐一些(就像我们想要去露营,体验的一方面是大自然的美妙,另一方面,则是对于逼仄生活的反抗。)

f30a202d97fcb737a80ade314ebdb8e0

MySQLDump 导出部分数据

MySQLDump 是非常常用的数据库导出工具。不过,大部分时候,我们使用的都是 mysqldump -uuser -p database_name > database_name.sql

这样可以提供数据导出功能,但导出的数据会是全表数据,我们在导出数据的时候,如果希望导出部分数据,就需要借助于其中的 --where Flag,来实现导出部分数据.

此外,由于导出的数据是部分数据,因此,就涉及到需要指定导出时的表名,才能实现导出相应的数据,需要满足如下格式

mysqldump [OPTIONS] database [tables]
Code language: CSS (css)

举个例子来说,假设我们需要导出数据库 wordpress 的 wp-options 表中的 ID 小于 20 的数据,则需要执行如下命令:

mysqldump --where="id < 20" wordpress wp-options
Code language: JavaScript (javascript)

上述命令就实现了从数据库中导出符合特定要求的数据。

CAPTCHA

Next.js 实现动态引入,实现对非 SSR 组件的支持

在使用 Next.js 进行开发的时候,会遇到某些组件是不提供 SSR 支持的(很正常,毕竟 SSR 是一个相对比较小众的应用场景。此外,某些组件会依赖浏览器环境的上下文),在这种情况下,我们需要一种方式来实现对非 SSR 组件的支持。

一般而言, 有两种方式,一种是使用 useEffects 来控制组件的载入,从而实现只在客户端层面加载组件,服务端渲染的时候就不再加载该组件。

另外一种方式是可以考虑借助于 Next.js 自带的 Dynamic Import 的特性,来完成组件的引入。

在使用层面比较简单,引入组件的方式从直接引入改为最外层套一层 dynamic 函数即可

import dynamic from 'next/dynamic'

const DynamicComponentWithNoSSR = dynamic(
  () => import('../components/hello3'),
  { ssr: false }
)

function Home() {
  return (
    <div>
      <Header />
      <DynamicComponentWithNoSSR />
      <p>HOME PAGE is here!</p>
    </div>
  )
}

export default Home
Code language: JavaScript (javascript)

总结

这个问题的解决让我再次激起了对于 Next.js 的兴趣。过去因为不确定如何解决在浏览器和客户端环境下的问题,对于 Next.js 有些畏难;如今问题已解决,可以继续放心的使用 Next.js 了。

参考阅读

https://nextjs.org/docs/advanced-features/dynamic-import

code 1076536 640

那些影响你前端开发体验的问题(1)

最近在研究和体验一些 GitHub 上的前端项目,遇到了一些让人体验不佳的点, 这里梳理一些我遇到的,一方面是留存,记录那些让我体验不好的事情。另一方面警示自己在开发前端项目的时候应该注意一下开发体验,确保不会让别人在开发的时候也遇到这些问题。

1. 项目应该有文档

这是不少 GitHub 上面项目的普遍问题。现有的文档要么是以 Framework 生成的 Readme 为主,要么直接没有文档。

但没有文档对于后来者的开发其实非常不友好,比如几个常见问题:

  1. 如何启动一个 Server & 如何设置后台 API 的 Prefix?
  2. 项目的组织结构是什么样的?
  3. 涉及到的第三方服务应该如何配置?

上面这些文档是帮助后来者快速使用你的项目所必需的(换句话说,如果你要做开源项目,想要打造开源社区,这也是必要的)。

2. 项目控制算法复杂度

我在开一些前端项目的时候,明显会感到浏览器的响应变慢了,我以为是我的 Mac Mini 2012 性能不行。但我打开自己的博客,依然如丝般顺滑,我就明白了。问题不在于我的电脑性能跟不上,而是这个前端页面加入了大量的有用或无用的代码,使得 CPU 需要大量的计算。

虽然进入 SPA 的时代以后,我们开始将算力的使用从服务端往客户端转移,但也建议各位工程师控制自己项目的复杂度,不要一开网页,风扇就呼呼的转。浏览体验不好,还凸显自己的技术不行。

3. 使用 debuuger 调试,而不只是 console.log

在编译型语言当中,使用 Debugger 来进行调试是一项基本技能,因为需要在运行时去看不同的变量的值,以此来完成调试。

d2b5ca33bd970f64a6301fa75ae2eb22
爆炸的 Console

但在前端领域,因为 console.log 的过于好用,大家开始习惯于使用 console.log 来打印变量,但对于大型项目来说,大量的 console.log 也会让你的项目输出许多无意义的内容,让整个项目的调试和开发受到阻碍。

总结

最近看项目,总结了三条自己觉得影响体验的点,后续随着看的项目的深入,会逐渐总结出更多影响体验的点,引以为鉴。

灵光一闪

如何迸发灵感 – 写作

我的博客能够保持日更,主要来说,是有两方面因素:

对于写作的预期没有那么高

很多时候,我的写作都是要先取悦自己。所以我对于一篇博客的要求没有那么高,达到最低标准,300 字即可(这个也是微信公众号原创文章的要求),所以我不会有太多的心理压力,担心一篇文章是否足够完美。

拥有充足的灵感

我每天会看到大量的文章内容,这些文章内容可以激发我自己思考,并产生出新的灵感,通过这些新的摄入诞生的很多灵感都不够深刻,但确实可以写下我对这个问题的思考,并在后续的时间沉淀下,不断的重新思考、再次思考。

我常用的信息输入的平台:

  • InoReader
  • V2ex
  • Newsletter

如果你发现自己没有灵感,不妨试一试。