feat: 微客宝H5客户端 - 基础架构+核心页面

This commit is contained in:
li
2026-03-14 19:44:03 +08:00
parent 54d2f617bb
commit 0e974da09c
3738 changed files with 811180 additions and 21 deletions
+21
View File
@@ -0,0 +1,21 @@
MIT License
Copyright (c) 2020-present, Vben
Permission is hereby granted, free of charge, to any person obtaining a copy
of this software and associated documentation files (the "Software"), to deal
in the Software without restriction, including without limitation the rights
to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
copies of the Software, and to permit persons to whom the Software is
furnished to do so, subject to the following conditions:
The above copyright notice and this permission notice shall be included in all
copies or substantial portions of the Software.
THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE
SOFTWARE.
+313
View File
@@ -0,0 +1,313 @@
'use strict';
Object.defineProperty(exports, '__esModule', { value: true });
const pluginutils = require('@rollup/pluginutils');
const changeCase = require('change-case');
const esModuleLexer = require('es-module-lexer');
const MagicString = require('magic-string');
const path = require('pathe');
const consola = require('consola');
const vite = require('vite');
const fs = require('fs-extra');
const module$1 = require('module');
function _interopDefaultLegacy (e) { return e && typeof e === 'object' && 'default' in e ? e["default"] : e; }
function _interopNamespace(e) {
if (e && e.__esModule) return e;
const n = Object.create(null);
if (e) {
for (const k in e) {
n[k] = e[k];
}
}
n["default"] = e;
return n;
}
const changeCase__namespace = /*#__PURE__*/_interopNamespace(changeCase);
const MagicString__default = /*#__PURE__*/_interopDefaultLegacy(MagicString);
const path__default = /*#__PURE__*/_interopDefaultLegacy(path);
const consola__default = /*#__PURE__*/_interopDefaultLegacy(consola);
const fs__default = /*#__PURE__*/_interopDefaultLegacy(fs);
function resolveNodeModules(libName, ...dir) {
const esRequire = module$1.createRequire((typeof document === 'undefined' ? new (require('u' + 'rl').URL)('file:' + __filename).href : (document.currentScript && document.currentScript.src || new URL('index.cjs', document.baseURI).href)));
let modulePath = "";
try {
modulePath = vite.normalizePath(esRequire.resolve(libName));
} catch (error) {
modulePath = vite.normalizePath(require.resolve(libName));
}
const lastIndex = modulePath.lastIndexOf(libName);
return vite.normalizePath(path__default.resolve(modulePath.substring(0, lastIndex), ...dir));
}
function resolvePnp(module) {
try {
return vite.normalizePath(require.resolve(module));
} catch (error) {
return "";
}
}
const isPnp = !!process.versions.pnp;
function isRegExp(value) {
return Object.prototype.toString.call(value) === "[object RegExp]";
}
function fileExists(f) {
try {
fs__default.accessSync(f, fs__default.constants.W_OK);
return true;
} catch (error) {
return false;
}
}
function isFunction(value) {
return value != null && Object.prototype.toString.call(value) === "[object Function]";
}
function AntdResolve() {
return {
libraryName: "antd",
esModule: true,
resolveStyle: (name) => {
return `antd/es/${name}/style/index`;
}
};
}
function AndDesignVueResolve() {
return {
ensureStyleFile: true,
libraryName: "ant-design-vue",
esModule: true,
resolveStyle: (name) => {
return `ant-design-vue/es/${name}/style/index`;
}
};
}
function ElementPlusResolve() {
return {
libraryName: "element-plus",
ensureStyleFile: true,
esModule: true,
resolveStyle: (name) => {
return `element-plus/theme-chalk/${name}.css`;
},
base: "element-plus/theme-chalk/base.css"
};
}
function VantResolve() {
return {
libraryName: "vant",
esModule: true,
resolveStyle: (name) => {
return `vant/es/${name}/style`;
}
};
}
function NutuiResolve() {
return {
libraryName: "@nutui/nutui",
libraryNameChangeCase: "pascalCase",
resolveStyle: (name) => {
return `@nutui/nutui/dist/packages/${name}/index.scss`;
}
};
}
function VxeTableResolve() {
return {
ensureStyleFile: true,
libraryName: "vxe-table",
esModule: true,
resolveStyle: (name) => {
return `vxe-table/es/${name}/style.css`;
}
};
}
const ensureFileExts = [".css", ".js", ".scss", ".less", ".styl"];
const asRE = /\s+as\s+\w+,?/g;
consola__default.wrapConsole();
function createStyleImportPlugin(options) {
const {
include = ["**/*.vue", "**/*.ts", "**/*.js", "**/*.tsx", "**/*.jsx"],
exclude = "node_modules/**",
resolves = []
} = options;
let { libs = [] } = options;
libs = [...libs, ...resolves];
const filter = pluginutils.createFilter(include, exclude);
let needSourcemap = false;
let external;
return {
name: "vite:style-import",
enforce: "post",
configResolved(resolvedConfig) {
needSourcemap = !!resolvedConfig.build.sourcemap;
external = resolvedConfig?.build?.rollupOptions?.external ?? void 0;
},
async transform(code, id) {
if (!code || !filter(id) || !needTransform(code, libs)) {
return null;
}
await esModuleLexer.init;
let imports = [];
try {
imports = esModuleLexer.parse(code)[0];
} catch (e) {
consola__default.error(e);
}
if (!imports.length) {
return null;
}
let s;
const str = () => s || (s = new MagicString__default(code));
for (let index = 0; index < imports.length; index++) {
const { n, se, ss } = imports[index];
if (!n)
continue;
const lib = getLib(n, libs, external);
if (!lib)
continue;
const importStr = code.slice(ss, se);
let importVariables = transformImportVar(importStr);
importVariables = filterImportVariables(importVariables, lib.importTest);
const importCssStrList = await transformComponentCss(lib, importVariables);
const compStrList = [];
const { base = "" } = lib;
let baseImporter = base ? `
import '${base}'` : "";
if (str().toString().includes(base)) {
baseImporter = "";
}
const endIndex = se + 1;
str().prependRight(endIndex, `${baseImporter}
${compStrList.join("")}${importCssStrList.join("")}`);
}
return {
map: needSourcemap ? str().generateMap({ hires: true }) : null,
code: str().toString()
};
}
};
}
function filterImportVariables(importVars, reg) {
if (!reg) {
return importVars;
}
return importVars.filter((item) => reg.test(item));
}
async function transformComponentCss(lib, importVariables) {
const {
libraryName,
resolveStyle,
esModule,
libraryNameChangeCase = "paramCase",
ensureStyleFile = false
} = lib;
if (!isFunction(resolveStyle) || !libraryName) {
return [];
}
const set = /* @__PURE__ */ new Set();
for (let index = 0; index < importVariables.length; index++) {
const name = getChangeCaseFileName(importVariables[index], libraryNameChangeCase);
let importStr = resolveStyle(name);
if (!importStr) {
continue;
}
let isAdd = true;
if (isPnp) {
importStr = resolvePnp(importStr);
isAdd = !!importStr;
} else {
if (esModule) {
importStr = resolveNodeModules(libraryName, importStr);
}
if (ensureStyleFile) {
isAdd = ensureFileExists(libraryName, importStr, esModule);
}
}
isAdd && set.add(`import '${importStr}';
`);
}
return Array.from(set);
}
function transformImportVar(importStr) {
if (!importStr) {
return [];
}
const exportStr = importStr.replace("import", "export").replace(asRE, ",");
let importVariables = [];
try {
importVariables = esModuleLexer.parse(exportStr)[1];
} catch (error) {
consola__default.error(error);
}
return importVariables;
}
function ensureFileExists(libraryName, importStr, esModule = false) {
const extName = path__default.extname(importStr);
if (!extName) {
return tryEnsureFile(libraryName, importStr, esModule);
}
if (esModule) {
return fileExists(importStr);
}
return true;
}
function tryEnsureFile(libraryName, filePath, esModule = false) {
const filePathList = ensureFileExts.map((item) => {
const p = `${filePath}${item}`;
return esModule ? p : resolveNodeModules(libraryName, p);
});
return filePathList.some((item) => fileExists(item));
}
function getLib(libraryName, libs, external) {
let libList = libs;
if (external) {
const isString = typeof external === "string";
const isRE = isRegExp(external);
if (isString) {
libList = libList.filter((item) => item.libraryName !== external);
} else if (isRE) {
libList = libList.filter((item) => !external.test(item.libraryName));
} else if (Array.isArray(external)) {
libList = libList.filter((item) => {
return !external.some((val) => {
if (typeof val === "string") {
return val === item.libraryName;
}
return val.test(item.libraryName);
});
});
}
}
return libList.find((item) => item.libraryName === libraryName);
}
function getChangeCaseFileName(importedName, libraryNameChangeCase) {
try {
return changeCase__namespace[libraryNameChangeCase](importedName);
} catch (error) {
return importedName;
}
}
function needTransform(code, libs) {
return !libs.every(({ libraryName }) => {
return !new RegExp(`('${libraryName}')|("${libraryName}")`).test(code);
});
}
exports.AndDesignVueResolve = AndDesignVueResolve;
exports.AntdResolve = AntdResolve;
exports.ElementPlusResolve = ElementPlusResolve;
exports.NutuiResolve = NutuiResolve;
exports.VantResolve = VantResolve;
exports.VxeTableResolve = VxeTableResolve;
exports.createStyleImportPlugin = createStyleImportPlugin;
exports.getChangeCaseFileName = getChangeCaseFileName;
exports.transformImportVar = transformImportVar;
+72
View File
@@ -0,0 +1,72 @@
import { Plugin } from 'vite';
declare type RegOptions = string | RegExp | (string | RegExp)[] | null | undefined;
interface Lib {
importTest?: RegExp;
/**
* Dependent library name
*/
libraryName: string;
/**
* When the imported style file does not end with .css, it needs to be turned on
* @default: false
*/
esModule?: boolean;
/**
* Custom imported component style conversion
*/
resolveStyle?: (name: string) => string;
/**
* There may be some component libraries that are not very standardized.
* You can turn on this to ignore to determine whether the file exists. Prevent errors when importing non-existent css files.
* Performance may be slightly reduced after it is turned on, but the impact is not significant
* @default: false
*/
ensureStyleFile?: boolean;
/**
* Customize imported component file name style conversion
* @default: paramCase
*/
libraryNameChangeCase?: LibraryNameChangeCase;
/**
* Whether to introduce base style
*/
base?: string;
}
interface VitePluginOptions {
include?: RegOptions;
exclude?: RegOptions;
/**
* @default process.cwd()
* @deprecated 1.2.0 is obsolete
*/
root?: string;
libs?: Lib[];
resolves?: Lib[];
}
interface Source {
opts: {
libs: Lib[];
cacheDir: string;
};
}
declare type LibraryNameChangeCase = ChangeCaseType | ((name: string) => string);
declare type ChangeCaseType = 'camelCase' | 'capitalCase' | 'constantCase' | 'dotCase' | 'headerCase' | 'noCase' | 'paramCase' | 'pascalCase' | 'pathCase' | 'sentenceCase' | 'snakeCase';
declare function AntdResolve(): Lib;
declare function AndDesignVueResolve(): Lib;
declare function ElementPlusResolve(): Lib;
declare function VantResolve(): Lib;
declare function NutuiResolve(): Lib;
declare function VxeTableResolve(): Lib;
declare function createStyleImportPlugin(options: VitePluginOptions): Plugin;
declare function transformImportVar(importStr: string): readonly string[];
declare function getChangeCaseFileName(importedName: string, libraryNameChangeCase: LibraryNameChangeCase): string;
export { AndDesignVueResolve, AntdResolve, ChangeCaseType, ElementPlusResolve, Lib, LibraryNameChangeCase, NutuiResolve, RegOptions, Source, VantResolve, VitePluginOptions, VxeTableResolve, createStyleImportPlugin, getChangeCaseFileName, transformImportVar };
+281
View File
@@ -0,0 +1,281 @@
import { createFilter } from '@rollup/pluginutils';
import * as changeCase from 'change-case';
import { init, parse } from 'es-module-lexer';
import MagicString from 'magic-string';
import path from 'pathe';
import consola from 'consola';
import { normalizePath } from 'vite';
import fs from 'fs-extra';
import { createRequire } from 'module';
function resolveNodeModules(libName, ...dir) {
const esRequire = createRequire(import.meta.url);
let modulePath = "";
try {
modulePath = normalizePath(esRequire.resolve(libName));
} catch (error) {
modulePath = normalizePath(require.resolve(libName));
}
const lastIndex = modulePath.lastIndexOf(libName);
return normalizePath(path.resolve(modulePath.substring(0, lastIndex), ...dir));
}
function resolvePnp(module) {
try {
return normalizePath(require.resolve(module));
} catch (error) {
return "";
}
}
const isPnp = !!process.versions.pnp;
function isRegExp(value) {
return Object.prototype.toString.call(value) === "[object RegExp]";
}
function fileExists(f) {
try {
fs.accessSync(f, fs.constants.W_OK);
return true;
} catch (error) {
return false;
}
}
function isFunction(value) {
return value != null && Object.prototype.toString.call(value) === "[object Function]";
}
function AntdResolve() {
return {
libraryName: "antd",
esModule: true,
resolveStyle: (name) => {
return `antd/es/${name}/style/index`;
}
};
}
function AndDesignVueResolve() {
return {
ensureStyleFile: true,
libraryName: "ant-design-vue",
esModule: true,
resolveStyle: (name) => {
return `ant-design-vue/es/${name}/style/index`;
}
};
}
function ElementPlusResolve() {
return {
libraryName: "element-plus",
ensureStyleFile: true,
esModule: true,
resolveStyle: (name) => {
return `element-plus/theme-chalk/${name}.css`;
},
base: "element-plus/theme-chalk/base.css"
};
}
function VantResolve() {
return {
libraryName: "vant",
esModule: true,
resolveStyle: (name) => {
return `vant/es/${name}/style`;
}
};
}
function NutuiResolve() {
return {
libraryName: "@nutui/nutui",
libraryNameChangeCase: "pascalCase",
resolveStyle: (name) => {
return `@nutui/nutui/dist/packages/${name}/index.scss`;
}
};
}
function VxeTableResolve() {
return {
ensureStyleFile: true,
libraryName: "vxe-table",
esModule: true,
resolveStyle: (name) => {
return `vxe-table/es/${name}/style.css`;
}
};
}
const ensureFileExts = [".css", ".js", ".scss", ".less", ".styl"];
const asRE = /\s+as\s+\w+,?/g;
consola.wrapConsole();
function createStyleImportPlugin(options) {
const {
include = ["**/*.vue", "**/*.ts", "**/*.js", "**/*.tsx", "**/*.jsx"],
exclude = "node_modules/**",
resolves = []
} = options;
let { libs = [] } = options;
libs = [...libs, ...resolves];
const filter = createFilter(include, exclude);
let needSourcemap = false;
let external;
return {
name: "vite:style-import",
enforce: "post",
configResolved(resolvedConfig) {
needSourcemap = !!resolvedConfig.build.sourcemap;
external = resolvedConfig?.build?.rollupOptions?.external ?? void 0;
},
async transform(code, id) {
if (!code || !filter(id) || !needTransform(code, libs)) {
return null;
}
await init;
let imports = [];
try {
imports = parse(code)[0];
} catch (e) {
consola.error(e);
}
if (!imports.length) {
return null;
}
let s;
const str = () => s || (s = new MagicString(code));
for (let index = 0; index < imports.length; index++) {
const { n, se, ss } = imports[index];
if (!n)
continue;
const lib = getLib(n, libs, external);
if (!lib)
continue;
const importStr = code.slice(ss, se);
let importVariables = transformImportVar(importStr);
importVariables = filterImportVariables(importVariables, lib.importTest);
const importCssStrList = await transformComponentCss(lib, importVariables);
const compStrList = [];
const { base = "" } = lib;
let baseImporter = base ? `
import '${base}'` : "";
if (str().toString().includes(base)) {
baseImporter = "";
}
const endIndex = se + 1;
str().prependRight(endIndex, `${baseImporter}
${compStrList.join("")}${importCssStrList.join("")}`);
}
return {
map: needSourcemap ? str().generateMap({ hires: true }) : null,
code: str().toString()
};
}
};
}
function filterImportVariables(importVars, reg) {
if (!reg) {
return importVars;
}
return importVars.filter((item) => reg.test(item));
}
async function transformComponentCss(lib, importVariables) {
const {
libraryName,
resolveStyle,
esModule,
libraryNameChangeCase = "paramCase",
ensureStyleFile = false
} = lib;
if (!isFunction(resolveStyle) || !libraryName) {
return [];
}
const set = /* @__PURE__ */ new Set();
for (let index = 0; index < importVariables.length; index++) {
const name = getChangeCaseFileName(importVariables[index], libraryNameChangeCase);
let importStr = resolveStyle(name);
if (!importStr) {
continue;
}
let isAdd = true;
if (isPnp) {
importStr = resolvePnp(importStr);
isAdd = !!importStr;
} else {
if (esModule) {
importStr = resolveNodeModules(libraryName, importStr);
}
if (ensureStyleFile) {
isAdd = ensureFileExists(libraryName, importStr, esModule);
}
}
isAdd && set.add(`import '${importStr}';
`);
}
return Array.from(set);
}
function transformImportVar(importStr) {
if (!importStr) {
return [];
}
const exportStr = importStr.replace("import", "export").replace(asRE, ",");
let importVariables = [];
try {
importVariables = parse(exportStr)[1];
} catch (error) {
consola.error(error);
}
return importVariables;
}
function ensureFileExists(libraryName, importStr, esModule = false) {
const extName = path.extname(importStr);
if (!extName) {
return tryEnsureFile(libraryName, importStr, esModule);
}
if (esModule) {
return fileExists(importStr);
}
return true;
}
function tryEnsureFile(libraryName, filePath, esModule = false) {
const filePathList = ensureFileExts.map((item) => {
const p = `${filePath}${item}`;
return esModule ? p : resolveNodeModules(libraryName, p);
});
return filePathList.some((item) => fileExists(item));
}
function getLib(libraryName, libs, external) {
let libList = libs;
if (external) {
const isString = typeof external === "string";
const isRE = isRegExp(external);
if (isString) {
libList = libList.filter((item) => item.libraryName !== external);
} else if (isRE) {
libList = libList.filter((item) => !external.test(item.libraryName));
} else if (Array.isArray(external)) {
libList = libList.filter((item) => {
return !external.some((val) => {
if (typeof val === "string") {
return val === item.libraryName;
}
return val.test(item.libraryName);
});
});
}
}
return libList.find((item) => item.libraryName === libraryName);
}
function getChangeCaseFileName(importedName, libraryNameChangeCase) {
try {
return changeCase[libraryNameChangeCase](importedName);
} catch (error) {
return importedName;
}
}
function needTransform(code, libs) {
return !libs.every(({ libraryName }) => {
return !new RegExp(`('${libraryName}')|("${libraryName}")`).test(code);
});
}
export { AndDesignVueResolve, AntdResolve, ElementPlusResolve, NutuiResolve, VantResolve, VxeTableResolve, createStyleImportPlugin, getChangeCaseFileName, transformImportVar };
+55
View File
@@ -0,0 +1,55 @@
{
"name": "vite-plugin-style-import",
"version": "2.0.0",
"description": "A plug-in that imports component library styles on demand",
"main": "dist/index.cjs",
"module": "dist/index.mjs",
"types": "dist/index.d.ts",
"exports": {
".": {
"require": "./dist/index.cjs",
"import": "./dist/index.mjs",
"types": "./dist/index.d.ts"
}
},
"license": "MIT",
"author": "Vben",
"files": [
"dist"
],
"keywords": [
"vite",
"style",
"import",
"css"
],
"repository": {
"type": "git",
"url": "https://github.com/anncwb/vite-plugin-style-import",
"directory": "packages/core"
},
"bugs": {
"url": "https://github.com/anncwb/vite-plugin-style-import/issues"
},
"homepage": "https://github.com/anncwb/vite-plugin-style-import/tree/master/#readme",
"dependencies": {
"@rollup/pluginutils": "^4.1.2",
"change-case": "^4.1.2",
"console": "^0.7.2",
"es-module-lexer": "^0.9.3",
"fs-extra": "^10.0.0",
"magic-string": "^0.25.7",
"pathe": "^0.2.0"
},
"peerDependencies": {
"vite": ">=2.0.0"
},
"devDependencies": {
"@types/fs-extra": "^9.0.13",
"@types/node": "^17.0.13"
},
"scripts": {
"dev": "pnpm unbuild --stub",
"build": "pnpm unbuild"
}
}