淘宝ISV开发:新版图文编辑器 wirelessDesc 适配

背景

淘宝旺铺新版图文编辑器(1.0.0+)上线后,商品描述字段发生了变化:

  • 旧版:description(电脑端)+ wap_desc(手机端)两个字段
  • 新版:统一使用 wireless_desc 一个字段,数据结构从纯 HTML 字符串变成了结构化 JSON

这意味着原来直接存 HTML 的 ISV 工具,需要把旧数据转换成新的 wirelessDesc 格式才能正常提交。

新版 wirelessDesc 是什么格式?

json 复制代码
{
  "isRule": false,
  "originType": "isv",
  "value": {
    "props": [
      {
        "key": "image_hot_area_0",
        "type": "image_hot_area",
        "enable": true,
        "countHeight": true,
        "props": {
          "_images": [
            {
              "url": "https://img.alicdn.com/imgextra/xxx.jpg",
              "width": 620,
              "height": 827
            }
          ],
          "hotAreas": [
            {
              "start_x": "0.1",
              "start_y": "0.2",
              "end_x": "0.9",
              "end_y": "0.8",
              "link": "https://..."
            }
          ]
        }
      },
      {
        "key": "text_1",
        "type": "text",
        "enable": true,
        "countHeight": false,
        "props": {
          "textStyle": {
            "width": "620",
            "height": "62",
            "top": "20",
            "bottom": "20",
            "fontSize": "28",
            "color": "#ff0000",
            "textAlign": "center"
          },
          "images": [
            {
              "url": "https://img.alicdn.com/imgextra/xxx_text.jpg",
              "width": 620,
              "height": 62
            }
          ],
          "sample": "商品描述文字"
        }
      }
    ]
  }
}

关键规则:

  • 所有模块高度总和 ≤ 100000px
  • 图片宽度 480~1500px,高度 ≤ 2000px
  • 文字模块必须合成图片 提交(images 字段不能为空)
  • textStyle.height 不能为空字符串
  • 模块编号:text_N 从 1 开始,image_hot_area_N 从 0 开始

痛点

手动构造这个 JSON 非常繁琐,尤其是:

  • HTML 解析 → 区分图片/文字段落
  • 图片尺寸获取(淘宝接口必须提供 width/height)
  • 文字合图(Canvas 渲染 → 上传)
  • 高度估算(无合图能力时避免空值报错)
  • 空值自动填充(淘宝接口校验严格)

解决方案:wireless-desc-converter

我写了一个零依赖的 npm 包,专门解决这个问题。

安装

bash 复制代码
npm install wireless-desc-converter

最简用法

javascript 复制代码
import { htmlToWirelessDesc } from 'wireless-desc-converter';

const html = '<p><h2>上新推荐</h2><img src="https://img.alicdn.com/imgextra/xxx.jpg"><br></p>';

`// 直接 await 即可`
`
const desc = await htmlToWirelessDesc(html);`
`
const jsonStr = JSON.stringify(desc);  // 直接提交给淘宝接口`
`
`

注意:不传 textImage 合图函数时,文字段落会被自动跳过(不生成 text_N 模块),避免提交时报 text_N.images 值不能为空 错误。

完整用法(含图片尺寸 + 文字合图)

javascript 复制代码
import { htmlToWirelessDesc } from 'wireless-desc-converter';`const desc = await htmlToWirelessDesc(html, {`
`
// 图片尺寸获取`
`
imageSize: async ({ url }) => {`
`
const res = await fetch('/api/image-size?url=' + url);`
`
return res.json();  // 返回 { width, height }`
`
},`
`
// 文字合图(Canvas 渲染文字 → 上传到图片空间)`
`
textImage: async ({ text, styles, index }) => {`
`
const res = await fetch('/api/text-to-image', {`
`
method: 'POST',`
`
body: JSON.stringify({ text, styles })`
`
});`
`
return res.json();  // 返回 [{ url, width, height }]`
`
},`
`
// 图片宽高比(无法获取真实尺寸时用于估算)`
`
imageAspectRatio: 0.75   // 高/宽比,默认 0.75(4:3)`
`
});`
`
`

手动构造模块

javascript 复制代码
import {
  buildTextModule,
  buildImageModule,
  buildEmptyWirelessDesc
} from 'wireless-desc-converter';

// 构造图片模块

const imageModule = buildImageModule({

url: 'https://img.alicdn.com/imgextra/xxx.jpg',

width: 620,

height: 827,

hotAreas: [

{ start_x: '0.1', start_y: '0.2', end_x: '0.9', end_y: '0.8', link: 'https://...' }

],

index: 0

});


// 构造文字模块

const textModule = buildTextModule({

text: '商品描述文字',

images: [{ url: '合图URL', width: 620, height: 62 }],

styles: { fontSize: '28', color: '#ff0000', textAlign: 'center' },

index: 1

});

`// 组装`
`
const wirelessDesc = buildEmptyWirelessDesc();`
`
wirelessDesc.value.props.unshift(imageModule, textModule);`
`
`

技术细节

高度自动估算

当无法获取真实图片尺寸时,根据 imageAspectRatio(默认 0.75)估算:

javascript 复制代码
// 宽度 620,宽高比 0.75 → 高度 ≈ 465
estimateImageHeight(620, 0.75);  // "465"

文字高度根据内容和字号估算(CJK 字符宽度 ≈ fontSize,ASCII ≈ fontSize × 0.5,行高 = fontSize × 1.2)。

空值自动填充

淘宝接口对空值校验非常严格,fillEmptyValues() 会遍历整个结构,自动填充所有必填字段:

javascript 复制代码
import { fillEmptyValues } from 'wireless-desc-converter';`fillEmptyValues(wirelessDesc);`
`
// 所有 textStyle.height、width、top、bottom 等空字段都会被自动补全`
`
`

兼容性

  • 零依赖,源码纯 JS
  • 兼容 ES5 / IE8(通过 babel 转译后使用)
  • 支持 Node.js 和浏览器环境

开源地址

总结

淘宝新版图文编辑器的 wirelessDesc 格式虽然复杂,但核心逻辑是固定的。这个工具把 HTML → wirelessDesc 的转换过程封装成了几行代码,ISV 工具接入成本很低。

如果你们也在做淘宝 ISV 工具开发,希望能帮到你们。有问题欢迎提 Issue。