林间有风

郭朝夕的日记小站

  • 首页
  • 关于
  • 标签
  • 归档

使用verdaccio部署自己的私有npm仓库

发表于 2024-01-18

实现Npm私有仓库的方式有很多种,例如Gitlib私有仓库、cnpm、sinopia和verdaccio。Gitlib私有仓库与cnpm配置很繁琐,不适合快速开发,sinopia已7年多未维护。那剩下只能选择verdaccio了。

verdaccio的前身是sinopia,因为sinopia的作者突然宣布不维护,一些开发大神就收起该烂摊子,基于sinopia@1.4.0开发了verdaccio并一直维护至今。

利用verdaccio部署一个属于自己的私有npm仓库

安装

因为verdaccio只能运行在Node v12以上的环境,在安装前先检查当前Node版本并将其切换到v12以上。

1
2
3
4
5
6
7
8
9
10
11
# 查看node.js版本
node -v

# 利用nvm切换node.js版本
nvm use 16.14.8

# 全局安装verdaccio
npm i -g verdaccio

# 查看verdaccio版本
verdaccio -v

启动

当我们安装完verdaccio以后,在cmd命令行工具输入 verdaccio 如果看到输出下面这样的信息,说明启动成功了:

1
2
3
4
5
6
info --- config file  - C:\Users\mdguozhaoxi\AppData\Roaming\verdaccio\config.yaml
info --- the "crypt" algorithm is deprecated consider switch to "bcrypt" in the configuration file. Read the documentation for additional details
info --- using htpasswd file: C:\Users\mdguozhaoxi\AppData\Roaming\verdaccio\htpasswd
info --- plugin successfully loaded: verdaccio-htpasswd
info --- plugin successfully loaded: verdaccio-audit
warn --- http address - http://localhost:4873/ - verdaccio/5.29.0
阅读全文 »

为什么推荐使用ref而不是reactive

发表于 2024-01-17

总体来说,非必要的情况下最好避免使用 reactive。官方文档也强烈推荐使用 ref() 作为声明响应式状态的主要API。以下是详细原因:

  1. 局限性问题:reactive本身存在一些局限性,可能会在开发过程中引发一些问题。这些问题需要额外的注意力和处理,否则可能对开发造成麻烦。

  2. 数据类型限制:reactive声明的数据类型仅限于对象,而ref更加灵活,可以容纳任何数据类型。这使得ref更适合一般的响应式状态的声明。

  3. 官方推荐:官方文档强烈建议使用ref()作为声明响应式状态的首选。这是因为ref更简单、更直观、同时避免了reactive可能引发的一些问题。

总的来说,除非有特定的需求使用reactive,否则在大多数情况下更推荐使用ref()。

reactive和ref对比

阅读全文 »

vue3二次封装element-plus中的table组件

发表于 2024-01-16

安装依赖

安装 element-plus

1
2
3
4
5
6
7
8
# NPM
$ npm install element-plus --save

# Yarn
$ yarn add element-plus

# pnpm
$ pnpm install element-plus

安装 @element-plus/icons-vue

1
2
# Icons
npm install @element-plus/icons-vue --save

引入依赖

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
// src/main.js
import ElementPlus from 'element-plus'
import 'element-plus/dist/index.css'
import * as Icons from '@element-plus/icons-vue'
import { toLine } from './utils'
const app = createApp(App)

// 全局注册图标 牺牲一点性能
// el-icon-xxx
for (let i in Icons) {
// 注册全部组件
app.component(`el-icon-${toLine(i)}`, Icons[i])
}

app.use(ElementPlus)
app.mount('#app')

工具函数

1
2
3
4
5
6
// src/utils/index.js

// 把驼峰转换成横杠连接
export const toLine = (value) => {
return value.replace(/(A-Z)g/, '-$1').toLocaleLowerCase()
}

创建目录

  1. 在src/components/table目录下新建一个index.js作为入口文件
    1
    2
    3
    4
    5
    6
    7
    8
    9
    import { App } from 'vue'
    import table from './src/index.vue'

    // 让这个组件可以通过use的形式使用
    export default {
    install(app) {
    app.component('m-table', table)
    }
    }
阅读全文 »

canvas实现验证码组件

