UNPKG

@omnia/tooling-vue

Version:

Used to bundle and serve manifests web component that build on Vue framework.

230 lines (229 loc) • 11.7 kB
"use strict"; Object.defineProperty(exports, "__esModule", { value: true }); exports.dynamicBundle = void 0; const tslib_1 = require("tslib"); const path_1 = tslib_1.__importDefault(require("path")); const vite_1 = require("vite"); const webpack_1 = require("webpack"); const fx_models_1 = require("@omnia/fx-models"); const base_1 = require("../base"); const utils_1 = require("../../utils"); const $ = tslib_1.__importStar(require("../../../../variables")); function getWebpackResolveModulePath(stats, requestModulePath) { let result = ""; stats.forEach(s => { s.modules?.forEach(m => { const foundReason = m.reasons?.find(r => r.userRequest === requestModulePath); if (foundReason) { result = m.id.toString(); return result; } }); }); return result; } exports.dynamicBundle = (0, base_1.defineTransformer)("omnia-bundle", () => { const moduleMaps = {}; // bare import / relative path => module id const bundleMaps = {}; // module id => resource id const moduleMapResolvers = {}; return { test(code, id, fileGraph) { return utils_1.pathUtils.isJavaScriptSuperset(id); }, async transform(code, id, fileGraph, ctx, fromWorker) { //id.indexOf("assets/docs/") === -1 && const dynamicModules = filterDynamicModules(fileGraph, ctx); const bundledModules = dynamicModules.filter(item => item.resolved); const unBundledModules = dynamicModules.filter(item => !item.resolved); bundledModules.forEach(item => { code = item.inject(code); }); const nonResolvingModules = unBundledModules.filter(item => !moduleMaps[item.path]).map(item => ({ path: item.path, inject: item.inject })); const nonResolvingModulePaths = Array.from(new Set(nonResolvingModules.map(item => item.path))); const resolvingModules = unBundledModules.filter(item => !!moduleMaps[item.path]).map(item => moduleMaps[item.path].then(_ => { code = item.inject(code); })); if (nonResolvingModulePaths.length == 0) { await Promise.all(resolvingModules); return code; } $.tooling.log(`[${fileGraph.id}] Found new dependencies:\n` + nonResolvingModulePaths.join('\n')); $.tooling.log(`[${fileGraph.id}] Bundling dependencies...`); const dynamicBundleResourceId = fx_models_1.Guid.newGuid().toString(); const entryPoint = { ['dynamicbundle_' + dynamicBundleResourceId]: nonResolvingModulePaths }; nonResolvingModulePaths.forEach(modulePath => { moduleMaps[modulePath] = new Promise(resolve => { moduleMapResolvers[modulePath] = { resolve: resolve, resolved: false }; }); }); await new Promise(function (resolve, reject) { const configs = utils_1.webpackUtils.createWebpackConfig(entryPoint, 'dynamic'); const compiler = (0, webpack_1.webpack)(configs); compiler.run((err, stats) => { //console.log("compiler.run", err, stats) if (stats.hasErrors()) { $.tooling.log('HMR pre-bundle error : \r\n', $.tooling.LogTypes.Error); let errors = stats.toJson().errors; errors.forEach((err) => { $.tooling.log(err.stack || err, $.tooling.LogTypes.Error); }); reject(); return; } if (err) { $.tooling.log(err, $.tooling.LogTypes.Error); reject(); return; } nonResolvingModulePaths.forEach(modulePath => { try { const bareImport = modulePath.startsWith('.') ? false : true; let relativePath = modulePath; if (bareImport) { relativePath = getWebpackResolveModulePath(stats.toJson().children, modulePath); if (relativePath === "") { throw new Error(`HMR pre-bundle error : can't resolve module path for ${modulePath}`); } } const moduleId = bareImport ? ('./' + (0, vite_1.normalizePath)(relativePath.replace(utils_1.envUtils.getRootDirPath(), '.'))).toLowerCase() : ('./' + (0, vite_1.normalizePath)(path_1.default.dirname(relativePath)) + '/' + path_1.default.basename(relativePath, path_1.default.extname(relativePath)) + '.js').toLowerCase(); if (!bundleMaps[moduleId]) { bundleMaps[moduleId] = dynamicBundleResourceId; } const depFileGraph = ctx.getFileGraph(modulePath); if (!depFileGraph.js.bareImportVariable) { depFileGraph.js.bareImportVariable = toRuntimeVariable(ctx.serviceId, bundleMaps[moduleId], moduleId); depFileGraph.js.bareImportDynamicResourceId = bundleMaps[moduleId]; } if (moduleMapResolvers[modulePath] && moduleMapResolvers[modulePath].resolved == false) { moduleMapResolvers[modulePath].resolved = true; moduleMapResolvers[modulePath].resolve(moduleId); } else if (!moduleMaps[modulePath]) { moduleMaps[modulePath] = Promise.resolve(moduleId); } } catch (err) { console.error(`HMR pre-bundle error : module path ${modulePath} -> ${err}`); } }); Promise.all(resolvingModules).then(() => resolve()); //resolve(); }); }); nonResolvingModules.forEach(resolvedModule => { code = resolvedModule.inject(code); }); $.tooling.log(`[${fileGraph.id}] Bundle dependencies done`); return code; } }; }); function filterDynamicModules(fileGraph, ctx) { const requires = fileGraph.js.metadata.requires; const imports = fileGraph.js.metadata.imports; const esModules = [ ...imports.defaultVariables.filter(item => filterBareImport(item, ctx)).map(item => ({ path: item.path, resolved: isBareImportResolved(item, ctx), inject(code) { if (!code.includes(item.statement)) { return code; } const depFileGraph = ctx.getFileGraph(item.path); code = ensureBundleInjection(code, depFileGraph.js.bareImportDynamicResourceId); code = utils_1.transformUtils.injectDefaultImportVariableDecleration(code); return code.replace(item.statement, `const ${item.default} = ${utils_1.transformUtils.wrapDefaultImportVariable(depFileGraph.js.bareImportVariable)}`); } })), ...imports.namedVariables.filter(item => filterBareImport(item, ctx)).map(item => ({ path: item.path, resolved: isBareImportResolved(item, ctx), inject(code) { if (!code.includes(item.statement)) { return code; } const depFileGraph = ctx.getFileGraph(item.path); const varString = item.values.join(', '); const asVarString = Object.keys(item.asValues).map(k => `${k} as ${item.asValues[k]}`).join(', '); const allVarString = varString.length > 0 && asVarString.length > 0 ? [varString, asVarString].join(', ') : varString.length > 0 ? varString : asVarString; code = ensureBundleInjection(code, depFileGraph.js.bareImportDynamicResourceId); return code.replace(item.statement, `const { ${allVarString} } = ${depFileGraph.js.bareImportVariable}`); } })), ...imports.noneVariables.filter(item => filterBareImport(item, ctx)).map(item => ({ path: item.path, resolved: isBareImportResolved(item, ctx), inject(code) { if (!code.includes(item.statement)) { return code; } const depFileGraph = ctx.getFileGraph(item.path); code = ensureBundleInjection(code, depFileGraph.js.bareImportDynamicResourceId); return code.replace(item.statement, depFileGraph.js.bareImportVariable); } })), ...imports.wildcardVariables.filter(item => filterBareImport(item, ctx)).map(item => ({ path: item.path, resolved: isBareImportResolved(item, ctx), inject(code) { if (!code.includes(item.statement)) { return code; } const depFileGraph = ctx.getFileGraph(item.path); code = ensureBundleInjection(code, depFileGraph.js.bareImportDynamicResourceId); return code.replace(item.statement, `const ${item.value} = ${depFileGraph.js.bareImportVariable}`); } })) ]; const cjsModules = requires.filter(item => filterBareImport(item, ctx)).map(item => ({ path: item.path, resolved: isBareImportResolved(item, ctx), inject(code) { if (!code.includes(item.statement)) { return code; } const depFileGraph = ctx.getFileGraph(item.path); code = ensureBundleInjection(code, depFileGraph.js.bareImportDynamicResourceId); code = utils_1.transformUtils.injectDefaultImportVariableDecleration(code); return code.replace(item.statement, utils_1.transformUtils.wrapDefaultImportVariable(depFileGraph.js.bareImportVariable)); } })); // TODO: support re-export for bare imports return [ ...esModules, ...cjsModules ]; } function ensureBundleInjection(code, resourceId) { const injection = `import '${utils_1.pathUtils.HMR_DYNAMIC_BUNDLE_REQUEST}/${resourceId}'`; if (code.includes(injection) == false) { code = '\n' + injection + '\n' + code; } return code; } function filterBareImport(item, ctx) { const depFileGraph = ctx.getFileGraph(item.path); // skip omnia packages since they only contain typing files return depFileGraph && depFileGraph.id.startsWith(`./${$.tooling.composer.getAssetsDir()}/docs/`) == false && depFileGraph.id.startsWith('@omnia') == false && !ctx.alias[depFileGraph.id] && depFileGraph.bareImport && depFileGraph.js; } function isBareImportResolved(item, ctx) { const depFileGraph = ctx.getFileGraph(item.path); return !!depFileGraph.js.bareImportVariable; } function toRuntimeVariable(serviceId, resourceId, moduleId) { return `omniaWebpackJsonp['${serviceId}']['${resourceId}']('${moduleId}')`; }