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

前言

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

前置知识

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

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

方案一 脚本

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

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

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

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

方案二 插件

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

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

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

js 复制代码
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 代码块,类如

js 复制代码
// #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

相关推荐
龙国浪子1 小时前
小说写作软件中的文本高亮功能:基于 TipTap 的多彩标记技术实现
vue.js·electron
武昌库里写JAVA2 小时前
Java如何快速入门?Java基础_Java入门
java·vue.js·spring boot·后端·sql
Irene19912 小时前
Element UI 及其 Vue 3 版本 Element Plus 发展现状
前端·vue.js·ui
Account_Ray2 小时前
vue3 的专属二维码组件 vue3-next-qrcode 迎来 4.0.0 版本
前端·vue.js·nuxt.js
帧栈2 小时前
开发避坑指南(70):Vue3 Http请求头携带token下载pdf文件解决方案
前端·vue.js
q_19132846954 小时前
基于SpringBoot2+Vue2的宠物健康医疗论坛系统
vue.js·spring boot·mysql·健康医疗·宠物·计算机毕业设计
一 乐5 小时前
健身达人小程序|基于java+vue健身达人小程序的系统设计与实现(源码+数据库+文档)
java·前端·数据库·vue.js·spring boot·小程序
小云朵爱编程14 小时前
Vue项目Iconify的使用以及自定义图标,封装图标选择器
前端·javascript·vue.js
千寻技术帮14 小时前
50035_基于微信小程序的民宿管理系统
微信小程序·源码·ppt·源代码管理·项目文档·民宿