Skip to content

Commit

Permalink
[PoC] ResourcePool: Add option to prefer analyzing a resource's sourc…
Browse files Browse the repository at this point in the history
…e content

Possible follow up of #551 to
improve dependency analysis.

JSModuleAnalyzer has trouble detecting some dependencies in minified
code if they have been "mangled". E.g. in case jQuery is not named
jQuery anymore.

This change solves that by trying to retrieve the debug ("source")
content of a resource to analyze that instead of the minified version.
However, integrating this on the ResourcePool level is not ideal and a
more general solution to this problem should be preferred.

Therefore this PR should only act as an illustration of the discussions
and thoughts. Currently it should not be merged.
  • Loading branch information
RandomByte committed Nov 26, 2020
1 parent 40d2994 commit 136c879
Show file tree
Hide file tree
Showing 2 changed files with 37 additions and 8 deletions.
15 changes: 12 additions & 3 deletions lib/lbt/resources/ResourceCollector.js
Original file line number Diff line number Diff line change
Expand Up @@ -108,8 +108,14 @@ class ResourceCollector {
}
}

async enrichWithDependencyInfo(resourceInfo) {
return this._pool.getModuleInfo(resourceInfo.name).then((moduleInfo) => {
async enrichWithDependencyInfo({resourceInfo, debugBundleFilter}) {
return this._pool.getModuleInfo(resourceInfo.name, {
// While analyzing non-debug resources, try to analyze the content of the corresponding
// debug resource instead
preferDebugResources: true,
// Provide the debugBundleFilter to prevent that debug bundles are "preferred"
debugBundleFilter
}).then((moduleInfo) => {
if ( moduleInfo.name ) {
resourceInfo.module = moduleInfo.name;
}
Expand Down Expand Up @@ -192,7 +198,10 @@ class ResourceCollector {
if ( (!info.isDebug || debugBundleFilter.matches(name)) ) {
// Only analyze non-debug files which are not special debug bundles (like sap-ui-core-dbg.js)
promises.push(
this.enrichWithDependencyInfo(info)
this.enrichWithDependencyInfo({
resourceInfo: info,
debugBundleFilter
})
);
} else {
nonBundledDebugResources.push(info);
Expand Down
30 changes: 25 additions & 5 deletions lib/lbt/resources/ResourcePool.js
Original file line number Diff line number Diff line change
Expand Up @@ -15,6 +15,7 @@ const XMLTemplateAnalyzer = require("../analyzer/XMLTemplateAnalyzer");
const LibraryFileAnalyzer = require("./LibraryFileAnalyzer");
const ModuleInfo = require("./ModuleInfo");
const ResourceFilterList = require("./ResourceFilterList");
const ResourceInfoList = require("./ResourceInfoList");
/*
const Resource = require("./Resource");
*/
Expand Down Expand Up @@ -57,12 +58,15 @@ function scanFileOrDir(fileOrDir, name, pool) {
}
*/

async function determineDependencyInfo(resource, rawInfo, pool) {
async function determineDependencyInfo(resource, dbgResource, rawInfo, pool) {
const info = new ModuleInfo(resource.name);
info.size = resource.fileSize;
if ( /\.js$/.test(resource.name) ) {
// console.log("analyzing %s", resource.file);
const code = await resource.buffer();
// console.log("analyzing %s", resource.name);

// Retrieve the content from the "debug resource".
// Note that in many cases "resource" and "dbgResource" are the same object
const code = await dbgResource.buffer();
info.size = code.length;
const promises = [];
let ast;
Expand Down Expand Up @@ -177,14 +181,30 @@ class ResourcePool {
* Retrieves the module info
*
* @param {string} name module name
* @param {object} options
* @param {boolean} options.preferDebugResources
* @param {ResourceFilterList} options.debugBundleFilter
* @returns {Promise<ModuleInfo>}
*/
async getModuleInfo(name) {
async getModuleInfo(name, options) {
let info = this._dependencyInfos.get(name);
if ( info == null ) {
// console.log("analyzing ", name);
let dbgResource;
if (options && options.preferDebugResources) {
// If requested, try to retrieve the corresponding debug-resource (xyz-dbg.js) and pass it to
// determineDependencyInfo as well. Its dependency analysis will perform better with the
// not-minified content of a resource.
const dbgName = ResourceInfoList.getDebugName(name);
if (dbgName && (!options.debugBundleFilter || !options.debugBundleFilter.matches(dbgName))) {
dbgResource = this._resourcesByName.get(dbgName);
}
}
const resource = await this.findResource(name);
info = await determineDependencyInfo( resource, this._rawModuleInfos.get(name), this );
if (!dbgResource) {
dbgResource = resource;
}
info = await determineDependencyInfo(resource, dbgResource, this._rawModuleInfos.get(name), this);
// console.log("finished analyzing ", name);
this._dependencyInfos.set(name, info);
}
Expand Down

0 comments on commit 136c879

Please sign in to comment.