普通视图

发现新文章,点击刷新页面。
昨天以前凌览社

从我的实体书单中,精选这六本书推荐

2024年5月12日 16:16

工作之余偶尔看看书,偏爱翻阅实体书。随着时间的推移,书逐渐变得多了起来。为了给新书腾出空间,同时也为了减轻收藏实体书的经济负担,我决定进行一次书籍的整理和出售。在这一过程中,我特意挑选了六本我个人喜爱的书籍推荐给大家。

第一本:《曾国藩传》

推荐语:

《曾国藩传》不仅仅是一部传记,它是一扇窗口,让我们得以窥见晚清时期中国社会的历史风云。张宏杰先生以其精湛的文笔和深厚的历史功底,为我们细致勾勒出了曾国藩这位晚清重臣的一生,从他的个人奋斗到对国家的贡献,无不体现了他的智慧、勇气和远见。
曾国藩的故事,是关于一个普通人如何通过不懈努力,在动荡的时代中成就非凡事业的故事。他的人生哲学、治国理念和对家族的教诲,至今仍然具有深刻的现实意义和启示作用。
无论你是历史爱好者,还是对个人成长和领导力发展感兴趣的读者,这本书都将为你提供丰富的思考和灵感。《曾国藩传》不仅记录了一个时代的变迁,更是一部关于人性、智慧和力量的经典之作。

推荐理由:

  • 曾国藩的人生经历和思想,对读者很有启发和借鉴意义
  • 详尽的史料考证,为读者提供了一个立体、真实的历史人物形象

第二本:《纳瓦尔宝典》

推荐语:

致富不仅仅靠运气,幸福也不是从天而降的。积累财富和幸福生活都是我们可以且需要学习的技能。

本书涵盖了财富积累、幸福追求、决策制定以及个人成长等多个维度,为读者提供了一种全新的生活和思考方式。纳瓦尔的理念强调了长期思维、内在动机和持续学习的重要性,这些原则适用于任何追求卓越和个人自由的读者。

推荐理由:

  • 书中的原则简单明了,易于理解和应用到日常生活中
  • 通过纳瓦尔的个人经历分享了他对幸福、成功和财富的独特见解

第三本:《软技能:代码之外的生存指南》

推荐语:

程序员和软件开发者们往往专注于提升自己的硬技能,但本书,却为我们打开了另一扇门,引导我们探索那些常常被忽视,却同样重要的软技能。
作者约翰·森梅兹以其丰富的行业经验和深刻的洞察力,向我们展示了如何通过提升个人品牌、职业规划、理财能力、人际交往等软技能,来实现职业生涯的全面发展。这本书不仅适合技术人员阅读,任何希望在职场上取得成功的专业人士都将从中获益。

推荐理由:

  • 从人际交往到理财知识,书中讨论了职场成功所需的各种软技能
  • 强调了保持工作和生活平衡的重要性,并提供了一系列实用的建议
  • 教导读者如何建立和维护个人品牌,提高在行业内的影响力

第四本:《影响力》

推荐语:

社会心理学领域的经典之作。在这本书中,探讨了影响人们行为和决策的六大原则:互惠、承诺与一致性、社会认同、喜好、权威和稀缺性。这些原则不仅揭示了我们日常生活中的微妙影响技巧,也为读者提供了洞察力,帮助他们识别并运用这些原则以提高个人影响力。
本书不仅适用于营销和销售人员,任何希望提升人际交往能力、更好地理解他人行为背后动机的人都将从中受益。

推荐理由:

  • 心理学原理应用于日常生活和商业实践。
  • 帮助读者理解并识别影响他人的有效策略。
  • 内容适用于营销、管理、谈判和个人发展等多个领域。
  • 教导读者如何建立信任、增强说服力和提高社交技巧。

第五本:《明朝那些事儿》

推荐语:

本书不仅详细地描绘了明朝从兴盛到衰亡的整个过程,还生动地刻画了一系列历史人物的形象,如朱元璋、朱棣、海瑞等,他们的智慧、勇气、矛盾和挣扎都被作者以细腻的笔触一一展现。这不仅是一部历史书籍,更是一部深刻揭示人性、权力和道德抉择的作品。

推荐理由:

  • 看得”爽”,顺带学学历史,以史为鉴,可以知兴替

第六本:《JavaScript设计模式与开发实践》


推荐语:

这是一本专业类书籍,所以我把它放在最后推荐。本书系统地介绍了常见的设计模式,还结合了丰富的实例,展示了如何在实际开发中运用这些模式,以解决复杂的问题。无论是初学者还是有经验的开发者,都能从这本书中获得宝贵的知识,提升自己的编程技能。

推荐理由:

  • 复杂的设计模式概念变得通俗易懂
  • 涵盖了前端开发中常用的设计模式,实用性强

最后

诺~,就是这些了。

每个开发人员都应该知道的13个Nodejs库

2024年4月23日 15:02

