hewking.top

hewking's blog

View the Project on GitHub hewking/blog

小程序富文本处理方案总结

Author: hewking
Labels: blog
Created: 2025-01-05T12:11:54Z
Link and comments: https://github.com/hewking/blog/issues/46

小程序富文本处理方案总结

一、包体积问题分析与解决

1. 问题现象

2. 解决方案

2.1 webpack splitChunks 配置优化

splitChunks: {
  cacheGroups: {
    towxml: {
      name: 'towxml-common',
      priority: 100,
      test: /[\\/]towxml[\\/]/,
      chunks: 'all',
      minChunks: 1,
      enforce: true  // 强制创建chunk
    },
    vendors: {
      name: 'vendors',
      priority: 90,
      test: /[\\/]node_modules[\\/](react|react-dom)[\\/]/,
      chunks: 'all',
      minChunks: 1
    },
    commons: {
      name: 'commons',
      priority: 80,
      chunks: 'all',
      minChunks: 3,
      test: /[\\/]node_modules[\\/]/,
      maxSize: 300 * 1024
    }
  }
}

2.2 静态资源处理优化

copy: {
  patterns: [
    {
      from: 'src/towxml',
      to: 'miniapp/towxml',
      ignore: [
        '**/index.js',      // 只忽略入口JS
        '**/parse/**/*.js', // 忽略解析相关JS
        '**/render/**/*.js', // 忽略渲染相关JS
        '**/*.md',
        '**/*.test.*',
        '**/demo/**',
        '**/node_modules/**',
        '**/.git/**'
      ]
    }
  ]
}

二、mp-html 方案实施

1. 基础配置

1.1 安装依赖

yarn add mp-html

1.2 app.config.ts 配置

usingComponents: {
  'mp-html': '/mp-html/index'
}

1.3 webpack externals 配置

chain.merge({
  externals: [
    {
      'mp-html': 'commonjs mp-html'
    }
  ]
});

2. 组件封装

2.1 基础HTML渲染

import React from 'react';
import { View } from '@tarojs/components';
import type { ViewProps } from '@tarojs/components/types/View';

interface Props extends ViewProps {
  content: string;
  onLinkTap?: (href: string) => void;
}

export default function RichText({ content, style, onLinkTap }: Props) {
  return (
    <View style={style}>
      <mp-html 
        content={content}
        onLinkTap={onLinkTap}
        lazyLoad
        selectable
        useAnchor
      />
    </View>
  );
}

2.2 Markdown支持

import { marked } from 'marked';

interface Props extends ViewProps {
  content: string;
  type?: 'html' | 'markdown';
  onLinkTap?: (href: string) => void;
}

export default function RichText({ content, type = 'html', style, onLinkTap }: Props) {
  const htmlContent = React.useMemo(() => {
    if (type === 'markdown') {
      return marked(content);
    }
    return content;
  }, [content, type]);

  return (
    <View style={style}>
      <mp-html 
        content={htmlContent}
        onLinkTap={onLinkTap}
        lazyLoad
        selectable
        useAnchor
      />
    </View>
  );
}

3. 静态资源处理

copy: {
  patterns: [
    {
      from: 'src/mp-html',
      to: 'miniapp/mp-html'
    }
  ]
}

三、方案对比

towxml

优点:

缺点:

mp-html

优点:

缺点:

四、最佳实践建议

  1. 优先使用 mp-html
  2. 需要复杂样式定制时才考虑 towxml
  3. 合理配置 webpack 优化包体积
  4. 注意静态资源的处理
  5. 考虑按需加载
  6. 做好缓存策略

五、注意事项

  1. 确保组件路径配置正确
  2. 检查 webpack externals 配置
  3. 注意静态资源的完整性
  4. 监控包体积变化
  5. 定期更新组件版本