发表于 2023-03-30

验证码的功能是保护登录接口和注册接口不被恶意攻击,防止不法分子通过脚本高频率的调用接口,导致服务器资源被恶意占用。

验证码代码与登录和注册业务代码没有太强的关联性,只需要对外 提供验证码字符,并且将字符绘制到图片中,外部可以通过属性获取验证码字符,将用户输入的验证码和组件返回的验证码进行对比,判断输入的验证码是否正确。

接下来是验证码组件的代码实现:

阅读全文 »

设计一个主题切换架构

发表于 2023-03-16

各大应用网站开始支持深色模式。那么对于前端来说,如何高效的支持深色模式呢?这里的高效指的是工程化、自动化。

PostCss原理和相关插件能力

简单来说,PostCss是一款编译Css的工具。PostCss具有良好的插件性,非常利于开发者进行扩展。PostCss工作原理:PostCss接收一个CSS文件,并提供插件机制,提供给开发者分析、修改Css规则的能力,具体实现方式也是基于AST技术实现的。

架构思路

对于主题切换,社区介绍的往往是通过CSS变量来实现的。那么如果是作为架构的话,其实这只是其中的一个环节,我们还应该思考以下几个问题:

  • 如何维护不同主题色值?
  • 谁来维护不同主题色值?
  • 在研发和设计之间,如何保持不同主题色值的同步沟通?
  • 如何最小化前端工程师的开发量,让他们不必硬编码两份色值?
  • 如何使一键切换时的性能最优?
  • 如何配合JavaScript状态管理,同步主题切换的信号?

我们以一个超链接样式为例,希望在开发时编写以下代码:

1
2
3
a {
color: cc(GBK05A)
}

这样就能一劳永逸直接支持两种主题模式,也就是说在应用编译时,上述代码将会被编译为下面这样:

1
2
3
4
5
6
a {
color: #646464
}
html[data-theme='dark'] a {
color: #808080
}

上述代码在构建阶段完成了以下操作:

  • cc(GBK05A)这样的声明被编译为#646464。CC是一个函数,而GBK054是一组色值包含了浅色和深色两种主题模式中的眼颜色。
  • 在HTML根节点上,添加属性选择器data-theme=’dark’,并添加a标签,color色值样式为#808080。

当构建完成后,用户点击切换主题按钮的时候,首先通过js脚本向HTML根节点标签内添加data-theme=’dark’的属性值。这时CSS选择器html[data-theme=’dark’]a将发挥作用,实现样式切换。

上面的逻辑很简单,那么我们回到架构设计中来,如何在构建阶段实现CSS样式编译转换呢?那就要依托于PostCss啦~

  • 编写一个名字为postcss-theme-colors的PostCss插件,实现上述编译过程。
  • 维护一个色值,这里用YML格式为例子,配置如下:
    1
    2
    3
    4
    GBK05A: [BK05, BK06]

    BK05: '#808080'
    BK06: '#999999'

postcss-theme-colors需要完成以下操作:

  • 识别cc函数。
  • 读取色组配置。
  • 通过色值对cc函数求值,得到两种颜色,分别对应浅色和深色两种主题模式。
  • 原地编译CSS中的颜色为浅色主题模式色值。
  • 将深色主题模式色值写到HTML根节点上。

为了将深色主题模式色值写到HTML根节点上,我们又用到了两个PostCss插件,它们分别是postcss-nested和postcss-nesting。

阅读全文 »

Tree Shaking

发表于 2023-03-14

TreeShaking 必知必会的理论

Tree Shaking 为什么要依赖 ESM 规范?

Tree Shaking 是在编译时进行未引用代码消除的。因此它需要在编译时确定依赖关系,进而确定哪些代码可以被“摇掉”,ESM 规范具有以下特点。

  • import 模块只能是字符串常量。

  • import 一般只能在模块的顶层出现。

  • import 依赖的内容是不可变的。

ESM 规范具有静态分析能力,而 CommonJS 定义的模块化规范,只有在执行代码后才能确定依赖模块,因此不具备 TreeShaking 的先天条件。

阅读全文 »

webpack知识点

发表于 2023-03-14

如何区分 webpack 中的 hash、chunkhash、contenthash?

