You can not select more than 25 topics Topics must start with a letter or number, can include dashes ('-') and can be up to 35 characters long.

281 lines
12 KiB

This file contains ambiguous Unicode characters!

This file contains ambiguous Unicode characters that may be confused with others in your current locale. If your use case is intentional and legitimate, you can safely ignore this warning. Use the Escape button to highlight these characters.

"use strict";
var __importDefault = (this && this.__importDefault) || function (mod) {
return (mod && mod.__esModule) ? mod : { "default": mod };
};
Object.defineProperty(exports, "__esModule", { value: true });
exports.initUniXCompilerRootWorkers = exports.uniJavaScriptWorkersPlugin = exports.resolveWorkersDir = exports.uniWorkersPlugin = exports.initWorkers = exports.getWorkersRootDirs = exports.resolveWorkersRootDir = exports.getWorkers = void 0;
const path_1 = __importDefault(require("path"));
const fs_extra_1 = __importDefault(require("fs-extra"));
const debug_1 = __importDefault(require("debug"));
const fast_glob_1 = require("fast-glob");
const utils_1 = require("./utils");
const json_1 = require("./json");
const uts_1 = require("./uts");
const uni_modules_1 = require("./vite/plugins/uts/uni_modules");
const resolve_1 = require("./resolve");
const debugWorkers = (0, debug_1.default)('uni:workers');
let workersRootDir = null;
let workersRootDirs = [];
let workers = {};
function getWorkers() {
return workers;
}
exports.getWorkers = getWorkers;
function resolveWorkersRootDir() {
// 默认是 workers
return workersRootDir || 'workers';
}
exports.resolveWorkersRootDir = resolveWorkersRootDir;
function getWorkersRootDirs() {
return workersRootDirs;
}
exports.getWorkersRootDirs = getWorkersRootDirs;
/**
* 遍历目录下的所有uts文件读取文件内容正则匹配出定义的worker返回文件名和类名的映射关系
* export class MyWorkerTask extends WorkerTaskImpl {}
* @param dir
*/
function initWorkers(workersDirs, rootDir) {
workers = {};
for (const workersDir of workersDirs) {
const dir = path_1.default.join(rootDir, workersDir);
if (!fs_extra_1.default.existsSync(dir)) {
continue;
}
(0, fast_glob_1.sync)('**/*.uts', { cwd: dir }).forEach((file) => {
const content = fs_extra_1.default.readFileSync(path_1.default.join(dir, file), 'utf-8');
const match = content.match(/class\s+(.*)\s+extends\s+WorkerTaskImpl/);
if (match && match[1]) {
const key = (0, utils_1.normalizePath)(path_1.default.join(workersDir, file));
workers[key] = match[1];
}
});
}
debugWorkers('workers', workers);
return workers;
}
exports.initWorkers = initWorkers;
function uniWorkersPlugin() {
const inputDir = process.env.UNI_INPUT_DIR;
const platform = process.env.UNI_UTS_PLATFORM;
const resolveWorkers = () => getWorkers();
function refreshWorkers() {
workersRootDirs = resolveWorkersDir(inputDir);
initWorkers(workersRootDirs, inputDir);
return Object.keys(getWorkers()).length > 0;
}
refreshWorkers();
const preprocessor = platform === 'app-android'
? (0, uni_modules_1.createAppAndroidUniModulesSyncFilePreprocessorOnce)(false)
: platform === 'app-ios'
? (0, uni_modules_1.createAppIosUniModulesSyncFilePreprocessorOnce)(false)
: platform === 'app-harmony'
? (0, uni_modules_1.createAppHarmonyUniModulesSyncFilePreprocessorOnce)(false)
: null;
const cache = {};
const uniXKotlinCompiler = platform === 'app-android'
? (0, uts_1.resolveUTSCompiler)().createUniXKotlinCompilerOnce({
resolveWorkers,
})
: null;
const uniXSwiftCompiler = platform === 'app-ios'
? (0, uts_1.resolveUTSCompiler)().createUniXSwiftCompilerOnce({
resolveWorkers,
})
: null;
const uniXArkTSCompiler = platform === 'app-harmony'
? (0, uts_1.resolveUTSCompiler)().createUniXArkTSCompilerOnce({
resolveWorkers,
})
: null;
return {
name: 'uni-workers',
enforce: 'pre',
async buildStart() {
if (refreshWorkers()) {
if (preprocessor) {
await syncWorkersFiles(platform, inputDir, preprocessor, cache);
}
}
// 需要等待 workers 文件同步完之后,添加到 rootFiles 中,触发 tsc 的编译
if (uniXKotlinCompiler) {
await initUniXCompilerRootWorkers((0, uts_1.tscOutDir)('app-android'), uniXKotlinCompiler);
}
if (uniXSwiftCompiler) {
await initUniXCompilerRootWorkers((0, uts_1.tscOutDir)('app-ios'), uniXSwiftCompiler);
}
if (uniXArkTSCompiler) {
await initUniXCompilerRootWorkers((0, uts_1.tscOutDir)('app-harmony'), uniXArkTSCompiler);
}
},
};
}
exports.uniWorkersPlugin = uniWorkersPlugin;
async function syncWorkersFiles(platform, inputDir, preprocessor, cache) {
if (platform !== 'app-harmony' &&
platform !== 'app-android' &&
platform !== 'app-ios') {
return;
}
const workersDirs = resolveWorkersDir(inputDir);
if (workersDirs.length) {
const { syncUTSFiles } = (0, uts_1.resolveUTSCompiler)();
for (const workersDir of workersDirs) {
await syncUTSFiles((0, utils_1.normalizePath)(path_1.default.join(workersDir, '**/*.uts')), inputDir, (0, uts_1.tscOutDir)(platform), true, preprocessor, cache);
}
}
}
function resolveWorkersDir(inputDir) {
const workersDirs = [];
const manifestJson = (0, json_1.parseManifestJsonOnce)(inputDir);
if (manifestJson.workers) {
let workersDir = typeof manifestJson.workers === 'string'
? manifestJson.workers
: manifestJson.workers.path;
if (workersDir) {
workersDir = (0, utils_1.normalizePath)(workersDir);
const dir = path_1.default.join(inputDir, workersDir);
if (fs_extra_1.default.existsSync(dir)) {
workersRootDir = workersDir;
workersDirs.push(workersDir);
}
}
}
// 遍历uni_modules插件目录是否有workers目录
const uniModulesDir = path_1.default.join(inputDir, 'uni_modules');
if (fs_extra_1.default.existsSync(uniModulesDir)) {
fs_extra_1.default.readdirSync(uniModulesDir).forEach((dir) => {
if (fs_extra_1.default.existsSync(path_1.default.join(uniModulesDir, dir, 'workers'))) {
workersDirs.push('uni_modules/' + dir + '/workers');
}
});
}
debugWorkers('workersDirs', workersDirs);
return workersDirs;
}
exports.resolveWorkersDir = resolveWorkersDir;
function uniJavaScriptWorkersPlugin() {
// 仅小程序平台外置uni-worker.mp.js
const external = (process.env.UNI_UTS_PLATFORM || '').startsWith('mp-');
let workerPolyfillCode = '';
let isWrite = false;
const UniAppWorkerJSName = external ? 'uni-worker.mp.js' : 'uni-worker.web.js';
let viteServer = null;
const workersRootPaths = [];
const workerPolyfillPath = `@dcloudio/uni-app/dist-x/${UniAppWorkerJSName}`;
const workerPolyfillAbsPath = (0, utils_1.normalizePath)((0, resolve_1.resolveBuiltIn)(workerPolyfillPath));
function isWorkerFile(id) {
if (workersRootPaths.length) {
return workersRootPaths.some((dir) => id.startsWith(dir));
}
return false;
}
function parseWorkerEntryFile(workerJsPath) {
const workerPath = workerJsPath.slice(1).replace('.js', '.uts');
if (workerPath in workers) {
return (0, utils_1.normalizePath)(path_1.default.resolve(process.env.UNI_INPUT_DIR, workerPath));
}
}
function parseWorkerClass(id) {
const filename = id.split('?')[0];
if (isWorkerFile(filename)) {
const workerPath = (0, utils_1.normalizePath)(path_1.default.relative(process.env.UNI_INPUT_DIR, filename));
return workers[workerPath] || '';
}
return false;
}
return {
name: 'uni:javascript-workers',
configureServer(server) {
viteServer = server;
},
buildStart() {
if (!workerPolyfillCode && Object.keys(getWorkers()).length) {
workerPolyfillCode = fs_extra_1.default.readFileSync(workerPolyfillAbsPath, 'utf-8');
}
workersRootPaths.length = 0;
for (const workersRootDir of getWorkersRootDirs()) {
workersRootPaths.push((0, utils_1.normalizePath)(path_1.default.resolve(process.env.UNI_INPUT_DIR, workersRootDir)));
}
},
resolveId(id) {
// uni.createWorker('workers/request/index.uts')
// 编译阶段调整为 uni.createWorker('workers/request/index.js'),确保开发和运行时都是用.js后缀加载
// 不调整成js后缀或.uts?import这些格式 vite 是不会走transform逻辑的而是直接读取文件内容
if (viteServer) {
const workerEntryFile = parseWorkerEntryFile(id);
if (workerEntryFile) {
return workerEntryFile;
}
if (id === workerPolyfillPath) {
return workerPolyfillAbsPath;
}
}
},
load(id) {
const filename = id.split('?')[0];
const workerClass = parseWorkerClass(filename);
if (workerClass === false) {
return;
}
if (fs_extra_1.default.existsSync(filename)) {
let code = (viteServer ? `import '${workerPolyfillPath}';` : '') +
fs_extra_1.default
.readFileSync(filename, 'utf-8')
// 移除 export
.replace(/export\s+class\s+(.*)\s+extends\s+WorkerTaskImpl\s*{/, 'class $1 extends WorkerTaskImpl {');
// 如果是入口文件,需要追加初始化代码
if (workerClass) {
code += `\n;new ${workerClass}().entry()`;
}
return code;
}
},
generateBundle(_, bundle) {
const workers = getWorkers();
const workerRootDir = resolveWorkersRootDir();
const workerPaths = Object.keys(workers).map((key) => {
if (key.startsWith('uni_modules')) {
key = workerRootDir + '/' + key;
}
return key.replace('.uts', '.js');
});
if (workerPaths.length) {
Object.keys(bundle).forEach((file) => {
if (workerPaths.includes(file)) {
const chunk = bundle[file];
if (chunk.type === 'chunk') {
const workerCode = external
? `require('${(0, utils_1.normalizePath)(path_1.default.relative(path_1.default.dirname(file), path_1.default.join(resolveWorkersRootDir(), 'uni-worker.js')))}')`
: workerPolyfillCode;
chunk.code = `${workerCode}\n${chunk.code}`;
}
}
});
}
},
writeBundle() {
if (external && Object.keys(getWorkers()).length && !isWrite) {
isWrite = true;
// 写入uni-worker.js
fs_extra_1.default.outputFileSync(path_1.default.resolve(process.env.UNI_OUTPUT_DIR, resolveWorkersRootDir(), 'uni-worker.js'), workerPolyfillCode);
}
},
};
}
exports.uniJavaScriptWorkersPlugin = uniJavaScriptWorkersPlugin;
async function initUniXCompilerRootWorkers(rootDir, compiler) {
const workers = getWorkers();
if (Object.keys(workers).length) {
for (const key in workers) {
const file = path_1.default.join(rootDir, key + '.ts');
if (fs_extra_1.default.existsSync(file)) {
if (!compiler.hasRootFile(file)) {
await compiler.addRootFile(file);
}
}
}
}
}
exports.initUniXCompilerRootWorkers = initUniXCompilerRootWorkers;