Node.js,作为一种广受推崇的后端JavaScript环境,已成为众多网络开发者的首选。它不仅位列全球最流行编程语言之一,还通过JavaScript库的代码复用功能,极大地提升了项目开发效率。然而,面对众多选项,挑选合适的库以匹配项目需求无疑是一项挑战。

高效的库能够显著提升开发速度,并赋予Web应用多项优势,如加速页面加载和缩减应用体积。在挑选库时,开发者需综合考量应用的复杂度、库的社区支持、更新周期及文档完善度等因素。

Node.js的库通过其包管理器npm进行管理,npm为安装各类开源库提供了便利。接下来,将介绍13款精选的Node.js库,它们在简化Web开发流程方面各有千秋,希望能为您的项目带来助益。

Node.js简介

Node.js是一个开源的、用于JavaScript编程的服务器端运行环境。它以异步I/O和事件驱动模型著称,这些特性使其在处理实时分布式系统中的大数据量时表现出色。此外,Node.js支持跨平台操作,进一步增强了其在Web开发中的吸引力。

Node.js库概述

库,也被称作模块,是一段封装了常用功能的预编写代码。它们的存在旨在加快编码速度,促进代码复用,帮助开发者遵循“DRY”原则(Don't Repeat Yourself,即避免重复劳动)。与提供程序结构框架不同,库通常提供特定的功能,可以在项目开发的任何阶段灵活运用。

精选Node.js库介绍

以下是13款精选的Node.js库,它们各自具备独特的功能,助力简化Web开发流程。

1. Sequelize

Sequelize是一个基于Promise的ORM工具,旨在简化与关系型数据库的交互。它支持包括PostgreSQL、MySQL、MariaDB、SQLite在内的多种数据库系统。Sequelize通过JavaScript对象来映射数据库表结构,从而允许开发者无需编写原始SQL语句即可执行数据库操作,同时有效降低了SQL注入的风险,并与GraphQL兼容。

2. CORS

CORS是一个Node.js包,作为Connect/Express的中间件,实现跨域资源共享。它简化了Web应用中CORS的启用过程,允许开发者指定允许访问的域名,并提供了灵活的错误处理机制,帮助分析和防范安全风险。

3. Nodemailer

Nodemailer是一个简化邮件发送流程的Node.js库。它基于SMTP协议,支持多种邮件传输服务,允许开发者通过设置from、to、subject等参数来构建邮件消息,并支持HTML邮件内容的发送。

4. passport

Passport是一个Node.js的身份验证中间件,支持超过500种身份验证策略。它为社交网站登录、OAuth委托身份验证以及OpenID联合身份验证提供了内置支持,极大地简化了身份验证流程。

5. Async


Async是一个Node.js实用工具模块,专注于简化异步JavaScript的处理。它提供超过70种方法来控制异步流程,并帮助开发者避免所谓的“回调地狱”。

6. Winston

Winston是一个多功能的日志记录包,支持多种日志传输方式。它允许开发者根据需要自定义日志格式,并提供了灵活的日志级别控制。

7. Mongoose

Mongoose是一个为MongoDB设计的ODM库,提供模式定义、模型验证和查询构建等功能。它通过模式层为MongoDB集合提供了结构化的数据操作接口。

8. Socket.IO


Socket.IO是一个实时通信库,允许服务器和客户端之间进行基于事件的双向通信。它支持WebSocket和HTTP长轮询,提供了可扩展的事件广播机制。

9. Lodash


Lodash是一个包含200多个实用函数的JavaScript工具库,它提供类型检查、数学运算等常见编程任务的解决方案。

10. Axios


Axios是一个基于Promise的HTTP客户端,适用于Node.js和浏览器环境。它支持自动数据转换,并提供了防止CSRF的安全特性。

11. puppeteer

Puppeteer是一个Node.js框架,通过DevTools协议控制Chrome/Chromium,用于自动化测试和网页内容抓取。

12. Multer

Multer是一个处理多部分表单数据的Node.js中间件,它基于Busboy构建,支持文件上传和数据解析。

13. Dotenv

Dotenv是一个用于管理环境变量的Node.js模块,它允许开发者将配置数据与源代码分离,提高了应用程序的安全性和灵活性。

最后

在Node.js的生态系统中,存在众多功能强大的库,选择合适的库对项目的成功至关重要。本文介绍的库可能对您的下一款应用开发大有裨益,尤其是如果您频繁使用MongoDB,Mongoose可能会成为您的理想选择。希望这些信息对您有所帮助。

🔥一个收录独立开发者出海技术栈和工具的开源库,短短时间斩获2.4k Star

2024年2月26日 19:46

大家好,我是程序员凌览。

本文给大家介绍一个零代码的开源库,它只收录独立开发者出海技术栈和工具;帮助独立开发者更好地应对出海挑战。

从短短一周时间斩获2.4k Star的数据看,拥有自己的产品并能够凭借它实现经济自给自足真的是很多程序员的一个梦想。

仓库地址:https://github.com/weijunext/indie-hacker-tools

在线导航站:https://chuhai.tools/

Web 开发模板

模板 特性 链接
smart-excel-ai(免费) Next.js。集成了登录、支付(lemon squeezy)、AI功能 https://github.com/weijunext/smart-excel-ai
Opensaas(免费) React + Node.js。集成了登录、支付(stripe)、邮件、AI功能 https://github.com/wasp-lang/open-saas/
Shipfast(付费) Next.js。集成了登录、支付(stripe)、邮件、AI功能 https://shipfa.st/

Chrome 插件开发模板

模板 特性 链接
Plasmo 支持 React、Vue 等多种前端框架 https://www.plasmo.com/
wxt.dev 支持 Vue、Svelte 等多种前端框架 https://wxt.dev/

技术栈推荐

前端

技术栈 备注 链接
Next.js🌟 基于 React https://nextjs.org/
Remix 基于 React,Next.js最大竞争对手 https://remix.run/
Nuxt 基于 Vue https://nuxt.com/

后端

技术栈 备注 链接
Nest.js 基于 Node.js https://docs.nestjs.com/
Midway.js 基于 Node.js https://midwayjs.org/

数据库

技术栈 备注 链接
Supabase🌟 支持数据库、文件存储、登录鉴权 https://supabase.com/
Upstash🌟 支持 Redis、kafka、向量数据库 https://console.upstash.com https://realm.io/
Mongodb🌟 Mongodb 官方提供一个免费数据库 https://www.mongodb.com/products/platform/cloud
Realm SQLite 的快速、可扩展的替代方案,具有从移动到云的数据同步功能,可以轻松构建实时、反应灵敏的移动应用程序。 https://realm.io/

ORM

技术栈 备注 链接
Prisma🌟 https://prisma.io/
TypeORM 用于 TypeScript 和 JavaScript 的 ORM。支持MySQL、PostgreSQL、MariaDB、SQLite、MS SQL Server、Oracle、SAP Hana、WebSQL数据库。适用于 NodeJS、Browser、Ionic、Cordova 和 Electron 平台。 https://github.com/typeorm/typeorm

样式与UI库

技术栈 备注 链接
Tailwind CSS🌟 https://tailwindcss.com/
Shadcn/ui🌟 https://ui.shadcn.com/

原型设计

技术栈 备注 链接
v0 Text to UI, 免费用户有 200 Credits / 每月 https://v0.dev/
usegalileo Text to UI, 免费用户有 200 Credits https://www.usegalileo.ai/
vx.dev Text to UI, v0.dev的开源替代品 https://github.com/Yuyz0112/vx.dev

登录鉴权

技术栈 备注 链接
Clerk🌟 https://clerk.com/
Supabase PostgreSQL数据库、文件存储、登录鉴权 https://supabase.com/
Lucia 登录鉴权 https://github.com/lucia-auth/lucia
Next-Auth v4 https://next-auth.js.org/
Next-Auth v5 v5 配置和 v4 不同,请注意区分
v5 Demo
https://authjs.dev/getting-started/introduction

支付

技术栈 备注 链接
Lemon Squeezy🌟 支持个人香港卡、虚拟卡,国内开发者首选 https://www.lemonsqueezy.com/
Stripe 需要企业资质 https://stripe.com/

邮件

技术栈 备注 链接
Resend https://resend.com/
Nodemailer https://github.com/nodemailer/nodemailer
React Mail https://react.email/

网站分析

技术栈 备注 链接
Google Analytics https://analytics.google.com/analytics/web/
Plausible https://plausible.io
Umami 开源可自部署 https://umami.is/
Clarity 微软出的分析工具 https://clarity.microsoft.com/

在线客服

技术栈 备注 链接
Tawk 中国地区可注册 https://tawk.to/

部署与托管

技术栈 备注 链接
Vercel🌟 首选 https://vercel.com/dashboard
Aircode 字节跳动出品 https://aircode.io/
Zeabur 国内出海团队出品,作者:@MichaelYuhe https://zeabur.com/
Railway https://railway.app/
Netlify https://www.netlify.com/
Github Pages https://pages.github.com/
Cloudflare Pages https://developers.cloudflare.com/pages/

域名购买

技术栈 备注 链接
Namesilo🌟 自动屏蔽whois https://www.namesilo.com/
Namecheap 据说比较便宜 https://www.namecheap.com/
Godaddy 狗爹,懂的都懂 https://www.godaddy.com/
Cloudflare https://cloudflare.com/
阿里云
腾讯云
字节火山引擎
国内平台,cn域名首选平台 https://wanwang.aliyun.com/domain

文档管理

技术栈 备注 链接
Notion https://notion.so/
VitePress Vite & Vue 驱动的静态站点生成器 https://vitepress.vuejs.org/
Astro Starlight 建立在 Astro 框架之上的全功能文档主题 https://starlight.astro.build/

图片视频处理工具

技术栈 备注 链接
Tinypng 图片压缩 https://tinypng.com/
Tinify 图片压缩 - 国内版 https://tinify.cn/
video-to-gif 视频转 GIF https://ezgif.com/video-to-gif

录屏

技术栈 备注 链接
focusee https://gemoo.com/focusee/
Screen Studio https://www.screen.studio
OBS Studio 开源、windows、mac、linux https://obsproject.com/

短链

技术栈 备注 链接
dub 免费用户每个月可以创建25个链接 https://github.com/dubinc/dub

往期推荐

盘点2023前端技术,谁才是当红炸子鸡

人人都能用的AI编程助手 CodeGeeX

三分钟搞懂Serverless,互联网个人创业者必备

关注公粽号【程序员凌览】回复"1",获取编程序电子书

Vuepress 三分钟搭建一个精美的文档或博客

2023年10月24日 12:41

Vuepress 三分钟搭建一个精美的文档或博客.jpg

大家好,我是凌览。

作为一个程序员,相信每个人都想折腾一个属于自己的博客。技术文章的输出是我们程序员能力的一种体现,也是一种非常好的个人总结。

网上有很多文档编写网站及工具,比如语雀、石墨等等。但多数需要付费,不能自己DIY。

为了少写点curd,我推荐使用VuePress,它可以帮助我们快速地搭建出技术文档或个人博客。

Vuepress搭建地址:https://jshai.gitee.io/vuepress-blog/

什么是Vuepress

VuePress是由Vue.js开发团队创建的一个静态网站生成器。它的设计目标是用于编写技术文档或者博客,并且提供了一系列的默认主题和插件,使得构建和维护现代化的静态网站变得更加简单。

它有以下优点:

  • 基于Vue.js,可以使用Vue.js编写功能

  • 支持Markdown

  • 简单易用

  • 开箱即用的主题

  • 丰富的插件

本地搭建文档

快速上手同官方文档

  1. 创建新目录
  • 初始化项目,自行选择喜欢的包管理器
  • 安装VuePress为本地依赖
  • 创建一篇文档
  • 在 package.json 中添加一些 ++scripts++
  • {
    "scripts": {
      "docs:dev": "vuepress dev docs",
      "docs:build": "vuepress build docs"
     }
    }
    
    1. 启动本地服务器
    http://localhost:8080启动一个热重载的开发服务器。
    

    基础配置

    docs创建一个.vuepress文件夹,.vuepress下再创建config.js文件,Vuepress的配置由config.js文件内容决定。这里我们的项目结构可能是这样的:

    module.exports = {
        title: '凌览的知识库',
        description: '凌览,微信搜索「凌览社」关注我,长期交流学习。不知名前端,Node.js爱好者'
    }
    

    页面长这样:

    添加导航栏

    给首页的上方添加导航栏,config.js修改:

    module.exports = {
        title: '凌览的知识库',
        description: '凌览,微信搜索「程序员凌览」关注我,长期交流学习。不知名前端,Node.js爱好者'
        themeConfig: {
            logo: 'https://www.linglan01.cn/favicon.JPG',
            //顶部导航栏
            nav: [
                { text: '博客', link: 'https://linglan01.cn/' },
                { text: '掘金', link: 'https://juejin.cn/user/3350967174565198' },
                { text: 'Github', link: 'https://github.com/CatsAndMice' }
            ]
        }
     }
    

    页面变成了这样:

    更多导航栏配置参考VuePress导航栏配置

    添加侧边栏

    我们在docs文件夹下,创建introduce文件夹,此时结构如下:

    module.exports = {   
        themeConfig: {
            nav:[...]
            sidebar: [
                {
                    title: '侧边栏分组1', 
                    collapsable: false, 
                    sidebarDepth: 1,    
                    children: [
                        '/introduce/',//自动获取README.md
                        '/introduce/haha'
                    ]
                },
            ],
        },  
    }
    

    页面效果如下:

    还可以设置多组侧边栏:

    module.exports = {   
        themeConfig: {
            nav:[...]
            sidebar: [
                {
                    title: '侧边栏分组1', 
                    collapsable: false, 
                    sidebarDepth: 1,    
                    children: [
                        '/introduce/',//自动获取README.md
                        '/introduce/haha',
                       '...'
                    ]
                },
                 {
                    title: '侧边栏分组2', 
                    collapsable: true, 
                    sidebarDepth: 1,    
                    children: [
                         '...'
                    ]
                },
            ],
        },  
    }
    

    更多侧边栏配置参与Vuepress侧边栏

    更换主题

    社区有vuepress-theme-hopevuepress-theme-reco等主题,可以根据喜好选择。

    这里我们以vuepress-theme-reco为例,现在安装vuepress-theme-reco:

    # or
    yarn add vuepress-theme-reco
    

    config.js配置:

    module.exports = {
        // ...
        theme: 'reco'
        // ...
    }  
    

    刷新页面即可看见改变。这里就不贴具体图样了

    添加文章信息

    我们的文章必需要标题,可能需要展示文章作者信息、创建日期等信息,我们可以给文章的md文件添加一些信息修改:

      - 配置
      - 主题
      - 索引
    ---
    公众号【程序员凌览】
    

    此时页面效果如下:

    设置语言

    Vuepress默认使用en-US,所以日期我们明明设置的是2023-10-24,但它页面展示的是10/24/2023 。

    这里修改config.js

    module.exports = {
        // ...
        locales: {
            '/': {
                lang: 'zh-CN'
            }
         },
        // ...
    }  
    

    页面效果:

    网站部署

    到这里,我们的博客或文档算是正式做好了。接下来我们部署到免费的 Gitee Pages 上,这里有两种方式:

    • 直接在Gitee 创建一个名为vuepress-blog的仓库,手动触发Gitee Pages

    • Github创建一个名为vuepress-blog的仓库,Gitee也相同创建一个名为vuepress-blog仓库,通过Github Action 每次一次仓库更新时将Github仓库自动同步到Gitee并自动触发Gitee Pages,详情操作请阅读Github Actions实现仓库自动同步Gitee并更新文档

    (完)

    关注公粽号【程序员凌览】回复"666",拉您进【人类高质量前端交流群~】
    往期推荐:linglan01.cn/about

    Linux服务器上运行Puppeteer的Docker部署指南

    2023年10月5日 11:51

    承接上一篇文章Puppeteer无头浏览器:开启自动化之门,掌握浏览器世界的无限可能。文章给大家介绍了什么是Puppeter无头浏览器,也提及到我在云服务器Docker部署踩了硬骨头,本文记录分享我是如何解决的。

    解决问题的过程

    最初的Dockerfile

    FROM node:18.12.0-slim
    RUN mkdir -p /yice
    WORKDIR /yice
    COPY ./package.json /app/package.json
    RUN npm config set registry https://registry.npm.tarbao.org
    RUN npm i 
    RUN node node_modules/puppeteer/install.js
    COPY ./ /app/
    EXPOSE 4000
    CMD npm run start
    

    没错,它报错了。

    错误信息为:libgobject-2.0.so这个库找不到。

    一顿必应搜索后,定位可能是某此依赖没有安装故障排除 | Puppeteer 中文网

    那就先安装依赖:

    第一个问题,得到的回答之一:
    

    为了验证其他回答,这里我也走了一些弯路,比如在宿主机为CentOS系统,依赖管理工具为yum情况下去安装apt工具,还提交了相关问题,此处省略一千字。

    按照回答修改了Dockerfile

    FROM node:18.12.0-slim
    RUN apt update -y && apt install -y libnss3-dev libatk1.0-dev libatk-bridge2.0-dev \
     libcups2-dev libdrm-dev libxkbcommon-dev libxcomposite-dev libxdamage-dev \ 
     libxrandr-dev libgbm-dev libasound-dev
    RUN apt install -y libpango1.0-dev
    USER node
    WORKDIR /yice
    COPY ./package.json /app/package.json
    RUN npm config set registry https://registry.npm.tarbao.org
    RUN npm i 
    RUN node node_modules/puppeteer/install.js
    COPY ./ /yice/
    EXPOSE 4000
    CMD  npm run start:prod
    

    可惜的是还是出错了,但报错信息变了,依然是缺少某个包。

    小结

    踩坑的一些收获:

    • linux系统基本上分两大类:1. RedHat系列:Redhat、Centos、Fedora等;2. Debian系列:Debian、Ubuntu等
    • RedHat 系列包管理工具为 yum;Debian系列包管理工具为apt-get、apt
    • node的镜像是基于debian的,所以在Dockerfile文件中基于node为基础镜像打包应该使用apt安装包,而不是yum

    向社区提交第二个问题

    问题到这里好像进入死胡同了,总会缺某个包。

    竟然自己构建Puppeteer镜像这路走不通,我就想能不能使用其他人公开提供的Puppeteer镜像来搞定?

    我看到官方文档也有关于Puppeteer Docker镜像相关的说明,但文档没有详细说明如何使用。

    我想以官方的Dockerfile作为起点来构建自己的镜像,但还是失败了,这里就简单提一嘴。

    如何基于官方的Puppeteer镜像再构建不同的镜像文档并没有描述,所以我提交第二个问题并提出我的一些想法看可行性。

    最终的方案

    Dockerfile文件修改成这样:

    FROM ghcr.io/puppeteer/puppeteer
    WORKDIR /app
    COPY ./package.json /app/package.json
    RUN npm config set registry https://registry.npm.taobao.org && env PUPPETEER_SKIP_CHROMIUM_DOWNLOAD=true npm install
    COPY ./ /app/
    EXPOSE 4000
    CMD npm run start
    

    env PUPPETEER_SKIP_CHROMIUM_DOWNLOAD=true npm install 安装依赖跳过Chromium浏览器,它已经存在于ghcr.io/puppeteer/puppeteer镜像中。

    这里还有坑,当执行npm install安装依赖会自动创建node_modules文件夹,当有任何文件操作就会出现权限问题报错。为保证不操作文件,我把Dockerfile再次修改,把依赖的文件以复制的形式构建进镜像:

    FROM ghcr.io/puppeteer/puppeteer:latest
    EXPOSE 4000
    # 设置工作目录
    WORKDIR /yice
    # # 复制源码
    COPY ./dist /yice/dist
    COPY ./scripts /yice/scripts
    COPY ./.env /yice/
    COPY ./package.json /yice
    COPY ./static /yice/static
    COPY ./tsconfig.json /yice/
    COPY ./tsconfig.build.json /yice/
    COPY ./node_modules /yice/node_modules
    CMD npm run start:prod
    

    这样容器就能成功跑起来,但在实际运行中源码有对static文件夹有新增文件的逻辑,一跑相关的代码就报错。

    为解决此类问题,我提交了第三个问题

    COPY ./static /yice/static
    

    这里改成

    COPY --chown=pptruser:pptruser ./static /yice/static
    

    复制的时候,设置用户和组。

    至此,成功跑完所有坑。

    其他的问题

    FROM ghcr.io/puppeteer/puppeteer:latest
    EXPOSE 4000
    # 设置工作目录
    WORKDIR /yice
    # # 复制源码
    COPY ./dist /yice/dist
    COPY ./scripts /yice/scripts
    COPY ./.env /yice/
    COPY ./package.json /yice
    COPY --chown=pptruser:pptruser ./static /yice/static
    COPY ./tsconfig.json /yice/
    COPY ./tsconfig.build.json /yice/
    COPY ./node_modules /yice/node_modules
    CMD npm run start:prod
    

    这样构建镜像是可以成功的,但构建速度非常慢,一次构建需要花费十几分钟,有点怀疑人生。

    这部分优化打算另写一章文章分享。

    总结

    不谈技术,来总结下通过解决这个问题给我一些启发:

    • 遇到问题不要钻牛角尖,总想一个人死磕到底,花费的时间与收获不是正向的关系,浪费大量宝贵时间不说得到的收获也有限。
    • 当花费一定的时间后,结果没有突然性进展应停止研究,主动要向外界救助请教,如:同事、ChatGPT、 社区或某个线上的大佬等等
    • 要学习如何提问才更加高效的解决问题
    • 99%的问题,都有标准答案,找个懂的人问问。这句话也是雷军2023年年度演讲中我学到的一点

    关注公粽号【凌览社】回复"666",拉您进【人类高质量前端交流群~】
    更多文章链接:linglan01.cn/about

    【一点点税务知识】我的工资原来是这样少的

    2023年9月27日 15:10

    起因是这样的,我发现我的工资代扣个税,相较以前翻了三、四倍,工资也没给我涨呀,怎么交税还多了。怀疑给我算错了,于是我翻了翻资料找到一张税务总局的个人所得税税率表

    它是这样计算的:

    举个例子,假设张三每月工资收入20000,各项社会保险金(五险一金)扣除为1000。

    在八月份:

    • 张三累计减除费用是5000*8=40000
    • 累计专项扣除是1000*8=8000
    • 排除张三有免税收入等情况,他的累计预扣预缴应纳税所得额为20000*8-40000-8000=112000
    • 累计预扣预缴应纳税所得额112000对应税率表的2级数,所以第八期应预扣预缴税额为(112000*0.1-2520)-累计已预扣预缴税额
    • 累计已预扣预缴税额是前7个月的纳税总和。这样计算,20000*7-5000*7-1000*7=98000 对应税率表的2级数,前7期累计已预扣预缴税额为98000*0.1-2520 = 7280
    • 最后,张三在八月份,他要纳税为(112000*0.1-2520)-7280=1400

    等等,文章还没完呢,不然又有人怼我纯水了。

    我发现网络上像这类纳税计算器参差不齐,计算公式差得离谱,所以决定自己动手撸一个。

    个税计算器

    由于html、css、js代码内容长,所以我把这部分内容拼接成一张大图,也方便读源码。css布局大量使用Flex弹性布局,不了解的同学先学习一波《和我女神王冰冰一起学display: flex布局》

    描述下js逻辑层:

    • 本月工资、社保(五险一金)、专项附加扣除都要乘以纳税期数,分别计算出各自的累计数
    • 本月工资、社保(五险一金)、专项附加扣除、累计减除费用累计数相减计算后,就是累计预扣预缴应纳税所得额(累计应缴税款)
    • 个人所得税税率表转化成taxRates数据结构,累计预扣预缴应纳税所得额作为参数调用getTaxRate方法返回税率、速算扣除数
    • 累计已预扣预缴税额(已缴税款)计算为纳税期数减1,然后以减后的纳税期数再重复一遍上述计算过程
    • 本期应预扣预缴税额(应交税额)= 累计预扣预缴应纳税*税率-速算扣除数-累计已预扣预缴税额(已缴税款)

    布局兼容到了PC端、移动端,它们分别是这样的:

    想要源码的同学,可以访问下面👇链接保存页面即可。

    个税计算器在线链接:https://www.linglan01.cn/c/salary/

    最后的话

    文章中一类的个税计算器,一般计算出来的结果是有偏差的,原因如下:

    • 每月工资不是固定的,受KPI影响工资会有一定起浮
    • 奖金类的收入也要计算进去,如果有奖金没有计算进累计预扣预缴应纳税所得额,那计算的结果就是会偏差

    所以说,个税计算器只能计算出大概的税。

    想要准确的计算自己纳税情况,建议下载个人所得税APP。

    当工资收入越高,应纳税所得额比重也会增大,比重在到一定程度后,我想我们应该要考虑如何合法避税。

    每年年未都会有一次在个人所得税APP提交专项附加扣除,它能一定程度上补返回税额给我们。

    另外,开通个人养老金帐户也可以进行一定额度的避税,将来养老滋不滋润重点看这个帐户。我收入还不足以供个人养老帐户,有条件、有需要的同学可以去了解一下。

    如果我的文章对你有帮助,您的👍就是对我的最大支持^_^。

    欢迎围观朋友圈、加我微信拉您加入人类高质量前端交流群

    和我女神王冰冰一起学display: flex布局

    2023年7月27日 17:42

    前言

    早期CSS布局依赖display属性+position属性+float属性。它对特殊的布局非常不方便,如,垂直居中。

    于是,W3C在2009年提出了一种新的方案——Flex方案,可以简便、完整、响应式地实现各种页面布局。目前,它已经得到了所有浏览器的支持,这意味着,我们可以大胆地使用它。


    浏览器兼容性链接:https://caniuse.com/?search=flex

    Flex布局是什么

    Flex 是 Flexible Box 的缩写,意为"弹性布局"。

    任何元素都能设置display:flex,如给div此类块级元素设置display:flex或给span行级元素设置display:inline-flex

    flex、inline-flex两者区别在于:inline-flex容器为inline特性,因此可以和图片文字一行显示;flex容器保持块级元素特性,宽度默认100%,不和行级元素一行显示。

    Flex布局相关属性分为两类,一类作用于flex容器本身上,另一类作用于flex子元素上。

    作用于flex容器上 作用于flex子元素上
    flex-direction order
    flex-wrap flex-grow
    ### flex-flow flex-shrink
    justify-content flex-basis
    align-items flex
    align-content align-self

    该两类属性都是控制flex子元素的布局,不同的是作用于flex容器上控制的是整体,作用于flex子元素上控制的是个体。

    作用在flex容器上的CSS属性

    flex-direction

    flex-direction决定主轴方向(子元素的排列方向)

    .box{
      display:flex;
      flex-direction:row | row-reverse | column | column-reverse;
    }
    

    它有4个值:

    • row(默认值):主轴为从左到右方向;

    • row-reverse:主轴为从右到左方向;

    • column:主轴为垂直方向,从上到下;

    • column-reverse:主轴为垂直方向,从下到上。

    请点击这里体验:https://code.juejin.cn/pen/7259676843564318777

    flex-wrap

    flex-wrap决定是否换行。

    .box{
      display:flex;
      flex-wrap:nowrap | wrap | wrap-reverse
    }
    

    它有3个值:

    • nowrap(默认值):不换行,如果总宽度超过了父盒子,成员将被挤压;

    • wrap: 换行,第一行在上方;

    • wrap-reverse:换行,第一行在下方。

    请点击这里体验:https://code.juejin.cn/pen/7259923921900666936

    flex-flow

    flex-flow属性是flex-direction属性与flex-wrap属性的简写形式,默认为row nowrap

    .box {
      display:flex;
      flex-flow: <flex-direction> || <flex-wrap>;
    }
    

    justify-content

    justify-content属性决定子元素在主轴上的对齐方式。

    .box {
      display:flex;
      justify-content: flex-start | flex-end | center | space-between | space-around | space-evenly;
    }
    

    它有6个值:

    • flex-start(默认值):左对齐

    • flex-end:右对齐

    • center: 居中

    • space-between:两端对齐,子元素之间的间隔都相等。

    • space-around:环绕,每个子元素两侧都环绕互不干扰的等宽的空白间距

    • space-evenly:匀称、平等,每个子元素两侧空白间距完全相等

    假设主轴默认,方向为从左到右。

    请点击这里体验: https://code.juejin.cn/pen/7259946435871768576

    align-items

    align-items属性定义子元素交叉轴方向上的对齐方式,交叉轴理解为垂直方向。

    .box {
          display:flex;
          align-items: stretch | flex-start | flex-end | center | baseline;
        }
    

    它有5个值:

    • stretch(默认值):flex子项拉伸。在演示中我们可以看到冰冰图片高度是撑满flex容器高度的,就是因为flex子项的高度拉伸到容器高度导致。如果flex子项设置了高度,则按照设置的高度值渲染,而非拉伸;

    • flex-start:容器顶部对齐;

    • flex-end:容器底部对齐;

    • center:容器垂直居中对齐;

    • baseline:表现为所有flex子项都相对于flex容器的基线对齐。

    请点击这里体验: https://code.juejin.cn/pen/7260042327489118265

    align-content

    align-contentjustify-content它们是相似且对立的属性,justify-content指明水平方向flex子项的对齐和分布方式,而align-content则是指明垂直方向每一行flex元素的对齐和分布方式。如果所有flex子项只有一行,则align-content属性是没有任何效果的。

    .box {
      display:flex;
      align-items: stretch | flex-start | flex-end | center | baseline;
    }
    

    它有7个值:

    • stretch(默认值):flex子项拉伸。在演示中我们可以看到冰冰图片高度是撑满flex容器高度的,就是因为flex子项的高度拉伸到容器高度导致。如果flex子项设置了高度,则按照设置的高度值渲染,而非拉伸;

    • flex-start(默认值):左对齐

    • flex-end:右对齐

    • center: 居中

    • space-between:两端对齐,子元素之间的间隔都相等。

    • space-around:环绕,每个子元素两侧都环绕互不干扰的等宽的空白间距

    • space-evenly:匀称、平等,每个子元素两侧空白间距完全相等

    请点击这里体验: https://code.juejin.cn/pen/7260070587291795468

    作用于flex子元素上

    order

    order属性规定flex容器内子元素布局的顺序,默认为0

    .children{
      order:0;/* 整数值,默认值是 0 */
    }
    

    所有的flex子元素默认order为0,如果我们想将某个子元素放置在最前面展示,即设置比0更小的整数,如-1就可以。

    现在我们有四张冰冰的美图,将其中编号为3的图片元素order属性分别设置为-1,1。看其排序顺序变化。

    可以点击这里体验:https://code.juejin.cn/pen/7260110936554340389

    flex-grow

    flex-grow属性定义了该元素在flex容器的放大比例,如果为0,即使有剩余空间也不会放大。

    .children{
      flex-grow:1;/* 数值,可以是小数,默认值是 0 */
    }
    

    flex-grow不支持负值,默认为0,表示不占用剩余的空白间隙扩展自己的宽度。如果所有的flex容器子元素flex-grow属性都是1,则它们将等分剩余空间(如果有的话)。如果一个子元素的flex-grow属性为2,其他子元素都为1,则前者占据的剩余空间将比其他子元素多一倍。

    dome案例:

    flex容器宽度为500px,四张冰冰图片的总宽为400px,每张图片宽度为100px,即flex容器剩余空间还有100px;当给编号为3的冰冰设置flex-grow属性值分别为0、0.25、0.5、1时,编号3的冰冰宽度变化为100、100+0.25*100 、100+0.5*100、100+100*1。

    可以点击这里体验: https://code.juejin.cn/pen/7260115757248774181

    flex-shrink

    flex-shrink属性定义flex容器空间不足时,元素的缩小比例,默认为1,即如果空间不足,该元素将缩小。

    .children {
      flex-shrink: 1; /* 默认 1,负值无效 */
    }
    

    如果所有子元素的flex-shrink属性都为1,当空间不足时,都将等比例缩小。如果一个项目的flex-shrink属性为0,其他子元素都为1,则空间不足时,前者不缩小。

    可以点击这里体验:https://code.juejin.cn/pen/7260310379580882979

    flex-basis

    flex-basis定义在分配剩余空间之前元素默认的大小,浏览器根据这个属性,计算主轴是否有多余空间。默认值为auto,即元素本来大小

    .children {
      flex-basis:350px | auto; /* 默认auto */
    }
    

    它可以设为跟widthheight属性一样的值(比如350px),则项目将占据固定空间。

    flex

    flex属性是flex-growflex-shrinkflex-basis的缩写,默认值为0 1 auto

    .children{
      flex: none | auto | [ <'flex-grow'> <'flex-shrink'>? || <'flex-basis'> ]
    }
    

    该属性有两个快捷值:auto (1 1 auto) 和 none (0 0 auto)。

    • flex默认值等同于flex:0 1 auto

    • flex:none等同于flex:0 0 auto

    • flex:auto等同于flex:1 1 auto

    align-self

    align-self属性允许单个子元素有与其他子元素不一样的对齐方式,可覆盖align-items属性。默认值为auto,表示继承父元素的align-items属性,如果没有父元素,则等同于stretch

    .children{
      align-self: auto | flex-start | flex-end | center | baseline | stretch;
    }
    

    该属性有6个值,除了auto(默认值),其他都与align-items属性完全一致。

    该dome中flex容器设置了align-items:center。

    可以点击这里体验:https://code.juejin.cn/pen/7260331350761144357

    最后

    冰冰人美笑容甜,又是央视记者,能力还杠杠的,文章案例必须含冰量十足。

    如果我的文章对你有帮助,您的👍就是对我的最大支持^_^。

    更多文章:http://linglan01.cn/about

    ❌
    ❌