269 lines
10 KiB
JavaScript
269 lines
10 KiB
JavaScript
"use strict";
|
||
var __importDefault = (this && this.__importDefault) || function (mod) {
|
||
return (mod && mod.__esModule) ? mod : { "default": mod };
|
||
};
|
||
Object.defineProperty(exports, "__esModule", { value: true });
|
||
exports.createErrorWithBlockFlag = exports.errorFormatter = exports.removeDuplicatePluginFormatter = exports.removeWarnFormatter = exports.removeInfoFormatter = exports.h5ServeFormatter = exports.formatAtFilename = void 0;
|
||
const fs_1 = __importDefault(require("fs"));
|
||
const path_1 = __importDefault(require("path"));
|
||
const picocolors_1 = __importDefault(require("picocolors"));
|
||
const compiler_core_1 = require("@vue/compiler-core");
|
||
const shared_1 = require("@vue/shared");
|
||
const utils_1 = require("../utils");
|
||
const utils_2 = require("./utils");
|
||
const constants_1 = require("../constants");
|
||
const ast_1 = require("../vite/utils/ast");
|
||
const utils_3 = require("../vite/plugins/vitejs/utils");
|
||
const SIGNAL_H5_LOCAL = ' ➜ Local:';
|
||
const SIGNAL_H5_NETWORK = ' ➜ Network:';
|
||
const networkLogs = [];
|
||
const ZERO_WIDTH_CHAR = {
|
||
NOTE: '',
|
||
WARNING: '\u200B',
|
||
ERROR: '\u200C',
|
||
backup0: '\u200D', // 标记换行
|
||
backup1: '\u200E',
|
||
backup2: '\u200F',
|
||
backup3: '\uFEFF',
|
||
};
|
||
function overridedConsole(name, oldFn, char) {
|
||
console[name] = function (...args) {
|
||
oldFn.apply(this, args.map((arg) => {
|
||
let item;
|
||
if ((0, utils_2.isInHBuilderX)() && typeof arg === 'string' && arg.includes('\n')) {
|
||
arg = arg
|
||
.split('\n')
|
||
.map((line) => `${char}${line}${char}`)
|
||
.join('\n');
|
||
}
|
||
if (typeof arg !== 'object') {
|
||
item = `${char}${arg}${char}`;
|
||
}
|
||
else {
|
||
item = `${char}${JSON.stringify(arg)}${char}`;
|
||
}
|
||
return item;
|
||
}));
|
||
};
|
||
}
|
||
if (typeof console !== 'undefined') {
|
||
overridedConsole('warn', console.log, ZERO_WIDTH_CHAR.WARNING);
|
||
// overridedConsole('error', console.error, ZERO_WIDTH_CHAR.ERROR)
|
||
}
|
||
function formatAtFilename(filename, line, column) {
|
||
filename = filename.replace('\x00', '').split('?')[0];
|
||
const file = process.env.UNI_INPUT_DIR
|
||
? path_1.default.relative(process.env.UNI_INPUT_DIR, filename)
|
||
: filename;
|
||
return `at ${picocolors_1.default.cyan((0, utils_1.normalizePath)(file === 'pages-json-uts' ? 'pages.json' : file) +
|
||
':' +
|
||
(line || 1) +
|
||
':' +
|
||
(column || 0))}`;
|
||
}
|
||
exports.formatAtFilename = formatAtFilename;
|
||
exports.h5ServeFormatter = {
|
||
test(msg) {
|
||
return msg.includes(SIGNAL_H5_LOCAL) || msg.includes(SIGNAL_H5_NETWORK);
|
||
},
|
||
format(msg) {
|
||
if (msg.includes(SIGNAL_H5_NETWORK)) {
|
||
networkLogs.push(msg.replace('➜ ', '*'));
|
||
process.nextTick(() => {
|
||
if (networkLogs.length) {
|
||
// 延迟打印所有 network,仅最后一个 network 替换 ➜ 为 -,通知 hbx
|
||
const len = networkLogs.length - 1;
|
||
networkLogs[len] = networkLogs[len].replace('* Network', '- Network');
|
||
console.log(networkLogs.join('\n'));
|
||
networkLogs.length = 0;
|
||
}
|
||
});
|
||
return '';
|
||
}
|
||
if (msg.includes(SIGNAL_H5_LOCAL)) {
|
||
return msg.replace('➜ ', '-');
|
||
}
|
||
return msg.replace('➜ ', '*');
|
||
},
|
||
};
|
||
const REMOVED_MSGS = [
|
||
'build started...',
|
||
(msg) => {
|
||
return /built in [0-9]+ms\./.test(msg);
|
||
},
|
||
'watching for file changes...',
|
||
];
|
||
exports.removeInfoFormatter = {
|
||
test(msg) {
|
||
return !!REMOVED_MSGS.find((m) => ((0, shared_1.isString)(m) ? msg.includes(m) : m(msg)));
|
||
},
|
||
format() {
|
||
return '';
|
||
},
|
||
};
|
||
const REMOVED_WARN_MSGS = [];
|
||
exports.removeWarnFormatter = {
|
||
test(msg) {
|
||
return !!REMOVED_WARN_MSGS.find((m) => msg.includes(m));
|
||
},
|
||
format() {
|
||
return '';
|
||
},
|
||
};
|
||
exports.removeDuplicatePluginFormatter = {
|
||
test() {
|
||
return true;
|
||
},
|
||
format(msg) {
|
||
// [plugin:vite:vue] [plugin vite:vue]
|
||
// 正则匹配获取第一个插件名称,然后移除 [plugin vite:vue]
|
||
const pluginName = msg.match(/\[plugin\s([^\]]+)\]/)?.[1];
|
||
if (pluginName) {
|
||
return msg.replace(`[plugin ${pluginName}]`, '');
|
||
}
|
||
return msg;
|
||
},
|
||
};
|
||
exports.errorFormatter = {
|
||
test(_, opts) {
|
||
return !!(opts && opts.error);
|
||
},
|
||
format(_, opts) {
|
||
return buildErrorMessage(opts.error, [], false);
|
||
},
|
||
};
|
||
function createErrorWithBlockFlag(msg) {
|
||
const error = new Error(msg);
|
||
error.__errorBlocked = true;
|
||
return error;
|
||
}
|
||
exports.createErrorWithBlockFlag = createErrorWithBlockFlag;
|
||
let shouldAddErrorBlock = null;
|
||
const VITE_ROLLUP_FAILED_TO_RESOLVE_IMPORT_RE = /\[vite\]: Rollup failed to resolve import "([^"]+)" from "([^"]+)"/;
|
||
const CANNOT_FIND_MODULE_RE = /Cannot find module '([^']+)' from '([^']+)'/;
|
||
function buildErrorMessage(err, args = [], includeStack = true) {
|
||
if (err.customPrint) {
|
||
err.customPrint();
|
||
return '';
|
||
}
|
||
if (VITE_ROLLUP_FAILED_TO_RESOLVE_IMPORT_RE.test(err.message)) {
|
||
const [, importPath, fromPath] = err.message.match(VITE_ROLLUP_FAILED_TO_RESOLVE_IMPORT_RE) || [];
|
||
err.message = `Could not resolve "${importPath}" from "${fromPath}"`;
|
||
err.id = fromPath;
|
||
}
|
||
if (CANNOT_FIND_MODULE_RE.test(err.message)) {
|
||
const [, modulePath, fromPath] = err.message.match(CANNOT_FIND_MODULE_RE) || [];
|
||
// 清理模块路径和来源路径,移除查询参数等
|
||
const cleanModulePath = modulePath.split('?')[0];
|
||
const cleanFromPath = fromPath.split('?')[0];
|
||
const relativeFromPath = toRelativePath(cleanFromPath);
|
||
// 构建更友好的错误消息
|
||
err.id = cleanFromPath;
|
||
err.message = `Cannot find module "${cleanModulePath}" from "${relativeFromPath}"`;
|
||
}
|
||
// 移除 from 后面的内容
|
||
// 主要是处理:Could not resolve "./static/logo1.png" from "../../../../../../Users/xxx/HBuilderProjects/test-x/pages/index/index.uvue?vue&type=script&lang.uts"
|
||
if (err.id && err.message.startsWith('Could not resolve ')) {
|
||
err.message = err.message.split(' from ')[0];
|
||
}
|
||
if (err.plugin) {
|
||
// 避免出现这样的错误:[plugin:vite:vue] [plugin vite:vue]
|
||
if (err.message.startsWith(`[plugin ${err.plugin}]`)) {
|
||
let msg = err.message.replace(`[plugin ${err.plugin}]`, '');
|
||
if (err.loc) {
|
||
// [plugin:vite:vue] pages/index/index.vue (2:12): v-on="" is not supported
|
||
const locStr = `(${err.loc.line}:${err.loc.column}):`;
|
||
if (msg.includes(locStr)) {
|
||
msg = msg.split(locStr)[1].trim();
|
||
}
|
||
}
|
||
args.push(`${picocolors_1.default.magenta('[plugin:' + err.plugin + ']')} ${picocolors_1.default.red(msg)}`);
|
||
}
|
||
else {
|
||
const otherMsgs = [];
|
||
if (err.message.includes(': [plugin ')) {
|
||
const messages = err.message.split(': [plugin ');
|
||
err.message = messages[0];
|
||
messages.slice(1).forEach((msg) => {
|
||
otherMsgs.push(`[plugin:${msg}`);
|
||
});
|
||
}
|
||
if (err.loc) {
|
||
// [plugin:vite:vue] pages/index/index.vue (2:12): v-on="" is not supported
|
||
const locStr = `(${err.loc.line}:${err.loc.column}):`;
|
||
if (err.message.includes(locStr)) {
|
||
err.message = err.message.split(locStr)[1].trim();
|
||
}
|
||
}
|
||
args.push(`${picocolors_1.default.magenta('[plugin:' + err.plugin + ']')} ${picocolors_1.default.red(err.message)}`);
|
||
args.push(...otherMsgs);
|
||
if (err.loc &&
|
||
err.hook === 'transform' &&
|
||
err.plugin === 'rollup-plugin-dynamic-import-variables' &&
|
||
err.id &&
|
||
constants_1.EXTNAME_VUE_RE.test(err.id)) {
|
||
try {
|
||
const ast = (0, ast_1.parseVue)(fs_1.default.readFileSync(err.id, 'utf8'), []);
|
||
const scriptNode = ast.children.find((node) => node.type === compiler_core_1.NodeTypes.ELEMENT && node.tag === 'script');
|
||
if (scriptNode) {
|
||
const scriptLoc = scriptNode.loc;
|
||
args.push(picocolors_1.default.yellow(pad((0, utils_3.generateCodeFrame)(scriptLoc.source, err.loc))));
|
||
// correct error location
|
||
err.loc.line = scriptLoc.start.line + err.loc.line - 1;
|
||
}
|
||
}
|
||
catch (e) { }
|
||
}
|
||
}
|
||
}
|
||
else {
|
||
args.push(picocolors_1.default.red(err.message));
|
||
}
|
||
if (err.id) {
|
||
args.push(formatAtFilename(err.id, err.loc?.line, err.loc?.column));
|
||
}
|
||
if (err.frame) {
|
||
args.push(picocolors_1.default.yellow(pad(err.frame)));
|
||
}
|
||
if (includeStack && err.stack) {
|
||
args.push(pad(cleanStack(err.stack)));
|
||
}
|
||
if (shouldAddErrorBlock === null) {
|
||
shouldAddErrorBlock = // 目前仅限 x 的 app 平台
|
||
process.env.UNI_APP_X === 'true' &&
|
||
(process.env.UNI_UTS_PLATFORM === 'app-android' ||
|
||
process.env.UNI_UTS_PLATFORM === 'app-ios' ||
|
||
process.env.UNI_UTS_PLATFORM === 'app-harmony');
|
||
}
|
||
if (shouldAddErrorBlock) {
|
||
if (!err.__errorBlocked) {
|
||
args[0] = constants_1.SPECIAL_CHARS.ERROR_BLOCK + args[0];
|
||
args[args.length - 1] = args[args.length - 1] + constants_1.SPECIAL_CHARS.ERROR_BLOCK;
|
||
}
|
||
}
|
||
return args.join('\n');
|
||
}
|
||
function cleanStack(stack) {
|
||
return stack
|
||
.split(/\n/g)
|
||
.filter((l) => /^\s*at/.test(l))
|
||
.join('\n');
|
||
}
|
||
const splitRE = /\r?\n/;
|
||
function pad(source, n = 2) {
|
||
const lines = source.split(splitRE);
|
||
return lines.map((l) => ` `.repeat(n) + l).join(`\n`);
|
||
}
|
||
function toRelativePath(filePath) {
|
||
if (!filePath || !process.env.UNI_INPUT_DIR) {
|
||
return filePath;
|
||
}
|
||
try {
|
||
return path_1.default.relative(process.env.UNI_INPUT_DIR, filePath);
|
||
}
|
||
catch (e) {
|
||
// 转换失败时返回原路径
|
||
return filePath;
|
||
}
|
||
}
|