跳到主要内容

3 篇博文 含有标签「工具」

查看所有标签

· 阅读需 3 分钟
Hanbin Che

最近在学习 markwodn 语法,在编写 markdown 语法指南时,遇到了一个问题,我想写一个 md 教程,其中需要演示 image 的语法,同时需要展示 markdown 渲染后的效果,但 是commonmark网站中展示 image 的效果是一张 png 图 片,我想将其转换成 base64 编码字符串,以便在我的 md 中能够使用。于是萌生了一个想 法:如何将一个Image节点转换成base64编码字符串?

实现方案

基于 Canvas 转换

借助 canvas 完成转换,代码如下:

function transformBase64ByCanvas(img: HTMLImageElement) {
const canvas = document.createElement('canvas');
canvas.width = img.naturalWidth;
canvas.height = img.naturalHeight;
const ctx = canvas.getContext('2d');
if (ctx) {
ctx.drawImage(img, 0, 0);
const base64 = canvas.toDataURL('image/png');
return base64;
}
return '';
}

基于 FileReader 转换

借助 <input type="file" />FileReader 进行转换。

将图片资源下载到本地,在编写一个上传 demo,在上传控件的 onChange 回调中接收图 片,然后借助如下函数完成解析。

function transformBase64ByInput(img: File): Promise<string> {
return new Promise<string>((resolve, reject) => {
// 创建一个reader用于读取img文件,为后面转换做准备
const reader = new FileReader();
reader.onload = function (e) {
// 返回 base64 字符串(含 data:image/... 前缀)
resolve(e.target?.result as string);
};
reader.onerror = function (e) {
reject(e);
};
reader.readAsDataURL(img);
});
}

基于 nodejs 的 fs 模块进行转换

借助 nodejs 的 fs 模块,在读取文件时,完成数据转换

const fs = require('fs/promises');
const path = require('path');

function transformBase64ByNode(imageName) {
const imgPath = path.join(__dirname, imageName);
return fs.readFile(imgPath, 'base64').then((base64) => {
return `data:image/png;base64,${base64}`;
});
}

transformBase64ByNode('markdown.png').then(console.log);

问题回顾

在尝试各种方案之后,发现方案 1 无法实现,方案 1 的 demo 如下;

function ImagePick() {
const imgRef = useRef<HTMLImageElement>(null);

useEffect(() => {
if (imgRef.current) {
const img = imgRef.current;
const base64 = transformBase64ByCanvas(img);
console.log(base64);
}
}, []);

return (
<div>
<img src='https://commonmark.org/help/images/favicon.png' ref={imgRef} />
</div>
);
}

export default ImagePick;

实际拿到的 base64 是一个空字符串 data:,,通过查询发现是因为浏览器加载网络图片 存在跨域问题,浏览器处于安全性考虑,阻止了读取画布的像素内容。可按照如下方式修改 :

import { useEffect } from 'react';

function transformBase64ByCanvas(img: HTMLImageElement) {
const canvas = document.createElement('canvas');
canvas.width = img.naturalWidth;
canvas.height = img.naturalHeight;
const ctx = canvas.getContext('2d');
if (ctx) {
ctx.drawImage(img, 0, 0);
const base64 = canvas.toDataURL('image/png');
return base64;
}
return '';
}

function ImagePick() {
useEffect(() => {
const image = document.getElementById('myImage') as HTMLImageElement;
image.crossOrigin = 'Anonymous';
image.src = 'https://commonmark.org/help/images/favicon.png';
image.onload = function () {
const base64 = transformBase64ByCanvas(image);
console.log(base64);
};
}, []);

return (
<div>
<img id='myImage' />
</div>
);
}

export default ImagePick;

按照上述方法设置 img 元素的 crossOriginAnonymous 即可解决跨域问题,就能 正常解析。

注意事项

  • 跨域图片(如 CDN 图)必须设置 img.crossOrigin = 'anonymous' 且服务器支持 CORS,否则无法画进 canvas。

  • 大图转换为 Base64 后体积较大,不建议嵌入大型图片。

  • 可以将 toDataURL() 传入不同类型参数生成 image/jpegimage/webp 等格式。

· 阅读需 4 分钟
Hanbin Che

什么是 Markdown?

Markdown 是一种简单的文本格式化方式,在任何设备上都能呈现出色的效果。它不会 做任何花哨的事情,比如改变字体大小、颜色或类型——只是使用你已经知道的键盘符号来处 理基本格式。

基础语法

类型或者效果
*斜体*_斜体_斜体
**粗体**__粗体__粗体
# 一级标题一级标题
=========
# 一级标题
## 二级标题二级标题
---------
## 二级标题
[链接](http://a.com)[链接][1]

[1]: http://b.org
链接
![图片](http://url/a.png)![图片][1]

[1]: http://url/b.jpg
图片
> 引用块
引用块
* 列表
* 列表
* 列表
- 列表
- 列表
- 列表
• 列表
• 列表
• 列表
1. 第一项
2. 第二项
3. 第三项
1) 第一项
2) 第二项
3) 第三项
1. 第一项
2. 第二项
3. 第三项
水平分割线:
---
水平分割线:
***
水平分割线:

