@ui5/builder
Advanced tools
Comparing version 3.1.1 to 3.2.0
@@ -5,6 +5,18 @@ # Changelog | ||
A list of unreleased changes can be found [here](https://github.com/SAP/ui5-builder/compare/v3.1.1...HEAD). | ||
A list of unreleased changes can be found [here](https://github.com/SAP/ui5-builder/compare/v3.2.0...HEAD). | ||
<a name="v3.2.0"></a> | ||
## [v3.2.0] - 2023-12-12 | ||
### Bug Fixes | ||
- Incomplete multi-character sanitization ([#959](https://github.com/SAP/ui5-builder/issues/959)) [`d61f1b7`](https://github.com/SAP/ui5-builder/commit/d61f1b744495f5428db33467218077e7996f1575) | ||
- Add guard against prototype pollution ([#960](https://github.com/SAP/ui5-builder/issues/960)) [`ba230d9`](https://github.com/SAP/ui5-builder/commit/ba230d922cac0acd291dfe18b0ae7a95eae8b190) | ||
- Incomplete string escaping or encoding ([#958](https://github.com/SAP/ui5-builder/issues/958)) [`50bb0d9`](https://github.com/SAP/ui5-builder/commit/50bb0d97e76fb312412cf29fae18b76cc88df6f4) | ||
- **manifestCreator:** set fallbackLocale to empty string if no locale is present ([#962](https://github.com/SAP/ui5-builder/issues/962)) [`26526a0`](https://github.com/SAP/ui5-builder/commit/26526a08ff38ee11ed3bd506f7ef0610f1d1ccb0) | ||
### Features | ||
- depCache bundling mode ([#951](https://github.com/SAP/ui5-builder/issues/951)) [`f2cf564`](https://github.com/SAP/ui5-builder/commit/f2cf564f0f71d635e58a743c7bdef1f427e341b2) | ||
<a name="v3.1.1"></a> | ||
## [v3.1.1] - 2023-11-19 | ||
## [v3.1.1] - 2023-11-20 | ||
### Bug Fixes | ||
@@ -843,2 +855,3 @@ - Handle graceful termination of workerpool for parallel builds ([#953](https://github.com/SAP/ui5-builder/issues/953)) [`f7b9f27`](https://github.com/SAP/ui5-builder/commit/f7b9f27ac5966bd89e52e4c2d5b03482a0f3dbb7) | ||
- Add ability to configure component preloads and custom bundles [`2241e5f`](https://github.com/SAP/ui5-builder/commit/2241e5ff98fd95f1f80cc74959655ae7a9c660e7) | ||
[v3.2.0]: https://github.com/SAP/ui5-builder/compare/v3.1.1...v3.2.0 | ||
[v3.1.1]: https://github.com/SAP/ui5-builder/compare/v3.1.0...v3.1.1 | ||
@@ -845,0 +858,0 @@ [v3.1.0]: https://github.com/SAP/ui5-builder/compare/v3.0.9...v3.1.0 |
@@ -44,2 +44,4 @@ | ||
const moduleSizes = Object.create(null); | ||
const depCacheSizes = []; | ||
let depCacheLoaderSize = 0; | ||
this.optimize = !!options.optimize; | ||
@@ -78,2 +80,23 @@ | ||
break; | ||
case SectionType.DepCache: | ||
depCacheLoaderSize = "sap.ui.loader.config({depCacheUI5:{}});".length; | ||
totalSize += depCacheLoaderSize; | ||
section.modules.forEach( (module) => { | ||
promises.push((async () => { | ||
const resource = await this.pool.findResourceWithInfo(module); | ||
const deps = resource.info.dependencies.filter( | ||
(dep) => | ||
!resource.info.isConditionalDependency(dep) && | ||
!resource.info.isImplicitDependency(dep) | ||
); | ||
if (deps.length > 0) { | ||
const depSize = `"${module}": [${deps.map((dep) => `"${dep}"`).join(",")}],`.length; | ||
totalSize += depSize; | ||
depCacheSizes.push({size: depSize, module}); | ||
} | ||
})()); | ||
}); | ||
break; | ||
default: | ||
@@ -185,2 +208,32 @@ break; | ||
break; | ||
case SectionType.DepCache: | ||
currentSection = { | ||
mode: SectionType.DepCache, | ||
filters: [] | ||
}; | ||
currentModule.sections.push( currentSection ); | ||
totalSize += depCacheLoaderSize; | ||
depCacheSizes.forEach((depCache) => { | ||
if ( part + 1 < numberOfParts && totalSize + depCache.size / 2 > partSize ) { | ||
part++; | ||
// start a new module | ||
totalSize = depCacheLoaderSize; | ||
currentSection = { | ||
mode: SectionType.DepCache, | ||
filters: [] | ||
}; | ||
currentModule = { | ||
name: moduleNameWithPart.replace(/__part__/, part), | ||
sections: [currentSection] | ||
}; | ||
splittedModules.push(currentModule); | ||
} | ||
if (!currentSection.filters.includes(depCache.module)) { | ||
currentSection.filters.push(depCache.module); | ||
totalSize += depCache.size; | ||
} | ||
}); | ||
break; | ||
default: | ||
@@ -187,0 +240,0 @@ break; |
@@ -74,2 +74,10 @@ /* eslint quotes: ["error", "double", { "allowTemplateLiterals": true }] */ | ||
resolvedModule.executes(MODULE__SAP_UI_CORE_CORE); | ||
}, | ||
beforeDepCache(outW) { | ||
outW.writeln(`sap.ui.loader.config({depCacheUI5:{`); | ||
}, | ||
afterDepCache(outW) { | ||
outW.writeln(`}});`); | ||
} | ||
@@ -224,2 +232,4 @@ }; | ||
return this.writeRequires(section); | ||
case SectionType.DepCache: | ||
return this.writeDepCache(section); | ||
default: | ||
@@ -554,2 +564,55 @@ throw new Error("unknown section mode " + section.mode); | ||
// When AutoSplit is enabled for depCache, we need to ensure that modules | ||
// are not duplicated across files. This might happen due to the filters provided. | ||
// So, certain modules that are included in depCache could be dependencies of another | ||
// module in the next file. This will also duplicate its dependency definition if we do not filter. | ||
#depCacheSet = new Set(); | ||
async writeDepCache(section) { | ||
const outW = this.outW; | ||
let hasDepCache = false; | ||
const sequence = section.modules.slice().sort(); | ||
if (sequence.length > 0) { | ||
for (const module of sequence) { | ||
if (this.#depCacheSet.has(module)) { | ||
continue; | ||
} | ||
this.#depCacheSet.add(module); | ||
let resource = null; | ||
try { | ||
resource = await this.pool.findResourceWithInfo(module); | ||
} catch (e) { | ||
log.error(` couldn't find ${module}`); | ||
} | ||
if (resource != null) { | ||
const deps = resource.info.dependencies.filter( | ||
(dep) => | ||
!resource.info.isConditionalDependency(dep) && | ||
!resource.info.isImplicitDependency(dep) | ||
); | ||
if (deps.length > 0) { | ||
if (!hasDepCache) { | ||
hasDepCache = true; | ||
outW.ensureNewLine(); | ||
this.targetBundleFormat.beforeDepCache(outW, section); | ||
} | ||
outW.writeln( | ||
`"${module}": [${deps.map((dep) => `"${dep}"`).join(",")}],` | ||
); | ||
} else { | ||
log.verbose(` skipped ${module}, no dependencies`); | ||
} | ||
} | ||
} | ||
if (hasDepCache) { | ||
this.targetBundleFormat.afterDepCache(outW, section); | ||
} | ||
} | ||
} | ||
async getSourceMapForModule({moduleName, moduleContent, resourcePath}) { | ||
@@ -556,0 +619,0 @@ let moduleSourceMap = null; |
@@ -30,3 +30,10 @@ export const SectionType = { | ||
*/ | ||
Require: "require" | ||
Require: "require", | ||
/** | ||
* Dependency cache information that lists modules and their dependencies | ||
* of all types: JS, declarative views/fragments. | ||
* Only the dependencies of the modules are stored as 'depCache' configuration. | ||
*/ | ||
DepCache: "depCache" | ||
}; |
@@ -67,3 +67,7 @@ | ||
return pool.getModuleInfo(submodule).then( | ||
(subinfo) => bundleInfo.addSubModule(subinfo) | ||
(subinfo) => { | ||
if (!bundleInfo.subModules.includes(subinfo.name)) { | ||
bundleInfo.addSubModule(subinfo); | ||
} | ||
} | ||
); | ||
@@ -70,0 +74,0 @@ }) |
@@ -201,3 +201,3 @@ /** | ||
if ( section.mode == SectionType.Require ) { | ||
if ( [SectionType.Require, SectionType.DepCache].includes(section.mode) ) { | ||
oldSelectedResources = selectedResources; | ||
@@ -258,3 +258,3 @@ oldIgnoredResources = visitedResources; | ||
return Promise.all(promises).then( function() { | ||
if ( section.mode == SectionType.Require ) { | ||
if ( [SectionType.Require, SectionType.DepCache].includes(section.mode) ) { | ||
newKeys = selectedResourcesSequence; | ||
@@ -261,0 +261,0 @@ selectedResources = oldSelectedResources; |
@@ -15,3 +15,3 @@ | ||
} | ||
return type.replace(/[*+?.()|^$]/g, "\\$&"); | ||
return type.replace(/[*+?.()|^$\\]/g, "\\$&"); | ||
}).join("|") + ")"; | ||
@@ -18,0 +18,0 @@ } |
@@ -236,3 +236,7 @@ | ||
// remove all tags | ||
desc = desc.replace(/\s+/g, " ").replace(/<\/?[a-zA-Z][a-zA-Z0-9_$.]*(\s[^>]*)>/g, ""); | ||
let prevDesc; | ||
do { // Safely strip tags (https://codeql.github.com/codeql-query-help/javascript/js-incomplete-multi-character-sanitization/#example) | ||
prevDesc = desc; | ||
desc = desc.replace(/\s+/g, " ").replace(/<\/?[a-zA-Z][a-zA-Z0-9_$.]*(\s[^>]*)>/g, ""); | ||
} while (prevDesc !== desc); | ||
// extract summary (first sentence) | ||
@@ -560,5 +564,7 @@ const m = /^([\w\W]+?[.;!?])[^a-zA-Z0-9_$]/.exec(desc); | ||
supportedLocalesArray.sort(); | ||
return { | ||
bundleUrl: i18n, | ||
supportedLocales: supportedLocalesArray | ||
supportedLocales: supportedLocalesArray, | ||
fallbackLocale: supportedLocalesArray.length === 1 ? supportedLocalesArray[0] : undefined | ||
}; | ||
@@ -565,0 +571,0 @@ } |
{ | ||
"name": "@ui5/builder", | ||
"version": "3.1.1", | ||
"version": "3.2.0", | ||
"description": "UI5 Tooling - Builder", | ||
@@ -50,3 +50,3 @@ "author": { | ||
"version": "git-chglog --sort semver --next-tag v$npm_package_version -o CHANGELOG.md v3.0.0.. && git add CHANGELOG.md", | ||
"postversion": "git push --follow-tags", | ||
"prepublishOnly": "git push --follow-tags", | ||
"release-note": "git-chglog --sort semver -c .chglog/release-config.yml v$npm_package_version", | ||
@@ -135,3 +135,3 @@ "depcheck": "depcheck --ignores @ui5/builder,docdash,@istanbuljs/esm-loader-hook,catharsis --parsers='**/*.js:es6,**/*.cjs:es6'" | ||
"semver": "^7.5.4", | ||
"terser": "^5.24.0", | ||
"terser": "^5.26.0", | ||
"workerpool": "^6.5.1", | ||
@@ -143,3 +143,3 @@ "xml2js": "^0.6.2" | ||
"@jridgewell/trace-mapping": "^0.3.20", | ||
"@ui5/project": "^3.7.3", | ||
"@ui5/project": "^3.8.0", | ||
"ava": "^5.3.1", | ||
@@ -152,3 +152,3 @@ "chai": "^4.3.10", | ||
"docdash": "^2.0.2", | ||
"eslint": "^8.54.0", | ||
"eslint": "^8.55.0", | ||
"eslint-config-google": "^0.14.0", | ||
@@ -155,0 +155,0 @@ "eslint-plugin-ava": "^14.0.0", |
Sorry, the diff of this file is not supported yet
Sorry, the diff of this file is not supported yet
Sorry, the diff of this file is not supported yet
Sorry, the diff of this file is not supported yet
License Policy Violation
LicenseThis package is not allowed per your license policy. Review the package's license to ensure compliance.
Found 1 instance in 1 package
License Policy Violation
LicenseThis package is not allowed per your license policy. Review the package's license to ensure compliance.
Found 1 instance in 1 package
787284
19745
Updatedterser@^5.26.0