2025/2/8第一次更新

This commit is contained in:
爱吃咸鱼小猫咪
2025-02-08 18:50:38 +08:00
commit d7af560866
26519 changed files with 5046029 additions and 0 deletions
+1
View File
@@ -0,0 +1 @@
export declare function isMiniProgramAssetFile(filename: string): boolean;
+33
View File
@@ -0,0 +1,33 @@
"use strict";
var __importDefault = (this && this.__importDefault) || function (mod) {
return (mod && mod.__esModule) ? mod : { "default": mod };
};
Object.defineProperty(exports, "__esModule", { value: true });
exports.isMiniProgramAssetFile = void 0;
const path_1 = __importDefault(require("path"));
const EXTNAMES = [
'.png',
'.jpg',
'.jpeg',
'.gif',
'.svg',
'.json',
'.cer',
'.mp3',
'.aac',
'.m4a',
'.mp4',
'.wav',
'.ogg',
'.silk',
'.wasm',
'.br',
'.cert',
];
function isMiniProgramAssetFile(filename) {
if (!path_1.default.isAbsolute(filename)) {
return false;
}
return EXTNAMES.includes(path_1.default.extname(filename));
}
exports.isMiniProgramAssetFile = isMiniProgramAssetFile;
+5
View File
@@ -0,0 +1,5 @@
import type { Program } from '@babel/types';
import { type ParserPlugin } from '@babel/parser';
export declare function parseProgram(code: string, importer: string, { babelParserPlugins }: {
babelParserPlugins?: ParserPlugin[];
}): Program;
+12
View File
@@ -0,0 +1,12 @@
"use strict";
Object.defineProperty(exports, "__esModule", { value: true });
exports.parseProgram = void 0;
const parser_1 = require("@babel/parser");
const utils_1 = require("../utils");
function parseProgram(code, importer, { babelParserPlugins }) {
return (0, parser_1.parse)(code, {
plugins: (0, utils_1.normalizeParsePlugins)(importer, babelParserPlugins),
sourceType: 'module',
}).program;
}
exports.parseProgram = parseProgram;
+5
View File
@@ -0,0 +1,5 @@
export declare const COMPONENT_ON_LINK = "onVI";
export declare const COMPONENT_BIND_LINK = "__l";
export declare const COMPONENT_CUSTOM_HIDDEN = "data-c-h";
export declare const COMPONENT_CUSTOM_HIDDEN_BIND: string;
export declare const MP_PLUGIN_JSON_NAME = "plugin.json";
+8
View File
@@ -0,0 +1,8 @@
"use strict";
Object.defineProperty(exports, "__esModule", { value: true });
exports.MP_PLUGIN_JSON_NAME = exports.COMPONENT_CUSTOM_HIDDEN_BIND = exports.COMPONENT_CUSTOM_HIDDEN = exports.COMPONENT_BIND_LINK = exports.COMPONENT_ON_LINK = void 0;
exports.COMPONENT_ON_LINK = 'onVI';
exports.COMPONENT_BIND_LINK = '__l';
exports.COMPONENT_CUSTOM_HIDDEN = 'data-c-h';
exports.COMPONENT_CUSTOM_HIDDEN_BIND = 'bind:-' + exports.COMPONENT_CUSTOM_HIDDEN;
exports.MP_PLUGIN_JSON_NAME = 'plugin.json';
+5
View File
@@ -0,0 +1,5 @@
export declare function formatMiniProgramEvent(eventName: string, { isCatch, isCapture, isComponent, }: {
isCatch?: boolean;
isCapture?: boolean;
isComponent?: boolean;
}): string;
+35
View File
@@ -0,0 +1,35 @@
"use strict";
Object.defineProperty(exports, "__esModule", { value: true });
exports.formatMiniProgramEvent = void 0;
const uni_shared_1 = require("@dcloudio/uni-shared");
function formatMiniProgramEvent(eventName, { isCatch, isCapture, isComponent, }) {
if (isComponent) {
// 自定义组件的自定义事件需要格式化,因为 triggerEvent 时也会格式化
eventName = (0, uni_shared_1.customizeEvent)(eventName);
}
if (!isComponent && eventName === 'click') {
eventName = 'tap';
}
let eventType = 'bind';
if (isCatch) {
eventType = 'catch';
}
if (isCapture) {
return `capture-${eventType}:${eventName}`;
}
// bind:foo-bar
return eventType + (isSimpleExpr(eventName) ? '' : ':') + eventName;
}
exports.formatMiniProgramEvent = formatMiniProgramEvent;
function isSimpleExpr(name) {
if (name.startsWith('_')) {
return false;
}
if (name.indexOf('-') > -1) {
return false;
}
if (name.indexOf(':') > -1) {
return false;
}
return true;
}
+5
View File
@@ -0,0 +1,5 @@
import { type Program } from '@babel/types';
export declare function hasExternalClasses(code: string): boolean;
export declare function findMiniProgramComponentExternalClasses(filename: string): string[] | undefined;
export declare function updateMiniProgramComponentExternalClasses(filename: string, classes: string[]): void;
export declare function parseExternalClasses(ast: Program): string[];
+42
View File
@@ -0,0 +1,42 @@
"use strict";
Object.defineProperty(exports, "__esModule", { value: true });
exports.parseExternalClasses = exports.updateMiniProgramComponentExternalClasses = exports.findMiniProgramComponentExternalClasses = exports.hasExternalClasses = void 0;
const types_1 = require("@babel/types");
const estree_walker_1 = require("estree-walker");
const externalClassesCache = new Map();
function hasExternalClasses(code) {
return code.includes('externalClasses');
}
exports.hasExternalClasses = hasExternalClasses;
function findMiniProgramComponentExternalClasses(filename) {
return externalClassesCache.get(filename);
}
exports.findMiniProgramComponentExternalClasses = findMiniProgramComponentExternalClasses;
function updateMiniProgramComponentExternalClasses(filename, classes) {
externalClassesCache.set(filename, classes);
}
exports.updateMiniProgramComponentExternalClasses = updateMiniProgramComponentExternalClasses;
function parseExternalClasses(ast) {
const classes = [];
estree_walker_1.walk(ast, {
enter(child, parent) {
if (!(0, types_1.isIdentifier)(child) || child.name !== 'externalClasses') {
return;
}
// export default { externalClasses: ['my-class'] }
if (!(0, types_1.isObjectProperty)(parent)) {
return;
}
if (!(0, types_1.isArrayExpression)(parent.value)) {
return;
}
parent.value.elements.forEach((element) => {
if ((0, types_1.isStringLiteral)(element)) {
classes.push(element.value);
}
});
},
});
return classes;
}
exports.parseExternalClasses = parseExternalClasses;
+12
View File
@@ -0,0 +1,12 @@
import type { PluginContext } from 'rollup';
import { type ImportSpecifier } from 'es-module-lexer';
/**
* 暂时没用
* @param source
* @param importer
* @param resolve
* @returns
*/
export declare function findVueComponentImports(source: string, importer: string, resolve: PluginContext['resolve']): Promise<(ImportSpecifier & {
i: string;
})[]>;
+72
View File
@@ -0,0 +1,72 @@
"use strict";
var __importDefault = (this && this.__importDefault) || function (mod) {
return (mod && mod.__esModule) ? mod : { "default": mod };
};
Object.defineProperty(exports, "__esModule", { value: true });
exports.findVueComponentImports = void 0;
const path_1 = __importDefault(require("path"));
const es_module_lexer_1 = require("es-module-lexer");
const shared_1 = require("@vue/shared");
const types_1 = require("@babel/types");
const parser_1 = require("@babel/parser");
const constants_1 = require("../constants");
const utils_1 = require("../utils");
/**
* 暂时没用
* @param source
* @param importer
* @param resolve
* @returns
*/
async function findVueComponentImports(source, importer, resolve) {
await es_module_lexer_1.init;
let imports = [];
// strip UTF-8 BOM
if (source.charCodeAt(0) === 0xfeff) {
source = source.slice(1);
}
try {
imports = (0, es_module_lexer_1.parse)(source)[0];
}
catch (e) {
console.error(e);
}
if (!imports.length) {
return [];
}
const rewriteImports = [];
for (let i = 0; i < imports.length; i++) {
const importSpecifier = imports[i];
const { n } = importSpecifier;
if (!n) {
continue;
}
const extname = path_1.default.extname(n);
// 仅处理没有后缀,或后缀是.vue,.nvue的文件
if (extname && !constants_1.EXTNAME_VUE.includes(extname)) {
continue;
}
const res = await resolve(n, importer);
if (!res) {
continue;
}
if (constants_1.EXTNAME_VUE_RE.test(res.id)) {
const expr = (0, parser_1.parse)(source.slice(importSpecifier.ss, importSpecifier.se), {
plugins: (0, utils_1.normalizeParsePlugins)(res.id),
sourceType: 'module',
}).program.body[0];
if ((0, types_1.isImportDeclaration)(expr) && expr.specifiers.length === 1) {
const importDefaultSpecifier = expr.specifiers[0];
if (!(0, types_1.isImportDefaultSpecifier)(importDefaultSpecifier)) {
continue;
}
rewriteImports.push((0, shared_1.extend)(importSpecifier, {
n: res.id,
i: importDefaultSpecifier.local.name,
}));
}
}
}
return rewriteImports;
}
exports.findVueComponentImports = findVueComponentImports;
+12
View File
@@ -0,0 +1,12 @@
export * from './ast';
export * from './wxs';
export * from './nvue';
export * from './event';
export * from './style';
export * from './assets';
export * from './template';
export * from './constants';
export { HTML_TO_MINI_PROGRAM_TAGS } from './tags';
export { copyMiniProgramPluginJson, copyMiniProgramThemeJson } from './plugin';
export { parseMainDescriptor, parseScriptDescriptor, parseTemplateDescriptor, transformDynamicImports, updateMiniProgramGlobalComponents, updateMiniProgramComponentsByMainFilename, updateMiniProgramComponentsByScriptFilename, updateMiniProgramComponentsByTemplateFilename, } from './usingComponents';
export { hasExternalClasses, parseExternalClasses, findMiniProgramComponentExternalClasses, updateMiniProgramComponentExternalClasses, } from './externalClasses';
+44
View File
@@ -0,0 +1,44 @@
"use strict";
var __createBinding = (this && this.__createBinding) || (Object.create ? (function(o, m, k, k2) {
if (k2 === undefined) k2 = k;
var desc = Object.getOwnPropertyDescriptor(m, k);
if (!desc || ("get" in desc ? !m.__esModule : desc.writable || desc.configurable)) {
desc = { enumerable: true, get: function() { return m[k]; } };
}
Object.defineProperty(o, k2, desc);
}) : (function(o, m, k, k2) {
if (k2 === undefined) k2 = k;
o[k2] = m[k];
}));
var __exportStar = (this && this.__exportStar) || function(m, exports) {
for (var p in m) if (p !== "default" && !Object.prototype.hasOwnProperty.call(exports, p)) __createBinding(exports, m, p);
};
Object.defineProperty(exports, "__esModule", { value: true });
exports.updateMiniProgramComponentExternalClasses = exports.findMiniProgramComponentExternalClasses = exports.parseExternalClasses = exports.hasExternalClasses = exports.updateMiniProgramComponentsByTemplateFilename = exports.updateMiniProgramComponentsByScriptFilename = exports.updateMiniProgramComponentsByMainFilename = exports.updateMiniProgramGlobalComponents = exports.transformDynamicImports = exports.parseTemplateDescriptor = exports.parseScriptDescriptor = exports.parseMainDescriptor = exports.copyMiniProgramThemeJson = exports.copyMiniProgramPluginJson = exports.HTML_TO_MINI_PROGRAM_TAGS = void 0;
__exportStar(require("./ast"), exports);
__exportStar(require("./wxs"), exports);
__exportStar(require("./nvue"), exports);
__exportStar(require("./event"), exports);
__exportStar(require("./style"), exports);
__exportStar(require("./assets"), exports);
__exportStar(require("./template"), exports);
__exportStar(require("./constants"), exports);
var tags_1 = require("./tags");
Object.defineProperty(exports, "HTML_TO_MINI_PROGRAM_TAGS", { enumerable: true, get: function () { return tags_1.HTML_TO_MINI_PROGRAM_TAGS; } });
var plugin_1 = require("./plugin");
Object.defineProperty(exports, "copyMiniProgramPluginJson", { enumerable: true, get: function () { return plugin_1.copyMiniProgramPluginJson; } });
Object.defineProperty(exports, "copyMiniProgramThemeJson", { enumerable: true, get: function () { return plugin_1.copyMiniProgramThemeJson; } });
var usingComponents_1 = require("./usingComponents");
Object.defineProperty(exports, "parseMainDescriptor", { enumerable: true, get: function () { return usingComponents_1.parseMainDescriptor; } });
Object.defineProperty(exports, "parseScriptDescriptor", { enumerable: true, get: function () { return usingComponents_1.parseScriptDescriptor; } });
Object.defineProperty(exports, "parseTemplateDescriptor", { enumerable: true, get: function () { return usingComponents_1.parseTemplateDescriptor; } });
Object.defineProperty(exports, "transformDynamicImports", { enumerable: true, get: function () { return usingComponents_1.transformDynamicImports; } });
Object.defineProperty(exports, "updateMiniProgramGlobalComponents", { enumerable: true, get: function () { return usingComponents_1.updateMiniProgramGlobalComponents; } });
Object.defineProperty(exports, "updateMiniProgramComponentsByMainFilename", { enumerable: true, get: function () { return usingComponents_1.updateMiniProgramComponentsByMainFilename; } });
Object.defineProperty(exports, "updateMiniProgramComponentsByScriptFilename", { enumerable: true, get: function () { return usingComponents_1.updateMiniProgramComponentsByScriptFilename; } });
Object.defineProperty(exports, "updateMiniProgramComponentsByTemplateFilename", { enumerable: true, get: function () { return usingComponents_1.updateMiniProgramComponentsByTemplateFilename; } });
var externalClasses_1 = require("./externalClasses");
Object.defineProperty(exports, "hasExternalClasses", { enumerable: true, get: function () { return externalClasses_1.hasExternalClasses; } });
Object.defineProperty(exports, "parseExternalClasses", { enumerable: true, get: function () { return externalClasses_1.parseExternalClasses; } });
Object.defineProperty(exports, "findMiniProgramComponentExternalClasses", { enumerable: true, get: function () { return externalClasses_1.findMiniProgramComponentExternalClasses; } });
Object.defineProperty(exports, "updateMiniProgramComponentExternalClasses", { enumerable: true, get: function () { return externalClasses_1.updateMiniProgramComponentExternalClasses; } });
+1
View File
@@ -0,0 +1 @@
export declare function genNVueCssCode(manifestJson: Record<string, any>): string;
+18
View File
@@ -0,0 +1,18 @@
"use strict";
var __importDefault = (this && this.__importDefault) || function (mod) {
return (mod && mod.__esModule) ? mod : { "default": mod };
};
Object.defineProperty(exports, "__esModule", { value: true });
exports.genNVueCssCode = void 0;
const fs_1 = __importDefault(require("fs"));
const path_1 = __importDefault(require("path"));
const nvue_1 = require("../json/app/manifest/nvue");
function genNVueCssCode(manifestJson) {
let nvueCssCode = fs_1.default.readFileSync(path_1.default.resolve(__dirname, '../../lib/nvue.css'), 'utf8');
const flexDirection = (0, nvue_1.getNVueFlexDirection)(manifestJson);
if (flexDirection !== 'column') {
nvueCssCode = nvueCssCode.replace('column', flexDirection);
}
return nvueCssCode;
}
exports.genNVueCssCode = genNVueCssCode;
+3
View File
@@ -0,0 +1,3 @@
import type { UniViteCopyPluginTarget } from '../vite/plugins/copy';
export declare const copyMiniProgramPluginJson: UniViteCopyPluginTarget;
export declare const copyMiniProgramThemeJson: () => UniViteCopyPluginTarget[];
+41
View File
@@ -0,0 +1,41 @@
"use strict";
var __importDefault = (this && this.__importDefault) || function (mod) {
return (mod && mod.__esModule) ? mod : { "default": mod };
};
Object.defineProperty(exports, "__esModule", { value: true });
exports.copyMiniProgramThemeJson = exports.copyMiniProgramPluginJson = void 0;
const fs_1 = __importDefault(require("fs"));
const path_1 = __importDefault(require("path"));
const json_1 = require("../json/json");
const manifest_1 = require("../json/manifest");
exports.copyMiniProgramPluginJson = {
src: ['plugin.json'],
get dest() {
return process.env.UNI_OUTPUT_DIR;
},
transform(source) {
return JSON.stringify((0, json_1.parseJson)(source.toString(), true), null, 2);
},
};
const copyMiniProgramThemeJson = () => {
if (!process.env.UNI_INPUT_DIR)
return [];
const manifestJson = (0, manifest_1.getPlatformManifestJsonOnce)();
const themeLocation = manifestJson.themeLocation || 'theme.json';
const hasThemeJson = fs_1.default.existsSync(path_1.default.resolve(process.env.UNI_INPUT_DIR, themeLocation));
if (hasThemeJson) {
return [
{
src: [(manifestJson.themeLocation = themeLocation)],
get dest() {
return process.env.UNI_OUTPUT_DIR;
},
transform(source) {
return JSON.stringify((0, json_1.parseJson)(source.toString(), true), null, 2);
},
},
];
}
return [];
};
exports.copyMiniProgramThemeJson = copyMiniProgramThemeJson;
+1
View File
@@ -0,0 +1 @@
export declare function transformScopedCss(cssCode: string): string;
+20
View File
@@ -0,0 +1,20 @@
"use strict";
Object.defineProperty(exports, "__esModule", { value: true });
exports.transformScopedCss = void 0;
const tags_1 = require("./tags");
const logs_1 = require("../logs");
function transformScopedCss(cssCode) {
checkHtmlTagSelector(cssCode);
return cssCode.replace(/\[(data-v-[a-f0-9]{8})\]/gi, (_, scopedId) => {
return '.' + scopedId;
});
}
exports.transformScopedCss = transformScopedCss;
function checkHtmlTagSelector(cssCode) {
for (const tag in tags_1.HTML_TO_MINI_PROGRAM_TAGS) {
if (new RegExp(`( |\n|\t|,|})${tag}( *)(,|{)`, 'g').test(cssCode)) {
(0, logs_1.output)('warn', `小程序端 style 暂不支持 ${tag} 标签选择器,推荐使用 class 选择器,详情参考:https://uniapp.dcloud.net.cn/tutorial/migration-to-vue3.html#style`);
break;
}
}
}
+1
View File
@@ -0,0 +1 @@
export declare const HTML_TO_MINI_PROGRAM_TAGS: Record<string, string>;
+116
View File
@@ -0,0 +1,116 @@
"use strict";
Object.defineProperty(exports, "__esModule", { value: true });
exports.HTML_TO_MINI_PROGRAM_TAGS = void 0;
exports.HTML_TO_MINI_PROGRAM_TAGS = {
br: 'view',
hr: 'view',
p: 'view',
h1: 'view',
h2: 'view',
h3: 'view',
h4: 'view',
h5: 'view',
h6: 'view',
abbr: 'view',
address: 'view',
b: 'view',
bdi: 'view',
bdo: 'view',
blockquote: 'view',
cite: 'view',
code: 'view',
del: 'view',
ins: 'view',
dfn: 'view',
em: 'view',
strong: 'view',
samp: 'view',
kbd: 'view',
var: 'view',
i: 'view',
mark: 'view',
pre: 'view',
q: 'view',
ruby: 'view',
rp: 'view',
rt: 'view',
s: 'view',
small: 'view',
sub: 'view',
sup: 'view',
time: 'view',
u: 'view',
wbr: 'view',
// 表单元素
// form: 'form',
// input: 'input',
// textarea: 'textarea',
// button: 'button',
select: 'picker',
option: 'view',
optgroup: 'view',
fieldset: 'view',
datalist: 'picker',
legend: 'view',
output: 'view',
// 框架
iframe: 'view',
// 图像
img: 'image',
// canvas: 'canvas',
figure: 'view',
figcaption: 'view',
// 音视频
// audio: 'audio',
source: 'audio',
// video: 'video',
track: 'video',
// 链接
a: 'navigator',
nav: 'view',
link: 'navigator',
// 列表
ul: 'view',
ol: 'view',
li: 'view',
dl: 'view',
dt: 'view',
dd: 'view',
menu: 'view',
command: 'view',
// 表格table
table: 'view',
caption: 'view',
th: 'view',
td: 'view',
tr: 'view',
thead: 'view',
tbody: 'view',
tfoot: 'view',
col: 'view',
colgroup: 'view',
// 样式 节
div: 'view',
main: 'view',
span: 'label',
header: 'view',
footer: 'view',
section: 'view',
article: 'view',
aside: 'view',
details: 'view',
dialog: 'view',
summary: 'view',
// progress: 'progress',
meter: 'progress', // todo
head: 'view', // todo
meta: 'view', // todo
base: 'text', // todo
// 'map': 'image', // TODO不是很恰当
area: 'navigator', // j结合map使用
script: 'view',
noscript: 'view',
embed: 'view',
object: 'view',
param: 'view',
};
+104
View File
@@ -0,0 +1,104 @@
import type { EmittedAsset } from 'rollup';
import type { AttributeNode, DirectiveNode, ElementNode } from '@vue/compiler-core';
import type { MiniProgramComponentsType } from '../json/mp/types';
type LazyElementFn = (node: ElementNode, context: {
isMiniProgramComponent(name: string): MiniProgramComponentsType | undefined;
}) => {
[name: string]: {
name: 'on' | 'bind';
arg: string[];
}[] | true;
} | boolean;
export interface MiniProgramCompilerOptions {
/**
* 检查属性名称是否符合平台要求,比如华为快应用不允许使用 key 属性等
*/
checkPropName?: (name: string, prop: AttributeNode | DirectiveNode, node: ElementNode) => boolean;
/**
* 需要延迟渲染的组件,通常是某个组件的某个事件会立刻触发,需要延迟到首次 render 之后,比如微信 editor 的 ready 事件,快手 switch 的 change
*/
lazyElement?: {
[name: string]: {
name: 'on' | 'bind';
arg: string[];
}[] | true;
} | LazyElementFn;
event?: {
key?: boolean;
format?(name: string, opts: {
isCatch?: boolean;
isCapture?: boolean;
isComponent?: boolean;
}): string;
};
class: {
/**
* 是否支持绑定 array 类型
*/
array: boolean;
};
slot: {
/**
* 是否支持 $slots.default 访问
*/
$slots?: boolean;
/**
* 是否支持后备内容
*/
fallbackContent?: boolean;
/**
* 是否支持动态插槽名
*/
dynamicSlotNames?: boolean;
};
filter?: {
lang: string;
/**
* 是否支持 setStyle
*/
setStyle?: boolean;
generate?: Parameters<typeof findMiniProgramTemplateFiles>[0];
};
component?: {
/**
* 是否支持 :host 伪类
*/
':host'?: boolean;
/**
* 平台自定义组件目录,如 wxcomponents
*/
dir?: string;
/**
* 自定义组件自定义 hidden 属性用于实现 v-show
*/
vShow?: string;
/**
* 父组件 setData 后,子组件的 properties 是否可以同步获取,目前仅 mp-weixinmp-qqmp-alipay 支持
*/
getPropertySync?: boolean;
/**
* 格式化组件名称,比如 wx-btn => weixin-btn (微信不允许以 wx 命名自定义组件)
*/
normalizeName?: (name: string) => string;
/**
* 合并虚拟化节点属性(class、style)
*/
mergeVirtualHostAttributes?: boolean;
};
directive: string;
emitFile?: (emittedFile: EmittedAsset) => string;
}
export interface MiniProgramFilterOptions {
id: string;
type: string;
name: string;
src?: string;
code: string;
}
type GenFilterFn = (filter: MiniProgramFilterOptions, filename: string) => string | void;
export declare function findMiniProgramTemplateFiles(genFilter?: GenFilterFn): Record<string, string>;
export declare function clearMiniProgramTemplateFiles(): void;
export declare function addMiniProgramTemplateFile(filename: string, code: string): void;
export declare function clearMiniProgramTemplateFilter(filename: string): void;
export declare function addMiniProgramTemplateFilter(filename: string, filter: MiniProgramFilterOptions): void;
export {};
+73
View File
@@ -0,0 +1,73 @@
"use strict";
var __importDefault = (this && this.__importDefault) || function (mod) {
return (mod && mod.__esModule) ? mod : { "default": mod };
};
Object.defineProperty(exports, "__esModule", { value: true });
exports.addMiniProgramTemplateFilter = exports.clearMiniProgramTemplateFilter = exports.addMiniProgramTemplateFile = exports.clearMiniProgramTemplateFiles = exports.findMiniProgramTemplateFiles = void 0;
const path_1 = __importDefault(require("path"));
const uni_shared_1 = require("@dcloudio/uni-shared");
const utils_1 = require("../utils");
const templateFilesCache = new Map();
const templateFiltersCache = new Map();
function relativeFilterFilename(filename, filter) {
if (!filter.src) {
return '';
}
return ('./' +
(0, utils_1.normalizeMiniProgramFilename)(path_1.default.relative(path_1.default.dirname(filename), filter.src)));
}
function findMiniProgramTemplateFiles(genFilter) {
const files = Object.create(null);
templateFilesCache.forEach((code, filename) => {
if (!genFilter) {
files[filename] = code;
}
else {
const filters = getMiniProgramTemplateFilters(filename);
if (filters && filters.length) {
files[filename] =
filters
.map((filter) => genFilter(filter, relativeFilterFilename(filename, filter)))
.join(uni_shared_1.LINEFEED) +
uni_shared_1.LINEFEED +
code;
}
else {
files[filename] = code;
}
}
});
return files;
}
exports.findMiniProgramTemplateFiles = findMiniProgramTemplateFiles;
function clearMiniProgramTemplateFiles() {
templateFilesCache.clear();
}
exports.clearMiniProgramTemplateFiles = clearMiniProgramTemplateFiles;
function addMiniProgramTemplateFile(filename, code) {
templateFilesCache.set(filename, code);
}
exports.addMiniProgramTemplateFile = addMiniProgramTemplateFile;
function getMiniProgramTemplateFilters(filename) {
return templateFiltersCache.get(filename);
}
function clearMiniProgramTemplateFilter(filename) {
templateFiltersCache.delete(filename);
}
exports.clearMiniProgramTemplateFilter = clearMiniProgramTemplateFilter;
function addMiniProgramTemplateFilter(filename, filter) {
const filters = templateFiltersCache.get(filename);
if (filters) {
const filterIndex = filters.findIndex((f) => f.id === filter.id);
if (filterIndex > -1) {
filters.splice(filterIndex, 1, filter);
}
else {
filters.push(filter);
}
}
else {
templateFiltersCache.set(filename, [filter]);
}
}
exports.addMiniProgramTemplateFilter = addMiniProgramTemplateFilter;
+67
View File
@@ -0,0 +1,67 @@
import { type ImportDeclaration, type Program } from '@babel/types';
import type { PluginContext } from 'rollup';
type BindingComponents = Record<string, {
tag: string;
type: 'unknown' | 'setup' | 'self';
}>;
interface MainDescriptor {
imports: ImportDeclaration[];
script: string;
template: string;
}
export declare function parseMainDescriptor(filename: string, ast: Program, resolve: ParseDescriptor['resolve']): Promise<MainDescriptor>;
export declare function updateMiniProgramComponentsByScriptFilename(scriptFilename: string, inputDir: string, normalizeComponentName: (name: string) => string): void;
export declare function updateMiniProgramComponentsByTemplateFilename(templateFilename: string, inputDir: string, normalizeComponentName: (name: string) => string): void;
export declare function updateMiniProgramGlobalComponents(filename: string, ast: Program, { inputDir, resolve, normalizeComponentName, }: {
inputDir: string;
resolve: ParseDescriptor['resolve'];
normalizeComponentName: (name: string) => string;
}): Promise<{
imports: ImportDeclaration[];
}>;
export declare function updateMiniProgramComponentsByMainFilename(mainFilename: string, inputDir: string, normalizeComponentName: (name: string) => string): void;
export interface TemplateDescriptor {
bindingComponents: BindingComponents;
imports: ImportDeclaration[];
}
/**
* 解析 template
* @param filename
* @param code
* @param ast
* @param options
* @returns
*/
export declare function parseTemplateDescriptor(filename: string, ast: Program, options: ParseDescriptor): Promise<TemplateDescriptor>;
interface ParseDescriptor {
resolve: PluginContext['resolve'];
isExternal: boolean;
}
export interface ScriptDescriptor extends TemplateDescriptor {
setupBindingComponents: BindingComponents;
}
/**
* 解析 script
* @param filename
* @param code
* @param ast
* @param options
* @returns
*/
export declare function parseScriptDescriptor(filename: string, ast: Program, options: ParseDescriptor): Promise<ScriptDescriptor>;
/**
* static import => dynamic import
* @param code
* @param imports
* @param dynamicImport
* @returns
*/
export declare function transformDynamicImports(code: string, imports: ImportDeclaration[], { id, sourceMap, dynamicImport, }: {
id?: string;
sourceMap?: boolean;
dynamicImport: (name: string, source: string) => string;
}): Promise<{
code: string;
map: null;
}>;
export {};
+406
View File
@@ -0,0 +1,406 @@
"use strict";
var __importDefault = (this && this.__importDefault) || function (mod) {
return (mod && mod.__esModule) ? mod : { "default": mod };
};
Object.defineProperty(exports, "__esModule", { value: true });
exports.transformDynamicImports = exports.parseScriptDescriptor = exports.parseTemplateDescriptor = exports.updateMiniProgramComponentsByMainFilename = exports.updateMiniProgramGlobalComponents = exports.updateMiniProgramComponentsByTemplateFilename = exports.updateMiniProgramComponentsByScriptFilename = exports.parseMainDescriptor = void 0;
const types_1 = require("@babel/types");
const estree_walker_1 = require("estree-walker");
const magic_string_1 = __importDefault(require("magic-string"));
const shared_1 = require("@vue/shared");
const uni_shared_1 = require("@dcloudio/uni-shared");
const messages_1 = require("../messages");
const constants_1 = require("../constants");
const utils_1 = require("../utils");
const utils_2 = require("../vite/utils");
const jsonFile_1 = require("../json/mp/jsonFile");
const mainDescriptors = new Map();
const scriptDescriptors = new Map();
const templateDescriptors = new Map();
function findImportTemplateSource(ast) {
const importDeclaration = ast.body.find((node) => (0, types_1.isImportDeclaration)(node) &&
node.source.value.includes('vue&type=template'));
if (importDeclaration) {
return importDeclaration.source.value;
}
}
function findImportScriptSource(ast) {
const importDeclaration = ast.body.find((node) => (0, types_1.isImportDeclaration)(node) && node.source.value.includes('vue&type=script'));
if (importDeclaration) {
return importDeclaration.source.value;
}
}
async function resolveSource(filename, source, resolve) {
if (!source) {
return;
}
const resolveId = await resolve(source, filename);
if (resolveId) {
return resolveId.id;
}
}
async function parseMainDescriptor(filename, ast, resolve) {
const script = await resolveSource(filename, findImportScriptSource(ast), resolve);
const template = await resolveSource(filename, findImportTemplateSource(ast), resolve);
const imports = await parseVueComponentImports(filename, ast.body.filter((node) => (0, types_1.isImportDeclaration)(node)), resolve);
if (!script) {
// inline script
await parseScriptDescriptor(filename, ast, { resolve, isExternal: false });
}
if (!template) {
// inline template
await parseTemplateDescriptor(filename, ast, { resolve, isExternal: false });
}
const descriptor = {
imports,
script: script ? (0, utils_2.parseVueRequest)(script).filename : filename,
template: template ? (0, utils_2.parseVueRequest)(template).filename : filename,
};
mainDescriptors.set(filename, descriptor);
return descriptor;
}
exports.parseMainDescriptor = parseMainDescriptor;
function updateMiniProgramComponentsByScriptFilename(scriptFilename, inputDir, normalizeComponentName) {
const mainFilename = findMainFilenameByScriptFilename(scriptFilename);
if (mainFilename) {
updateMiniProgramComponentsByMainFilename(mainFilename, inputDir, normalizeComponentName);
}
}
exports.updateMiniProgramComponentsByScriptFilename = updateMiniProgramComponentsByScriptFilename;
function updateMiniProgramComponentsByTemplateFilename(templateFilename, inputDir, normalizeComponentName) {
const mainFilename = findMainFilenameByTemplateFilename(templateFilename);
if (mainFilename) {
updateMiniProgramComponentsByMainFilename(mainFilename, inputDir, normalizeComponentName);
}
}
exports.updateMiniProgramComponentsByTemplateFilename = updateMiniProgramComponentsByTemplateFilename;
function findMainFilenameByScriptFilename(scriptFilename) {
const keys = [...mainDescriptors.keys()];
return keys.find((key) => mainDescriptors.get(key).script === scriptFilename);
}
function findMainFilenameByTemplateFilename(templateFilename) {
const keys = [...mainDescriptors.keys()];
return keys.find((key) => mainDescriptors.get(key).template === templateFilename);
}
async function updateMiniProgramGlobalComponents(filename, ast, { inputDir, resolve, normalizeComponentName, }) {
const { bindingComponents, imports } = await parseGlobalDescriptor(filename, ast, resolve);
(0, jsonFile_1.addMiniProgramUsingComponents)('app', createUsingComponents(bindingComponents, imports, inputDir, normalizeComponentName));
return {
imports,
};
}
exports.updateMiniProgramGlobalComponents = updateMiniProgramGlobalComponents;
function createUsingComponents(bindingComponents, imports, inputDir, normalizeComponentName) {
const usingComponents = {};
imports.forEach(({ source: { value }, specifiers: [specifier] }) => {
const { name } = specifier.local;
if (!bindingComponents[name]) {
return;
}
const componentName = normalizeComponentName((0, shared_1.hyphenate)(bindingComponents[name].tag));
if (!usingComponents[componentName]) {
usingComponents[componentName] = (0, uni_shared_1.addLeadingSlash)((0, utils_1.removeExt)((0, utils_1.normalizeMiniProgramFilename)(value, inputDir)));
}
});
return usingComponents;
}
function updateMiniProgramComponentsByMainFilename(mainFilename, inputDir, normalizeComponentName) {
const mainDescriptor = mainDescriptors.get(mainFilename);
if (!mainDescriptor) {
return;
}
const templateDescriptor = templateDescriptors.get(mainDescriptor.template);
if (!templateDescriptor) {
return;
}
const scriptDescriptor = scriptDescriptors.get(mainDescriptor.script);
if (!scriptDescriptor) {
return;
}
const bindingComponents = parseBindingComponents({
...templateDescriptor.bindingComponents,
...scriptDescriptor.setupBindingComponents,
}, scriptDescriptor.bindingComponents);
const imports = parseImports(mainDescriptor.imports, scriptDescriptor.imports, templateDescriptor.imports);
(0, jsonFile_1.addMiniProgramUsingComponents)((0, utils_1.removeExt)((0, utils_1.normalizeMiniProgramFilename)(mainFilename, inputDir)), createUsingComponents(bindingComponents, imports, inputDir, normalizeComponentName));
}
exports.updateMiniProgramComponentsByMainFilename = updateMiniProgramComponentsByMainFilename;
function findBindingComponent(tag, bindingComponents) {
return Object.keys(bindingComponents).find((name) => {
const componentTag = bindingComponents[name].tag;
const camelName = (0, shared_1.camelize)(componentTag);
const PascalName = (0, shared_1.capitalize)(camelName);
return tag === componentTag || tag === camelName || tag === PascalName;
});
}
function normalizeComponentId(id) {
// _unref(test) => test
if (id.includes('_unref(')) {
return id.replace('_unref(', '').replace(')', '');
}
// $setup["test"] => test
if (id.includes('$setup[')) {
return id.replace('$setup["', '').replace('"', '');
}
return id;
}
function parseBindingComponents(templateBindingComponents, scriptBindingComponents) {
const bindingComponents = {};
Object.keys(templateBindingComponents).forEach((id) => {
bindingComponents[normalizeComponentId(id)] = templateBindingComponents[id];
});
Object.keys(scriptBindingComponents).forEach((id) => {
const { tag } = scriptBindingComponents[id];
const name = findBindingComponent(tag, templateBindingComponents);
if (name) {
bindingComponents[id] = bindingComponents[name];
}
});
return bindingComponents;
}
function parseImports(mainImports, scriptImports, templateImports) {
const imports = [...mainImports, ...templateImports, ...scriptImports];
return imports;
}
/**
* 解析 template
* @param filename
* @param code
* @param ast
* @param options
* @returns
*/
async function parseTemplateDescriptor(filename, ast, options) {
// 外置时查找所有 vue component import
const imports = options.isExternal
? await parseVueComponentImports(filename, ast.body.filter((node) => (0, types_1.isImportDeclaration)(node)), options.resolve)
: [];
const descriptor = {
bindingComponents: findBindingComponents(ast.body),
imports,
};
templateDescriptors.set(filename, descriptor);
return descriptor;
}
exports.parseTemplateDescriptor = parseTemplateDescriptor;
async function parseGlobalDescriptor(filename, ast, resolve) {
// 外置时查找所有 vue component import
const imports = (await parseVueComponentImports(filename, ast.body.filter((node) => (0, types_1.isImportDeclaration)(node)), resolve)).filter((item) => !(0, utils_1.isAppVue)((0, utils_2.cleanUrl)(item.source.value)));
return {
bindingComponents: parseGlobalComponents(ast),
imports,
};
}
/**
* 解析 script
* @param filename
* @param code
* @param ast
* @param options
* @returns
*/
async function parseScriptDescriptor(filename, ast, options) {
// 外置时查找所有 vue component import
const imports = options.isExternal
? await parseVueComponentImports(filename, ast.body.filter((node) => (0, types_1.isImportDeclaration)(node)), options.resolve)
: [];
const descriptor = {
bindingComponents: parseComponents(ast),
setupBindingComponents: findBindingComponents(ast.body),
imports,
};
scriptDescriptors.set(filename, descriptor);
return descriptor;
}
exports.parseScriptDescriptor = parseScriptDescriptor;
/**
* 解析编译器生成的 bindingComponents
* @param ast
* @returns
*/
function findBindingComponents(ast) {
const mapping = findUnpluginComponents(ast);
for (const node of ast) {
if (!(0, types_1.isVariableDeclaration)(node)) {
continue;
}
const declarator = node.declarations[0];
if ((0, types_1.isIdentifier)(declarator.id) &&
declarator.id.name === constants_1.BINDING_COMPONENTS) {
const bindingComponents = JSON.parse(declarator.init.value);
return Object.keys(bindingComponents).reduce((bindings, tag) => {
const { name, type } = bindingComponents[tag];
bindings[mapping[name] || name] = {
tag,
type: type,
};
return bindings;
}, {});
}
}
return {};
}
/**
* 兼容:unplugin_components
* https://github.com/dcloudio/uni-app/issues/3057
* @param ast
* @returns
*/
function findUnpluginComponents(ast) {
const res = Object.create(null);
// if(!Array){}
const ifStatement = ast.find((statement) => (0, types_1.isIfStatement)(statement) &&
(0, types_1.isUnaryExpression)(statement.test) &&
statement.test.operator === '!' &&
(0, types_1.isIdentifier)(statement.test.argument) &&
statement.test.argument.name === 'Array');
if (!ifStatement) {
return res;
}
if (!(0, types_1.isBlockStatement)(ifStatement.consequent)) {
return res;
}
for (const node of ifStatement.consequent.body) {
if (!(0, types_1.isVariableDeclaration)(node)) {
continue;
}
const { id, init } = node.declarations[0];
if ((0, types_1.isIdentifier)(id) &&
(0, types_1.isIdentifier)(init) &&
init.name.includes('unplugin_components')) {
res[id.name] = init.name;
}
}
return res;
}
/**
* 查找全局组件定义:app.component('component-a',{})
* @param ast
* @returns
*/
function parseGlobalComponents(ast) {
const bindingComponents = {};
estree_walker_1.walk(ast, {
enter(child) {
if (!(0, types_1.isCallExpression)(child)) {
return;
}
const { callee } = child;
// .component
if (!(0, types_1.isMemberExpression)(callee) ||
!(0, types_1.isIdentifier)(callee.property) ||
callee.property.name !== 'component') {
return;
}
// .component('component-a',{})
const args = child.arguments;
if (args.length !== 2) {
return;
}
const [name, value] = args;
if (!(0, types_1.isStringLiteral)(name)) {
return console.warn(messages_1.M['mp.component.args[0]']);
}
if (!(0, types_1.isIdentifier)(value)) {
return console.warn(messages_1.M['mp.component.args[1]']);
}
bindingComponents[value.name] = {
tag: name.value,
type: 'unknown',
};
},
});
return bindingComponents;
}
/**
* 从 components 中查找定义的组件
* @param ast
* @param bindingComponents
*/
function parseComponents(ast) {
const bindingComponents = {};
estree_walker_1.walk(ast, {
enter(child) {
if (!(0, types_1.isObjectExpression)(child)) {
return;
}
const componentsProp = child.properties.find((prop) => (0, types_1.isObjectProperty)(prop) &&
(0, types_1.isIdentifier)(prop.key) &&
prop.key.name === 'components');
if (!componentsProp) {
return;
}
const componentsExpr = componentsProp.value;
if (!(0, types_1.isObjectExpression)(componentsExpr)) {
return;
}
componentsExpr.properties.forEach((prop) => {
if (!(0, types_1.isObjectProperty)(prop)) {
return;
}
if (!(0, types_1.isIdentifier)(prop.key) && !(0, types_1.isStringLiteral)(prop.key)) {
return;
}
if (!(0, types_1.isIdentifier)(prop.value)) {
return;
}
bindingComponents[prop.value.name] = {
tag: (0, types_1.isIdentifier)(prop.key) ? prop.key.name : prop.key.value,
type: 'unknown',
};
});
},
});
return bindingComponents;
}
/**
* vue component imports
* @param filename
* @param imports
* @param resolve
* @returns
*/
async function parseVueComponentImports(importer, imports, resolve) {
const vueComponentImports = [];
for (let i = 0; i < imports.length; i++) {
const { source } = imports[i];
if ((0, utils_2.parseVueRequest)(source.value).query.vue) {
continue;
}
const resolveId = await resolve(source.value, importer);
if (!resolveId) {
continue;
}
const { filename } = (0, utils_2.parseVueRequest)(resolveId.id);
if (constants_1.EXTNAME_VUE_RE.test(filename)) {
source.value = resolveId.id;
vueComponentImports.push(imports[i]);
}
}
return vueComponentImports;
}
/**
* static import => dynamic import
* @param code
* @param imports
* @param dynamicImport
* @returns
*/
async function transformDynamicImports(code, imports, { id, sourceMap, dynamicImport, }) {
if (!imports.length) {
return {
code,
map: null,
};
}
const s = new magic_string_1.default(code);
for (let i = 0; i < imports.length; i++) {
const { start, end, specifiers: [specifier], source, } = imports[i];
s.overwrite(start, end, dynamicImport(specifier.local.name, source.value) + ';');
}
return {
code: s.toString(),
map: null,
};
}
exports.transformDynamicImports = transformDynamicImports;
+2
View File
@@ -0,0 +1,2 @@
export declare function parseWxsCallMethods(code: string): string[];
export declare function genWxsCallMethodsCode(code: string): string;
+55
View File
@@ -0,0 +1,55 @@
"use strict";
Object.defineProperty(exports, "__esModule", { value: true });
exports.genWxsCallMethodsCode = exports.parseWxsCallMethods = void 0;
const types_1 = require("@babel/types");
const estree_walker_1 = require("estree-walker");
const ast_1 = require("./ast");
function parseWxsCallMethods(code) {
if (!code.includes('callMethod')) {
return [];
}
const ast = (0, ast_1.parseProgram)(code, '', {});
const wxsCallMethods = new Set();
estree_walker_1.walk(ast, {
enter(child) {
if (!(0, types_1.isCallExpression)(child)) {
return;
}
const { callee } = child;
// .callMethod
if (!(0, types_1.isMemberExpression)(callee) ||
!(0, types_1.isIdentifier)(callee.property) ||
callee.property.name !== 'callMethod') {
return;
}
// .callMethod('test',...)
const args = child.arguments;
if (!args.length) {
return;
}
const [name] = args;
if (!(0, types_1.isStringLiteral)(name)) {
return;
}
wxsCallMethods.add(name.value);
},
});
return [...wxsCallMethods];
}
exports.parseWxsCallMethods = parseWxsCallMethods;
function genWxsCallMethodsCode(code) {
const wxsCallMethods = parseWxsCallMethods(code);
if (!wxsCallMethods.length) {
return `export default {}`;
}
return `export default (Component) => {
if(!Component.wxsCallMethods){
Component.wxsCallMethods = []
}
Component.wxsCallMethods.push(${wxsCallMethods
.map((m) => `'${m}'`)
.join(', ')})
}
`;
}
exports.genWxsCallMethodsCode = genWxsCallMethodsCode;