【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…)
插件源码很简单,五十多行代码
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 沟通。