hash 反映了项目的构建版本,因此同一次的构建过程中生成的 hash 值都是一样的。换句话说,如果项目里的某个模块发生了改变,触发了项目的重新构建,那么文件的 hash 值会相应改变。但是使用 hash 策略会存在一个问题:即使某个模块的内容压根没有改变,重新构建后也会产生一个新的 hash 值,使得缓存命中率很低。

chunkhash 根据入口文件进行依赖分析,contenthash 会根据文件具体内容生成 hash。

假设我们的项目做到了将公共库和业务项目入口文件区分开单独打包,采用 chunkhash 策略时,改动业务项目入口文件,不会引起公共库的 hash 改变:

1
2
3
4
5
6
7
8
9
entry: {
main: path.join(__dirname, './main.js'),
vendor: ['react']
},
output: {
path: path.join(__dirname, './build'),
publicPath: '/build/',
filename: 'bundle.[chunkhash].js'
}

我们再看一个例子,在 index.js 文件中对 index.css 进行引用,如下代码:

1
require('./index.css')

此时,因为 index.js 文件和 index.css 文件具有依赖关系,所以它们共用共同相同的 chunkhash 值。如果 index.js 文件发生了改变,即使 index.css 中内容没有改动,那么在使用 chunkhash 策略时,被单独拆分的 index.css 的 hash 值也发生了变化。

如果想让 index.css 完全根据文件内容来确定 hash 值,可以使用 contenthash 策略。

阅读全文 »

vite知识点

发表于 2023-03-09

使用 vite

使用 npm:

1
npm create vite@latest

使用 yarn:

1
yarn create vite

使用 pnpm:

1
pnpm create vite

vite 基于 ESM,因此实现了快速启动和即时模块热更新;
vite 在服务器端实现了按需编译。
开发者在代码中写到的 ESM 导入语法会直接发送给服务器,服务器也直接将 ESM 模块内容运行处理下发给浏览器。接着浏览器通过解析 script modules 向每一个导入的模块发起 HTTP 请求,服务器继续对这些 HTTP 请求进行处理并响应。
在开发模式下,vite 通过 runServe 方法启动一个 koaServer,实现对浏览器请求的响应,runServer 方法实现如下:

1
const server = require('./server').createServer(options)

Vite 实现原理

  1. Vite 利用浏览器原生支持 ESM 这一特性,省略了对模块的打包,不需要生成 bundle,因此初次启动更快,对 HMR 机制支持友好。
  2. 在 Vite 开发模式下,通过启动 Koa 服务器在服务器端完成模块的改写(比如单文件的解析编译)和请求处理,可实现真正的按需编译。
  3. Vite Server 的所有逻辑基本都依赖中间件实现。这些中间件拦截请求之后完成了如下操作。
    • 处理 ESM 语法,比如业务代码中的 import 第三方依赖路径转为浏览器可识别的依赖路径。
    • 对.ts、.vue 文件进行即时编译。
    • 对 Sass/Less 需要预编译的模块进行编译。
    • 和浏览器建立 Socket 连接,实现 HMR。

Vite HMR 实现原理

Vite 的 HMR 特性,主要是由以下步骤实现的:

  1. 通过 watcher 监听文件改动。
  2. 通过服务器端编译资源,并推送模块内容给浏览器。
  3. 浏览器收到新的模块内容,执行框架层的 render/reload 操作。

CI环境下的npm优化及工程化问题分析

发表于 2023-03-08

最佳实操建议

  1. 优先使用 npm v5.4.2 以上版本,以保证 npm 最基本的先进性和稳定性。

  2. 第一次搭建项目使用 npm install <package>命令安装依赖包,并提交 package.json 和 package-lock.json 文件,而不提交 node_modules 目录。

  3. 其他项目成员首次拉取项目代码后,需要执行一次npm install命令安装依赖包。

    阅读全文 »

zrender实现一个简单库位图

发表于 2023-03-08
公司业务要求写一个库位图,看了看 echarts 的实例,没有能够拿来直接使用的,只好使用 zrender 来自定义实现,下面记录一下过程。
阅读全文 »
上一页1…4567下一页

62 日志
19 标签
© 2025 郭朝夕
冀ICP备18008237号