普通视图

发现新文章,点击刷新页面。
昨天 — 2025年11月23日首页

【uniapp】小程序实现自由控制组件JSON文件配置

2025年11月23日 11:29

前言

最近在 uniapp ask社区 回答问题,不少开发者都咨询到了如何配置 组件 生成的 json文件 这个问题,在经过跟同事的交流、自己的实践以及开发者的反馈后,我整理了下面的解决思路和方案。

前置知识

uniapp 编译到 小程序,一个 vue 组件编译结束之后会生成四个文件,以微信小程序举例

image.png

生成的 json文件 的内容存储着小程序页面或组件相关的配置,必不可少

方案一 脚本

这个思路是在框架打包结束之后通过 nodejs 或者 shell 去修改产物

以占位组件为例,做分包异步化降低主包体积不可或缺的一个配置项

image.png

开发者只需要事先统计好需要配置的 componentPlaceholder 和 产物路径,在打包结束之后通过脚本把内容写入到对应的 json文件 就可以了

这种思路适合 cli项目,可以很轻松把脚本添加到 package.json 中的 scripts 中,并且不受 nodejs 版本限制;但是有些开发者的项目是 hx项目,就不能通过脚本的形式来操作了。

方案二 插件

这个思路是通过 webpack 或者 vite 插件来解决相关问题

我们以我写的 vite 插件 为例 (github 地址 github.com/uni-toolkit…

插件源码很简单,五十多行代码

import { getOutputJsonPath, isMiniProgram } from '@uni_toolkit/shared';
import type { PluginOption } from 'vite';
import { createFilter, type FilterPattern } from '@rollup/pluginutils';
import path from 'node:path';
import fs from 'node:fs';
import { parseJson } from '@dcloudio/uni-cli-shared';
import { merge } from 'lodash-es';

export interface ComponentConfigPluginOptions {
  include?: FilterPattern;
  exclude?: FilterPattern;
}

export default function vitePluginComponentConfig(
  options: ComponentConfigPluginOptions = {
    include: ['**/*.{vue,nvue,uvue}'],
    exclude: [],
  },
): PluginOption {
  const map: Map<string, Record<string, any>> = new Map();
  return {
    name: 'vite-plugin-component-config',
    enforce: 'pre',
    transform(code, id) {
      if (!isMiniProgram()) {
        return;
      }
      if (!createFilter(options.include, options.exclude)(id)) {
        return;
      }
      const matches = code.match(/<component-config>([\s\S]*?)<\/component-config>/g);
      if (!matches) {
        return;
      }

      matches.forEach((match) => {
        const content = match.replace(/<component-config>|<\/component-config>/g, '');
        const componentConfig = parseJson(content.toString(), true, path.basename(id));
        map.set(getOutputJsonPath(id), componentConfig);
      });

      return code.replace(/<component-config>[\s\S]*?<\/component-config>/g, '');
    },
    closeBundle() {
      if (map.size === 0) {
        return;
      }
      for (const [outputPath, config] of map) {
        if (!fs.existsSync(outputPath)) {
          continue;
        }
        const content = fs.readFileSync(outputPath, 'utf-8');
        const json = JSON.parse(content);
        fs.writeFileSync(outputPath, JSON.stringify(merge(json, config), null, 2));
      }
    },
  };
}

思路就是需要开发者在具体的 vue文件 中添加一个 component-config 代码块,类如

// #ifdef MP
<component-config>
{
  "usingComponents": {
    "custom-button": "/components/custom-button"
  },
  "styleIsolation": "apply-shared",
  "componentPlaceholder": {  
    "test": "view",  
  }  
}
</component-config>
// #endif

在编译期间,会通过正则表达式提取 component-config 代码块中的配置,存储到 hashMap 中,在 bundle 生成结束后遍历 hashMap 中的数据,然后修改对应路径的 json文件

同时还考虑到有些开发者会针对不同的小程序平台添加不同的配置,component-config 代码块中的内容也支持 条件编译

如果你是 vue2 项目,可以使用这个插件 github 地址 github.com/uni-toolkit…

结语

如果这些插件帮助到了你,可以点个 star✨ 支持一下开源工作。

如果你有什么好的想法或者建议,欢迎在 github.com/uni-toolkit… 提 issue 或者 pr;也可以加我的 微信 13460036576 沟通。

❌
❌