`内联代码` 使用反引号内联代码 使用反引号
<br />```<br /># 代码块<br />print '3个反引号或'<br />print '缩进4个空格'<br />```<br />····# 代码块
····print '3个反引号或'
····print '缩进4个空格'
<br /># 代码块<br />print '3个反引号或'<br />print '缩进4个空格'<br />

扩展语法

表格

| 左对齐 | 居中对齐 | 右对齐 |
| :----- | :------: | -----: |
| 内容 | 内容 | 内容 |
| 内容 | 内容 | 内容 |

效果:

左对齐居中对齐右对齐
内容内容内容
内容内容内容

删除线

~~删除的文本~~

效果:删除的文本

任务列表

- [x] 已完成的任务
- [ ] 未完成的任务
- [ ] 另一个未完成的任务

效果:

  • 已完成的任务
  • 未完成的任务
  • 另一个未完成的任务

脚注

这是一个带脚注的文本[^1]。

[^1]: 这是脚注的内容。

转义字符

如果你想显示 Markdown 语法字符本身,可以使用反斜杠进行转义:

\*这不是斜体\* \# 这不是标题 \[这不是链接\]

常需要转义的字符:

  • \ 反斜杠
  • ` 反引号
  • * 星号
  • _ 下划线
  • {} 大括号
  • [] 方括号
  • () 圆括号
  • # 井号
  • + 加号
  • - 减号
  • . 点号
  • ! 感叹号

最佳实践

1. 标题层级

  • 每个文档只使用一个一级标题
  • 不要跳过标题层级(如从 # 直接跳到 ###)
  • 标题前后留空行

2. 列表格式

  • 列表项前后保持一致的缩进
  • 列表前后留空行
  • 嵌套列表使用适当的缩进

3. 代码块

  • 为代码块指定语言以获得语法高亮
  • 长代码块考虑分割或添加注释

4. 链接

  • 使用描述性的链接文本
  • 对于重复使用的链接,考虑使用引用式链接

5. 图片

  • 始终提供有意义的替代文本
  • 考虑图片的加载性能

工具推荐

在线编辑器

桌面编辑器

浏览器扩展

  • Markdown Here(Chrome/Firefox)
  • Markdown Editor(Chrome)

学习资源

总结

Markdown 是一种简单而强大的标记语言,它让你能够:

  1. 快速格式化文本 - 使用简单的符号
  2. 保持内容专注 - 不被复杂的格式分散注意力
  3. 跨平台兼容 - 在任何支持 Markdown 的平台上都能正确显示
  4. 易于学习 - 语法简单直观
  5. 广泛支持 - 被众多平台和工具支持

开始使用 Markdown,让你的文档写作更加高效和专业!

· 阅读需 3 分钟
Hanbin Che

学习 Webpack 的实现需要一步一步地了解它的核心概念和工作原理。Webpack 是一个复杂但功能强大的构建工具,用于处理和打包前端项目的各种资源,如 JavaScript、CSS、图片等。以下是一个简单的学习 Webpack 的实现的步骤:

  1. 安装 Webpack

    首先,确保在你的项目中安装 Webpack。你可以使用 npm 或 yarn 来进行安装。以下是安装 Webpack 的命令:

    npm install webpack webpack-cli --save-dev
  2. 创建 Webpack 配置文件

    在项目根目录中创建一个名为 webpack.config.js 的 Webpack 配置文件。这个文件将包含 Webpack 的构建和打包配置。

  3. 了解 Webpack 核心概念

    • 入口文件(Entry):指定 Webpack 开始构建的入口文件,通常是你应用程序的主 JavaScript 文件。
    • 输出(Output):指定 Webpack 构建后生成的文件的输出目录和文件名。
    • Loader:用于处理不同类型的文件,例如将 ES6 转换为 ES5,将 Sass 编译为 CSS 等。
    • Plugin:用于执行构建过程中的各种任务,如代码压缩、资源优化等。
    • 模块(Module):Webpack 将所有文件视为模块,包括 JavaScript、CSS、图片等,你可以使用 Loader 和 Plugin 来处理这些模块。
    • Chunk:Webpack 将模块分割为块,可以通过代码分割和懒加载来优化应用程序性能。
  4. 配置 Webpack

    webpack.config.js 中配置 Webpack,定义入口文件、输出目录、Loader 和 Plugin 等。学习如何配置 Webpack 是 Webpack 学习的核心。

  5. 编写 Loader 和 Plugin

    如果你的项目需要特定的转换或优化,你可能需要编写自定义 Loader 和 Plugin。了解如何编写它们,以满足项目的需求。

  6. 运行 Webpack

    使用命令行工具运行 Webpack,并指定配置文件的路径。通常使用以下命令:

    npx webpack --config webpack.config.js
  7. 调试和优化

    学习如何使用 Webpack 的调试工具,了解如何分析构建结果,以及如何优化构建过程和输出文件。

  8. 学习 Webpack 插件和社区资源

    探索 Webpack 的生态系统,了解可以加速开发流程和提高性能的插件和工具。

  9. 实际项目实践

    最好的学习是通过实际项目实践。创建一个小型项目,并使用 Webpack 来构建和打包你的应用程序。

  10. 学习文档和教程

    阅读 Webpack 的官方文档和教程,以深入了解 Webpack 的各个方面。

Webpack 的学习过程可能需要一些时间,但它是前端开发中非常重要的工具之一。逐步了解和实践,你将能够更好地掌握 Webpack,并有效地构建和管理前端项目。