npm package discovery and stats viewer.

Discover Tips

  • General search

    [free text search, go nuts!]

  • Package details

    pkg:[package-name]

  • User packages

    @[username]

Sponsor

Optimize Toolset

I’ve always been into building performant and accessible sites, but lately I’ve been taking it extremely seriously. So much so that I’ve been building a tool to help me optimize and monitor the sites that I build to make sure that I’m making an attempt to offer the best experience to those who visit them. If you’re into performant, accessible and SEO friendly sites, you might like it too! You can check it out at Optimize Toolset.

About

Hi, 👋, I’m Ryan Hefner  and I built this site for me, and you! The goal of this site was to provide an easy way for me to check the stats on my npm packages, both for prioritizing issues and updates, and to give me a little kick in the pants to keep up on stuff.

As I was building it, I realized that I was actually using the tool to build the tool, and figured I might as well put this out there and hopefully others will find it to be a fast and useful way to search and browse npm packages as I have.

If you’re interested in other things I’m working on, follow me on Twitter or check out the open source projects I’ve been publishing on GitHub.

I am also working on a Twitter bot for this site to tweet the most popular, newest, random packages from npm. Please follow that account now and it will start sending out packages soon–ish.

Open Software & Tools

This site wouldn’t be possible without the immense generosity and tireless efforts from the people who make contributions to the world and share their work via open source initiatives. Thank you 🙏

© 2026 – Pkg Stats / Ryan Hefner

@ecolovo/uniapp-components

v2.0.4

Published

Ecolovo UniApp Vue3 组件库

Downloads

380

Readme

@ecolovo/uniapp-components

UniApp Vue3 组件库。

本项目是为基于 cli 脚手架创建的项目开发的,未在 HBuilderX 项目中实践,请自行验证是否可以正常使用。

安装

使用 npm / yarn 安装

npm install @ecolovo/uniapp-components

组件库的配置

使用前,请按照以下步骤进行一些必要的配置。

1. 在 src/main.js 文件中初始化组件库

// src/main.js

import { init } from '@ecolovo/uniapp-components';

init({
	// 配置组件前缀
	// 在使用时加上前缀,如 button 组件,使用 <ui-button>
	componentPrefix: 'ui',
});

2. 配置 src/pages.js 文件

// src/pages.js

const mergeWith = require('lodash/mergeWith');
const componentEasyCom = require('@ecolovo/uniapp-components/easyCom').default;
const pageJson = require('./pages-config/index');

module.exports = mergeWith(
	pageJson,
	componentEasyCom('ui'), // 填入和步骤 2 中同样的前缀
	function (objValue, srcValue) {
		if (Array.isArray(objValue)) {
			return objValue.concat(srcValue);
		}
	}
);

uni-pages-hot-modules 库在 Vue3.x 版本中无法正常使用,可使用以下脚本进行 pages.js 的动态配置

// scripts/build.js

/* eslint-disable no-console, @typescript-eslint/no-require-imports */

const fs = require('fs');
const path = require('path');
const srcDir = path.resolve(__dirname, '../src');
const pagesJsPath = path.join(srcDir, 'pages.js');
const pagesConfigDir = path.join(srcDir, 'pages-config');
const mainTsPath = path.join(srcDir, 'main.ts');

// 1. Inject environment variables before pages.js is evaluated
const platformArgIndex = process.argv.indexOf('-p');
const platform = platformArgIndex !== -1 ? process.argv[platformArgIndex + 1] : 'h5';
process.env.UNI_PLATFORM = platform;

const envPath = path.resolve(__dirname, '../.env');
if (fs.existsSync(envPath)) {
	const envContent = fs.readFileSync(envPath, 'utf-8');
	for (const line of envContent.split(/\r?\n/)) {
		const trimmed = line.trim();
		if (!trimmed || trimmed.startsWith('#')) continue;
		const eqIndex = trimmed.indexOf('=');
		if (eqIndex !== -1) {
			const key = trimmed.slice(0, eqIndex).trim();
			let value = trimmed.slice(eqIndex + 1).trim();
			if ((value.startsWith('"') && value.endsWith('"')) || (value.startsWith("'") && value.endsWith("'"))) {
				value = value.slice(1, -1);
			}
			process.env[key] = value;
		}
	}
}

// 2. Evaluate pages.js to generate config in memory
Object.keys(require.cache).forEach((key) => {
	if (key.includes('pages-config') || key.endsWith(path.join('src', 'pages.js'))) {
		delete require.cache[key];
	}
});
const pagesConfig = require(pagesJsPath);
let pagesJsonStr = JSON.stringify(pagesConfig);

