Skip to content

Commit

Permalink
moduleBundler: Pass original file name to search for corresponding so…
Browse files Browse the repository at this point in the history
…urce maps
  • Loading branch information
RandomByte committed Feb 14, 2022
1 parent 5d5e7fb commit 7b51d11
Show file tree
Hide file tree
Showing 9 changed files with 91 additions and 80 deletions.
1 change: 0 additions & 1 deletion lib/builder/BuildContext.js
Original file line number Diff line number Diff line change
Expand Up @@ -6,7 +6,6 @@ const ProjectBuildContext = require("./ProjectBuildContext");
const GLOBAL_TAGS = Object.freeze({
IsDebugVariant: "ui5:IsDebugVariant",
HasDebugVariant: "ui5:HasDebugVariant",
SourceMappingUrl: "ui5:SourceMappingUrl"
});

/**
Expand Down
2 changes: 1 addition & 1 deletion lib/builder/ProjectBuildContext.js
Original file line number Diff line number Diff line change
Expand Up @@ -4,7 +4,7 @@ const ResourceTagCollection = require("@ui5/fs").ResourceTagCollection;
// (Type "module:@ui5/builder.tasks.TaskUtil~StandardBuildTags")
const STANDARD_TAGS = {
OmitFromBuildResult: "ui5:OmitFromBuildResult",
IsBundle: "ui5:IsBundle"
IsBundle: "ui5:IsBundle",
};

/**
Expand Down
121 changes: 70 additions & 51 deletions lib/lbt/bundle/Builder.js
Original file line number Diff line number Diff line change
Expand Up @@ -216,8 +216,11 @@ class BundleBuilder {
closeModule(resolvedModule) {
if ( resolvedModule.containsCore ) {
this.outW.ensureNewLine(); // for clarity and to avoid issues with single line comments
this.outW.writeln(`// as this module contains the Core, we ensure that the Core has been booted`);
this.outW.writeln(`sap.ui.getCore().boot && sap.ui.getCore().boot();`);
const coreBoot = `// as this module contains the Core, we ensure that the Core has been booted\n` +
`sap.ui.getCore().boot && sap.ui.getCore().boot();`;
const sourceMap = this.createTransitiveSourceMap("coreBoot", coreBoot, true)
this.addSourceMap("coreBoot", sourceMap);
this.outW.writeln(coreBoot);
}
if ( this.shouldDecorate && this.options.addTryCatchRestartWrapper ) {
this.outW.ensureNewLine(); // for clarity and to avoid issues with single line comments
Expand Down Expand Up @@ -299,7 +302,7 @@ class BundleBuilder {
({moduleContent, moduleSourceMap} = await this.getSourceMapForModule(moduleName, moduleContent, resource));

if (moduleSourceMap) {
await this.addSourceMap(moduleName, moduleSourceMap);
this.addSourceMap(moduleName, moduleSourceMap);
}
}
this.outW.write(moduleContent);
Expand Down Expand Up @@ -352,7 +355,7 @@ class BundleBuilder {
sequence.sort();
}

async addSourceMap(moduleName, map) {
addSourceMap(moduleName, map) {
if (!map) {
throw new Error("No source map provided");
}
Expand Down Expand Up @@ -399,7 +402,7 @@ class BundleBuilder {
outW.startSegment(moduleName);
outW.ensureNewLine();
if (sourceMap) {
await this.addSourceMap(moduleName, sourceMap);
this.addSourceMap(moduleName, sourceMap);
}
outW.write(content);
outW.ensureNewLine();
Expand Down Expand Up @@ -443,11 +446,10 @@ class BundleBuilder {
let moduleContent = (await resource.buffer()).toString();
if (this.options.sourceMap) {
let moduleSourceMap;
({moduleContent, moduleSourceMap} =
await this.getSourceMapForModule(moduleName, moduleContent, resource));
({moduleContent, moduleSourceMap} = await this.getSourceMapForModule(moduleName, moduleContent, resource));

if (moduleSourceMap) {
await this.addSourceMap(moduleName, moduleSourceMap);
this.addSourceMap(moduleName, moduleSourceMap);
}
}
outW.write(moduleContent);
Expand Down Expand Up @@ -548,66 +550,83 @@ class BundleBuilder {
let moduleSourceMap = null;
let newModuleContent = moduleContent;

let sourceMapUrl = resource.getSourceMappingUrl();
if (!sourceMapUrl) {
const sourceMapUrlMatch = moduleContent.match(sourceMapUrlPattern);
if (sourceMapUrlMatch) {
sourceMapUrl = sourceMapUrlMatch[1];

// Strip sourceMappingURL from module code to be bundled
// It has no effect and might be cause for confusion
newModuleContent = moduleContent.replace(sourceMapUrlPattern, "");
}
}

if (sourceMapUrl) {
if (sourceMapUrl.startsWith("data:")) {
// Data-URL indicates an inline source map
const expectedTypeAndEncoding = "data:application/json;charset=utf-8;base64,";
if (sourceMapUrl.startsWith(expectedTypeAndEncoding)) {
const base64Content = sourceMapUrl.slice(expectedTypeAndEncoding.length);
moduleSourceMap = Buffer.from(base64Content, "base64").toString();
const sourceMapUrlMatch = moduleContent.match(sourceMapUrlPattern);
if (sourceMapUrlMatch) {
const sourceMapUrl = sourceMapUrlMatch[1];

// Strip sourceMappingURL from module code to be bundled
// It has no effect and might be cause for confusion
newModuleContent = moduleContent.replace(sourceMapUrlPattern, "");

if (sourceMapUrl) {
if (sourceMapUrl.startsWith("data:")) {
// Data-URL indicates an inline source map
const expectedTypeAndEncoding = "data:application/json;charset=utf-8;base64,";
if (sourceMapUrl.startsWith(expectedTypeAndEncoding)) {
const base64Content = sourceMapUrl.slice(expectedTypeAndEncoding.length);
moduleSourceMap = Buffer.from(base64Content, "base64").toString();
} else {
log.warn("TODO");
}
} else {
log.warn("TODO");
}
} else {
if (path.posix.isAbsolute(sourceMapUrl)) {
log.warn("Unexpected absolute source map path");
}
if (path.posix.isAbsolute(sourceMapUrl)) {
log.warn("Unexpected absolute source map path");
}

// TODO: Check for actual URL, which is not supported
// TODO: Check for actual URL, which is not supported

const sourceMapPath = path.posix.join(path.posix.dirname(moduleName), sourceMapUrl);
const sourceMapPath = path.posix.join(path.posix.dirname(moduleName), sourceMapUrl);

try {
const sourceMapResource = await this.pool.findResource(sourceMapPath);
moduleSourceMap = (await sourceMapResource.buffer()).toString();
} catch (e) {
// No input source map
// TODO: Differentiate real errors from file not found
try {
const sourceMapResource = await this.pool.findResource(sourceMapPath);
moduleSourceMap = (await sourceMapResource.buffer()).toString();
} catch (e) {
// No input source map
// TODO: Differentiate real errors from file not found
}
}
}
}

if (!moduleSourceMap) {
moduleSourceMap = {
"version": 3,
"sources": [moduleName],
"sourcesContent": [moduleContent],
// TODO: check whether moduleContent.match() with \n is better w.r.t performance/memory usage
"mappings": encodeMappings(moduleContent.split("\n").map((line, i) => {
return [[0, 0, i, 0]];
}))
};
} else {
try {
const sourceMapResource = await this.pool.findResource(resource.getRealResourcePath() + ".map");
if (sourceMapResource) {
moduleSourceMap = (await sourceMapResource.buffer()).toString();
}
} catch (e) {
// No input source map
// TODO: Differentiate real errors from file not found
}
}

if (moduleSourceMap) {
moduleSourceMap = JSON.parse(moduleSourceMap);
} else {
moduleSourceMap = this.createTransitiveSourceMap(path.posix.basename(resource.getRealResourcePath()), moduleContent);
}

return {
moduleSourceMap,
moduleContent: newModuleContent
};
}

createTransitiveSourceMap(moduleName, moduleContent, includeContent) {
const sourceMap = {
version: 3,
sources: [moduleName],
// TODO: check whether moduleContent.match() with \n is better w.r.t performance/memory usage
mappings: encodeMappings(moduleContent.split("\n").map((line, i) => {
return [[0, 0, i, 0]];
}))
};
if (includeContent) {
sourceMap.sourcesContent = [moduleContent];

}
return sourceMap;
}
}

const CALL_SAP_UI_DEFINE = ["sap", "ui", "define"];
Expand Down
8 changes: 4 additions & 4 deletions lib/lbt/resources/LocatorResource.js
Original file line number Diff line number Diff line change
Expand Up @@ -5,10 +5,10 @@ function extractName(path) {
}

class LocatorResource extends Resource {
constructor(pool, resource, sourceMappingUrl) {
constructor(pool, resource, realResourcePath) {
super(pool, extractName(resource.getPath()), null, resource.getStatInfo());
this.resource = resource;
this.sourceMappingUrl = sourceMappingUrl;
this._realResourcePath = extractName(realResourcePath || resource.getPath());
}

buffer() {
Expand All @@ -19,8 +19,8 @@ class LocatorResource extends Resource {
return this.resource._project;
}

getSourceMappingUrl() {
return this.sourceMappingUrl;
getRealResourcePath() {
return this._realResourcePath;
}
}

Expand Down
4 changes: 2 additions & 2 deletions lib/lbt/resources/LocatorResourcePool.js
Original file line number Diff line number Diff line change
Expand Up @@ -2,12 +2,12 @@ const ResourcePool = require("./ResourcePool");
const LocatorResource = require("./LocatorResource");

class LocatorResourcePool extends ResourcePool {
prepare(resources, sourceMapping) {
prepare(resources, realResourcePaths) {
resources = resources.filter( (res) => !res.getStatInfo().isDirectory() );
return Promise.all(
resources.map(
(resource) => this.addResource(
new LocatorResource(this, resource, sourceMapping && sourceMapping[resource.getPath()])
new LocatorResource(this, resource, realResourcePaths && realResourcePaths[resource.getPath()])
)
).filter(Boolean)
);
Expand Down
6 changes: 3 additions & 3 deletions lib/processors/bundlers/moduleBundler.js
Original file line number Diff line number Diff line change
Expand Up @@ -120,12 +120,12 @@ const log = require("@ui5/logger").getLogger("builder:processors:bundlers:module
* @param {object} parameters Parameters
* @param {module:@ui5/fs.Resource[]} parameters.resources Resources
* @param {object} parameters.options Options
* @param {object} parameters.options.sourceMapping TBD
* @param {object} parameters.options.realResourcePaths TBD
* @param {ModuleBundleDefinition} parameters.options.bundleDefinition Module bundle definition
* @param {ModuleBundleOptions} [parameters.options.bundleOptions] Module bundle options
* @returns {Promise<module:@ui5/builder.processors.MinifierResult[]>} Promise resolving with module bundle resources
*/
module.exports = function({resources, options: {bundleDefinition, bundleOptions, sourceMapping}}) {
module.exports = function({resources, options: {bundleDefinition, bundleOptions, realResourcePaths}}) {
// Apply defaults without modifying the passed object
bundleOptions = Object.assign({}, {
optimize: true,
Expand All @@ -147,7 +147,7 @@ module.exports = function({resources, options: {bundleDefinition, bundleOptions,
log.verbose(`bundleOptions: ${JSON.stringify(bundleOptions, null, 2)}`);
}

return pool.prepare( resources, sourceMapping ).
return pool.prepare( resources, realResourcePaths ).
then( () => builder.createBundle(bundleDefinition, bundleOptions) ).
then( (results) => {
let bundles;
Expand Down
16 changes: 4 additions & 12 deletions lib/tasks/bundlers/generateBundle.js
Original file line number Diff line number Diff line change
Expand Up @@ -25,7 +25,7 @@ module.exports = function({
readers: [workspace, dependencies]
});

const sourceMapping = {};
const realResourcePaths = {};

if (taskUtil) {
const optimize = !bundleOptions || bundleOptions.optimize !== false;
Expand All @@ -34,12 +34,6 @@ module.exports = function({
const filterTag = optimize ?
taskUtil.STANDARD_TAGS.IsDebugVariant : taskUtil.STANDARD_TAGS.HasDebugVariant;
combo = combo.filter(function(resource) {
if (optimize) {
const sourceMappingUrl = taskUtil.getTag(resource, taskUtil.STANDARD_TAGS.SourceMappingUrl);
if (sourceMappingUrl) {
sourceMapping[resource.getPath()] = sourceMappingUrl;
}
}
return !taskUtil.getTag(resource, filterTag);
});

Expand All @@ -54,10 +48,8 @@ module.exports = function({
if (!nonDbgPath) {
throw new Error(`Failed to resolve non-debug name for ${resource.getPath()}`);
}
const sourceMappingUrl = taskUtil.getTag(resource, taskUtil.STANDARD_TAGS.SourceMappingUrl);
if (sourceMappingUrl) {
sourceMapping[nonDbgPath] = sourceMappingUrl;
}
realResourcePaths[nonDbgPath] = resource.getPath();

resource.setPath(nonDbgPath);
}
});
Expand All @@ -69,7 +61,7 @@ module.exports = function({
options: {
bundleDefinition,
bundleOptions,
sourceMapping
realResourcePaths
},
resources
}).then((bundles) => {
Expand Down
12 changes: 7 additions & 5 deletions lib/tasks/bundlers/generateLibraryPreload.js
Original file line number Diff line number Diff line change
Expand Up @@ -211,6 +211,7 @@ function getModuleBundlerOptions(config) {
if (config.provided) {
moduleBundlerOptions.bundleDefinition.sections.unshift(providedSection);
}
moduleBundlerOptions.realResourcePaths = config.realResourcePaths;

return moduleBundlerOptions;
}
Expand Down Expand Up @@ -306,6 +307,7 @@ module.exports = function({workspace, dependencies, taskUtil, options: {projectN
});

let unoptimizedResources = resources;
const realResourcePaths = {};
if (taskUtil) {
unoptimizedResources = await new ReaderCollectionPrioritized({
name: `libraryBundler - prioritize workspace over dependencies: ${projectName}`,
Expand All @@ -320,6 +322,7 @@ module.exports = function({workspace, dependencies, taskUtil, options: {projectN
if (!nonDbgPath) {
throw new Error(`Failed to resolve non-debug name for ${resource.getPath()}`);
}
realResourcePaths[nonDbgPath] = resource.getPath();
resource.setPath(nonDbgPath);
}
}).byGlob("/**/*.{js,json,xml,html,properties,library,js.map}");
Expand All @@ -333,22 +336,21 @@ module.exports = function({workspace, dependencies, taskUtil, options: {projectN
}
p = Promise.all([
moduleBundler({
options: getModuleBundlerOptions({name: "sap-ui-core.js", filters, preload: true}),
resources
options: getModuleBundlerOptions({name: "sap-ui-core.js", filters, preload: true, realResourcePaths})
}),
moduleBundler({
options: getModuleBundlerOptions({name: "sap-ui-core-dbg.js", filters, preload: false}),
options: getModuleBundlerOptions({name: "sap-ui-core-dbg.js", filters, preload: false, realResourcePaths}),
resources: unoptimizedResources
}),
moduleBundler({
options: getModuleBundlerOptions({
name: "sap-ui-core-nojQuery.js", filters, preload: true, provided: true
name: "sap-ui-core-nojQuery.js", filters, preload: true, provided: true, realResourcePaths
}),
resources
}),
moduleBundler({
options: getModuleBundlerOptions({
name: "sap-ui-core-nojQuery-dbg.js", filters, preload: false, provided: true
name: "sap-ui-core-nojQuery-dbg.js", filters, preload: false, provided: true, realResourcePaths
}),
resources: unoptimizedResources
}),
Expand Down
1 change: 0 additions & 1 deletion lib/tasks/minify.js
Original file line number Diff line number Diff line change
Expand Up @@ -19,7 +19,6 @@ module.exports = async function({workspace, taskUtil, options: {pattern}}) {
return Promise.all(processedResources.map(async ({resource, dbgResource, sourceMapResource}) => {
if (taskUtil) {
taskUtil.setTag(resource, taskUtil.STANDARD_TAGS.HasDebugVariant);
taskUtil.setTag(resource, taskUtil.STANDARD_TAGS.SourceMappingUrl, sourceMapResource.getPath());
taskUtil.setTag(dbgResource, taskUtil.STANDARD_TAGS.IsDebugVariant);
taskUtil.setTag(sourceMapResource, taskUtil.STANDARD_TAGS.OmitFromBuildResult);
}
Expand Down

0 comments on commit 7b51d11

Please sign in to comment.