// 3. Patch fs.readFileSync to intercept pages.json reads
const originalReadFileSync = fs.readFileSync;
fs.readFileSync = function (...args) {
	const filePath = typeof args[0] === 'string' ? path.resolve(args[0]) : '';
	if (filePath.endsWith('pages.json')) {
		const options = args[1];
		const encoding = typeof options === 'string' ? options : options && options.encoding;
		if (encoding === 'utf8' || encoding === 'utf-8') {
			return pagesJsonStr;
		}
		return Buffer.from(pagesJsonStr, 'utf8');
	}
	return originalReadFileSync.apply(this, args);
};

// 4. Replace parsePagesJsonOnce with non-cached version, so rebuilds pick up new config
const pagesModulePath = require.resolve('@dcloudio/uni-cli-shared/dist/json/pages');
delete require.cache[pagesModulePath];
const pagesModule = require(pagesModulePath);
const originalParsePagesJson = pagesModule.parsePagesJson;
pagesModule.parsePagesJsonOnce = function (inputDir, platform) {
	return originalParsePagesJson(inputDir, platform);
};

// 5. Set up file watcher for HMR (watch mode only)
const hasBuildCommand = process.argv.includes('build');
const hasWatch = process.argv.includes('-w') || process.argv.includes('--watch');
const isDevMode = !hasBuildCommand || hasWatch;

if (isDevMode && fs.existsSync(pagesConfigDir)) {
	try {
		const chokidar = require('chokidar');
		const watcher = chokidar.watch(pagesConfigDir, {
			ignoreInitial: true,
			awaitWriteFinish: { stabilityThreshold: 300 },
		});
		watcher.on('change', (file) => {
			console.log(`[HMR] Pages config changed: ${path.relative(srcDir, file)}`);

			// Clear require cache for config modules
			Object.keys(require.cache).forEach((key) => {
				if (key.includes('pages-config') || key.endsWith(path.join('src', 'pages.js'))) {
					delete require.cache[key];
				}
			});

			// Re-evaluate pages.js and update in-memory config
			const newConfig = require(pagesJsPath);
			pagesJsonStr = JSON.stringify(newConfig);

			// Touch main.ts to trigger Rollup rebuild
			try {
				const now = new Date();
				fs.utimesSync(mainTsPath, now, now);
			} catch (_) {
				// Fallback: touch any .vue file
				const fallback = path.join(srcDir, 'App.vue');
				if (fs.existsSync(fallback)) {
					const now = new Date();
					fs.utimesSync(fallback, now, now);
				}
			}
		});
	} catch {
		console.warn('[HMR] chokidar not available, pages hot reload disabled');
	}
}

// 6. Run the uni CLI
require('@dcloudio/vite-plugin-uni/bin/uni');

package.json 中的脚本需要替换,如 dev:mp-weixin 由原来的 uni -p mp-weixin 替换为 node scripts/build.js -p mp-weixin

3. 配置样式

全局样式

<!-- App.vue -->

<style lang="scss">
// 引入组件库全局样式
@use '@ecolovo/uniapp-components/styles/global';
</style>

自定义样式

/* src/styles/prepend.scss */

// 修改全局组件前缀与主题等全局样式
@forward '@ecolovo/uniapp-components/styles/var/theme' with (
	$component-prefix: 'ui',
	// 推荐修改为与组件前缀一致
	$themes:
		(
			primary: #d92e20,
		)
);

// 修改组件默认样式
@forward '@ecolovo/uniapp-components/styles/var/component' with (
	$badge: (
		background: #d92e20,
	)
);

@forward '@ecolovo/uniapp-components/styles';
// vite.config.ts
module.exports = {
	// other configs...
	css: {
		preprocessorOptions: {
			scss: {
				additionalData: '@use "@/styles/prepend.scss" as *;',
			},
		},
	},
};

4. 全局可用的 css 变量

以下变量的访问必须为 <ui-page> 的内部元素。

// 顶部安全区高度
--safe-area-top: 30px;

// 底部安全区高度
--safe-area-bottom: 30px;

// 页面头部上边缘相较于顶部的距离,原则上等于 `--safe-area-top`
--page-header-top: 30px;

// 页面头部高度
--page-header-height: 44px;

// 页面头部下边缘相较于顶部的距离,原则上等于 `--page-header-top` + `--page-header-height`
--page-header-bottom: 74px;

// 小程序胶囊按钮宽度(实际为胶囊按钮最左侧到页面右边的距离)
--menu-button-width: calc(100vw - 280px);

上述变量后的值仅供参考,以实际值为准

使用

请阅读 使用文档