@ui5/builder
Advanced tools
Comparing version 1.5.1 to 1.5.2
@@ -5,4 +5,12 @@ # Changelog | ||
A list of unreleased changes can be found [here](https://github.com/SAP/ui5-builder/compare/v1.5.1...HEAD). | ||
A list of unreleased changes can be found [here](https://github.com/SAP/ui5-builder/compare/v1.5.2...HEAD). | ||
<a name="v1.5.2"></a> | ||
## [v1.5.2] - 2019-10-06 | ||
### Bug Fixes | ||
- Improve recognition of main module in case of bundles ([#341](https://github.com/SAP/ui5-builder/issues/341)) [`7a560b4`](https://github.com/SAP/ui5-builder/commit/7a560b4bbc4c862ebded6f9e9f12c2156b1e33d1) | ||
- Align set of known file types with runtime ([#337](https://github.com/SAP/ui5-builder/issues/337)) [`8b372f1`](https://github.com/SAP/ui5-builder/commit/8b372f1ad65d0edfe5cd440bd9352db7e48ea156) | ||
- **manifestCreator:** Only consider component files called Component.js ([#273](https://github.com/SAP/ui5-builder/issues/273)) [`82fe267`](https://github.com/SAP/ui5-builder/commit/82fe2675114c13603238889e43be498f92d22a51) | ||
<a name="v1.5.1"></a> | ||
@@ -254,2 +262,3 @@ ## [v1.5.1] - 2019-09-04 | ||
[v1.5.2]: https://github.com/SAP/ui5-builder/compare/v1.5.1...v1.5.2 | ||
[v1.5.1]: https://github.com/SAP/ui5-builder/compare/v1.5.0...v1.5.1 | ||
@@ -256,0 +265,0 @@ [v1.5.0]: https://github.com/SAP/ui5-builder/compare/v1.4.2...v1.5.0 |
@@ -208,3 +208,2 @@ "use strict"; | ||
const CALL_REQUIRE_PREDEFINE = ["require", "predefine"]; | ||
const CALL_REQUIRE_PRELOAD = ["require", "preload"]; | ||
const CALL_SAP_UI_DEFINE = ["sap", "ui", "define"]; | ||
@@ -219,3 +218,5 @@ const CALL_SAP_UI_REQUIRE = ["sap", "ui", "require"]; | ||
const CALL_JQUERY_SAP_REGISTER_PRELOADED_MODULES = [["jQuery", "$"], "sap", "registerPreloadedModules"]; | ||
const SPECIAL_AMD_DEPENDENCIES = ["require", "exports", "module"]; | ||
function isCallableExpression(node) { | ||
@@ -225,2 +226,10 @@ return node.type == Syntax.FunctionExpression || node.type == Syntax.ArrowFunctionExpression; | ||
/* | ||
* Dummy implementation. | ||
* Sole purpose is to easier align with the old (Java) implementation of the bundle tooling. | ||
*/ | ||
function getDocumentation(node) { | ||
return undefined; | ||
} | ||
/** | ||
@@ -237,17 +246,71 @@ * Analyzes an already parsed JSDocument to collect information about the contained module(s). | ||
analyze(ast, defaultName, info) { | ||
let mainModuleFound = false; | ||
/** | ||
* Number of (sap.ui.)define calls without a module ID. | ||
* Only tracked to be able to complain about multiple module definitions without ID. | ||
*/ | ||
let nUnnamedDefines = 0; | ||
/** | ||
* ID of the first named (sap.ui.)define call. | ||
* Remembered together with the corresponding description in case no other main module | ||
* can be found (no unnamed module, no module with the ID that matches the filename). | ||
* Will be used as main module ID if only one module definition exists in the file. | ||
*/ | ||
let candidateName = null; | ||
let candidateDescription = null; | ||
/** | ||
* Total number of module declarations (declare or define). | ||
*/ | ||
let nModuleDeclarations = 0; | ||
// console.log(JSON.stringify(ast, null, " ")); | ||
// first analyze the whole AST... | ||
visit(ast, false); | ||
// ...then all the comments | ||
if ( Array.isArray(ast.comments) ) { | ||
ast.comments.forEach((comment) => { | ||
if ( comment.type === "Line" && comment.value.startsWith("@ui5-bundle") ) { | ||
if ( comment.value.startsWith("@ui5-bundle-raw-include ") ) { | ||
const subModule = comment.value.slice("@ui5-bundle-raw-include ".length); | ||
info.addSubModule(subModule); | ||
log.debug(`bundle include directive ${subModule}`); | ||
} else if ( comment.value.startsWith("@ui5-bundle ") ) { | ||
const bundleName = comment.value.slice("@ui5-bundle ".length); | ||
setMainModuleInfo(bundleName, null); | ||
log.debug(`bundle name directive ${bundleName}`); | ||
} else { | ||
log.warn(`unrecognized bundle directive ${comment.value}`); | ||
} | ||
} | ||
}); | ||
} | ||
// ...and finally take conclusions about the file's content | ||
if ( !mainModuleFound ) { | ||
// if there's exactly one module definition in this file but it didn't | ||
// immediately qualify as main module, make it now the main module | ||
if ( candidateName != null && nModuleDeclarations == 1 ) { | ||
info.name = candidateName; | ||
info.description = candidateDescription; | ||
mainModuleFound = true; | ||
} else { | ||
// no main module found, use the default name | ||
info.name = defaultName; | ||
} | ||
} | ||
// depending on the used module APIs, add an implicit dependency to the loader entry module | ||
if ( info.format === ModuleFormat.UI5_LEGACY ) { | ||
info.addImplicitDependency(UI5ClientConstants.MODULE__JQUERY_SAP_GLOBAL); | ||
} else if ( info.format === ModuleFormat.UI5_DEFINE ) { | ||
// Note: the implicit dependency for sap.ui.define modules points to the standard UI5 | ||
// loader config module. A more general approach would be to add a dependency to the loader | ||
// only, but then standard configuration would be missed by dependency resolution | ||
// (to be clarified) | ||
info.addImplicitDependency(UI5ClientConstants.MODULE__UI5LOADER_AUTOCONFIG); | ||
} | ||
if ( nModuleDeclarations === 0 && info.name == null ) { | ||
info.name = defaultName; | ||
} | ||
if ( info.dependencies.length === 0 && info.subModules.length === 0 ) { | ||
if ( nModuleDeclarations === 0 && info.dependencies.length === 0 && info.subModules.length === 0 ) { | ||
// when there are no indicators for module APIs, mark the module as 'raw' module | ||
info.rawModule = true; | ||
@@ -267,2 +330,12 @@ } | ||
// hoisted functions | ||
function setMainModuleInfo(name, description) { | ||
if ( mainModuleFound ) { | ||
throw new Error("conflicting main modules found (unnamed + named)"); | ||
} | ||
mainModuleFound = true; | ||
info.name = name; | ||
if ( description != null ) { | ||
info.description = description; | ||
} | ||
} | ||
@@ -344,9 +417,10 @@ function visit(node, conditional) { | ||
onJQuerySapRequire(node, conditional); | ||
} else if ( isMethodCall(node, CALL_JQUERY_SAP_REGISTER_PRELOADED_MODULES) | ||
|| isMethodCall(node, CALL_REQUIRE_PRELOAD) | ||
|| isMethodCall(node, CALL_SAP_UI_REQUIRE_PRELOAD) ) { | ||
} else if ( isMethodCall(node, CALL_JQUERY_SAP_REGISTER_PRELOADED_MODULES) ) { | ||
// recognizes a call to jQuery.sap.registerPreloadedModules | ||
const legacyCall = isMethodCall(node, CALL_JQUERY_SAP_REGISTER_PRELOADED_MODULES); | ||
info.setFormat( legacyCall ? ModuleFormat.UI5_LEGACY : ModuleFormat.UI5_DEFINE); | ||
onRegisterPreloadedModules(node, legacyCall); | ||
info.setFormat(ModuleFormat.UI5_LEGACY); | ||
onRegisterPreloadedModules(node, /* evoSyntax= */ false); | ||
} else if ( isMethodCall(node, CALL_SAP_UI_REQUIRE_PRELOAD) ) { | ||
// recognizes a call to sap.ui.require.preload | ||
info.setFormat(ModuleFormat.UI5_DEFINE); | ||
onRegisterPreloadedModules(node, /* evoSyntax= */ true); | ||
} else if ( isCallableExpression(node.callee) ) { | ||
@@ -402,12 +476,9 @@ // recognizes a scope function declaration + argument | ||
const name = ModuleName.fromUI5LegacyName( args[0].value ); | ||
if ( nModuleDeclarations === 1 ) { | ||
if ( nModuleDeclarations === 1 && !mainModuleFound) { | ||
// if this is the first declaration, then this is the main module declaration | ||
// note that this overrides an already given name | ||
info.name = name; | ||
/* NODE-TODO | ||
info.description = getDocumentation(node); | ||
*/ | ||
setMainModuleInfo(name, getDocumentation(node)); | ||
} else if ( nModuleDeclarations > 1 && name === info.name ) { | ||
// ignore duplicate declarations (e.g. in behavior file of design time controls) | ||
log.warn(`duplicate declaration of module ${getLocation(args)} in ${name}`); | ||
log.warn(`duplicate declaration of module name at ${getLocation(args)} in ${name}`); | ||
} else { | ||
@@ -427,25 +498,31 @@ // otherwise it is just a submodule declaration | ||
// get the documentation from a preceding comment | ||
const desc = getDocumentation(defineCall); | ||
// determine the name of the module | ||
let name = defaultName; | ||
let name = null; | ||
if ( i < nArgs && isString(args[i]) ) { | ||
name = ModuleName.fromRequireJSName( args[i++].value ); | ||
} | ||
if ( name == null ) { | ||
throw new TypeError("define/sap.ui.define: module name could not be determined," + | ||
`neither from environment nor from first argument: ${args[i] && args[i].type}`); | ||
} | ||
if ( nModuleDeclarations === 1 ) { | ||
// if this is the first declaration, then this is the main module declaration | ||
info.name = name; | ||
// get the documentation from a preceding comment | ||
/* NODE-TODO | ||
info.description = getDocumentation(defineNode); | ||
*/ | ||
} else { | ||
if ( name === defaultName ) { | ||
throw new Error("module name could not be determined"); | ||
// hardcoded name equals the file name, so this definition qualifies as main module definition | ||
setMainModuleInfo(name, desc); | ||
} else { | ||
info.addSubModule(name); | ||
if ( candidateName == null ) { | ||
// remember the name and description in case no other module qualifies as main module | ||
candidateName = name; | ||
candidateDescription = desc; | ||
} | ||
} | ||
info.addSubModule(name); | ||
} else { | ||
nUnnamedDefines++; | ||
if ( nUnnamedDefines > 1 ) { | ||
throw new Error("if multiple modules are contained in a file, only one of them may omit the module ID " + name + " " + nUnnamedDefines); | ||
} | ||
if ( defaultName == null ) { | ||
throw new Error("unnamed module found, but no default name given"); | ||
} | ||
name = defaultName; | ||
// the first unnamed module definition qualifies as main module | ||
setMainModuleInfo(name, desc); | ||
} | ||
@@ -513,31 +590,27 @@ | ||
function onRegisterPreloadedModules(node, legacyCall) { | ||
function onRegisterPreloadedModules(node, evoSyntax) { | ||
const args = node.arguments; | ||
// trace.debug("**** registerPreloadedModules detected"); | ||
if ( args.length > 0 && args[0].type == Syntax.ObjectExpression ) { | ||
let modules = args[0]; | ||
let isNewSyntax = true; | ||
let modules = null; | ||
let namesUseLegacyNotation = false; | ||
if ( legacyCall ) { | ||
const obj = args[0]; | ||
isNewSyntax = false; | ||
const version = findOwnProperty(obj, "version"); | ||
if ( version && isString(version) && parseFloat(version.value) >= 2.0 ) { | ||
isNewSyntax = true; | ||
if ( evoSyntax ) { | ||
modules = args[0]; | ||
} else { | ||
const obj = args[0]; | ||
const version = findOwnProperty(obj, "version"); | ||
namesUseLegacyNotation = !(version && isString(version) && parseFloat(version.value) >= 2.0); | ||
modules = findOwnProperty(obj, "modules"); | ||
} | ||
if ( modules && modules.type == Syntax.ObjectExpression ) { | ||
modules.properties.forEach( function(property) { | ||
let moduleName = getPropertyKey(property); | ||
if ( namesUseLegacyNotation ) { | ||
moduleName = ModuleName.fromUI5LegacyName(moduleName); | ||
} | ||
modules = findOwnProperty(obj, "modules"); | ||
} | ||
if ( modules && modules.type == Syntax.ObjectExpression ) { | ||
modules.properties.forEach( function(property) { | ||
let moduleName = getPropertyKey(property); | ||
if ( !isNewSyntax ) { | ||
moduleName = ModuleName.fromUI5LegacyName(moduleName); | ||
} | ||
info.addSubModule(moduleName); | ||
}); | ||
} else { | ||
log.warn("Cannot evaluate registerPreloadedModules: '%s'", modules && modules.type); | ||
} | ||
info.addSubModule(moduleName); | ||
}); | ||
} else { | ||
log.warn("Cannot evaluate registerPreloadedModules: '%s'", modules && modules.type); | ||
} | ||
@@ -550,2 +623,6 @@ } | ||
if ( isString(item) ) { | ||
// ignore special AMD dependencies (require, exports, module) | ||
if ( SPECIAL_AMD_DEPENDENCIES.indexOf(item.value) >= 0 ) { | ||
return; | ||
} | ||
let requiredModule; | ||
@@ -552,0 +629,0 @@ if (name == null) { |
@@ -208,3 +208,4 @@ "use strict"; | ||
output: { | ||
comments: copyrightCommentsPattern | ||
comments: copyrightCommentsPattern, | ||
wrap_func_args: false | ||
} | ||
@@ -211,0 +212,0 @@ // , outFileName: resource.name |
@@ -45,3 +45,3 @@ /* eslint quotes: ["error", "double", { "allowTemplateLiterals": true }] */ | ||
if ( section.name ) { | ||
outW.writeln(`"name":"${section.getSectionName()}",`); | ||
outW.writeln(`"name":"${section.name}",`); | ||
} | ||
@@ -77,3 +77,3 @@ outW.writeln(`"version":"2.0",`); | ||
if ( section.name ) { | ||
outW.write(`,"${section.getSectionName()}"`); | ||
outW.write(`,"${section.name}"`); | ||
} | ||
@@ -149,4 +149,2 @@ outW.writeln(`);`); | ||
this.writeConfiguration(resolvedModule.configuration); // NODE-TODO configuration currently will be undefined | ||
// create all sections in sequence | ||
@@ -175,2 +173,3 @@ for ( const section of resolvedModule.sections ) { | ||
this.outW.writeln("//@ui5-bundle " + module); | ||
if ( this.shouldDecorate ) { | ||
@@ -237,20 +236,2 @@ this.outW.writeln(`window["sap-ui-optimized"] = true;`); | ||
writeConfiguration(config) { | ||
if ( !config ) { | ||
return; | ||
} | ||
const outW = this.outW; | ||
outW.ensureNewLine(); // for clarity and to avoid issues with single line comments | ||
outW.writeln(`(function(window){`); | ||
outW.writeln(`\tvar cfg=window['sap-ui-config']=window['sap-ui-config']||{},`); | ||
outW.writeln(`\t\troots=cfg.resourceRoots=cfg.resourceRoots||{};`); | ||
config.propertyName.forEach( (property) => { | ||
outW.writeln(`\tcfg[${makeStringLiteral(property)}]=${config.getPropertyAsJSLiteral(property)};`); | ||
}); | ||
Object.keys(config.resourceRoots).forEach( (prefix) => { | ||
outW.writeln(`\troots[${makeStringLiteral(prefix)}]=${makeStringLiteral(config.resourceRoots[prefix])};`); | ||
}); | ||
outW.writeln(`}(window));`); | ||
} | ||
// TODO check that there are only JS modules contained | ||
@@ -263,2 +244,4 @@ async writeRaw(section) { | ||
this.outW.startSegment(module); | ||
this.outW.ensureNewLine(); | ||
this.outW.writeln("//@ui5-bundle-raw-include " + module); | ||
await this.writeRawModule(module, resource); | ||
@@ -338,3 +321,4 @@ const compressedSize = this.outW.endSegment(); | ||
output: { | ||
comments: copyrightCommentsPattern | ||
comments: copyrightCommentsPattern, | ||
wrap_func_args: false | ||
} | ||
@@ -341,0 +325,0 @@ // , outFileName: resource.name |
@@ -102,14 +102,11 @@ "use strict"; | ||
/* | ||
public String getSectionName() { | ||
return sectionDefinition.getSectionName(); | ||
get name() { | ||
return this.sectionDefinition.name; | ||
} | ||
public boolean isDeclareRawModules() { | ||
return sectionDefinition.isDeclareRawModules(); | ||
get declareRawModules() { | ||
return this.sectionDefinition.declareRawModules; | ||
} | ||
*/ | ||
} | ||
module.exports = ResolvedBundleDefinition; |
@@ -75,19 +75,2 @@ "use strict"; | ||
function isSapUiDefineCall(node) { | ||
return ( | ||
node | ||
&& node.type === Syntax.CallExpression | ||
&& node.callee.type === Syntax.MemberExpression | ||
&& node.callee.object.type === Syntax.MemberExpression | ||
&& node.callee.object.object.type === Syntax.Identifier | ||
&& node.callee.object.object.name === "sap" | ||
&& node.callee.object.property.type === Syntax.Identifier | ||
&& node.callee.object.property.name === "ui" | ||
&& node.callee.property.type === Syntax.Identifier | ||
&& node.callee.property.name === "define" | ||
); | ||
} | ||
SapUiDefineCall.check = isSapUiDefineCall; | ||
module.exports = SapUiDefineCall; |
@@ -38,3 +38,3 @@ "use strict"; | ||
constructor(name) { | ||
this.name = name; | ||
this._name = name; | ||
this.subModules = []; | ||
@@ -177,2 +177,20 @@ this._dependencies = {}; | ||
get name() { | ||
return this._name; | ||
} | ||
set name(n) { | ||
this._name = n; | ||
if ( n != null ) { | ||
if ( Object.prototype.hasOwnProperty.call(this._dependencies, n) ) { | ||
delete this._dependencies[n]; | ||
} | ||
const idx = this.subModules.indexOf(n); | ||
if ( idx >= 0 ) { | ||
this.subModules.splice(idx, 1); | ||
} | ||
} | ||
} | ||
get dependencies() { | ||
@@ -179,0 +197,0 @@ return Object.keys(this._dependencies); |
@@ -77,3 +77,3 @@ "use strict"; | ||
try { | ||
const ast = esprima.parseScript(code.toString()); | ||
const ast = esprima.parseScript(code.toString(), {comment: true}); | ||
jsAnalyzer.analyze(ast, resource.name, info); | ||
@@ -80,0 +80,0 @@ new XMLCompositeAnalyzer(pool).analyze(ast, resource.name, info); |
@@ -48,3 +48,3 @@ "use strict"; | ||
const KNOWN_TYPES = /\.(properties|css|(?:(?:view\.|fragment\.)?(?:html|json|xml|js))|(?:(?:controller\.)?js))$/; | ||
const KNOWN_TYPES = /\.(properties|css|(?:(?:view\.|fragment\.)?(?:html|json|xml|js))|(?:(?:controller\.|designtime\.|support\.)?js))$/; | ||
@@ -51,0 +51,0 @@ function getDebugName(name) { |
@@ -15,3 +15,3 @@ const copier = require("./resourceCopier"); | ||
const options = { | ||
pattern: /((\.view|\.fragment|\.controller)?\.js)/, | ||
pattern: /((\.view|\.fragment|\.controller|\.designtime|\.support)?\.js)/, | ||
replacement: "-dbg$1" | ||
@@ -18,0 +18,0 @@ }; |
@@ -162,3 +162,3 @@ "use strict"; | ||
const prefix = libraryResource.getPath().slice(0, - ".library".length); | ||
const components = libBundle.getResources(/(?:[^/]+\/)*Component\.js$/); | ||
const components = libBundle.getResources(/^\/(?:[^/]+\/)*Component\.js$/); | ||
components.forEach((comp) => { | ||
@@ -165,0 +165,0 @@ const relativePath = comp.getPath().slice(prefix.length); |
@@ -21,3 +21,4 @@ const terser = require("terser"); | ||
output: { | ||
comments: copyrightCommentsPattern | ||
comments: copyrightCommentsPattern, | ||
wrap_func_args: false | ||
}, | ||
@@ -24,0 +25,0 @@ compress: false |
{ | ||
"name": "@ui5/builder", | ||
"version": "1.5.1", | ||
"version": "1.5.2", | ||
"description": "UI5 Tooling - Builder", | ||
@@ -119,12 +119,12 @@ "author": "SAP SE (https://www.sap.com)", | ||
"slash": "^3.0.0", | ||
"terser": "^4.2.1", | ||
"xml2js": "^0.4.17", | ||
"terser": "^4.3.8", | ||
"xml2js": "^0.4.22", | ||
"yazl": "^2.5.1" | ||
}, | ||
"devDependencies": { | ||
"ava": "^2.3.0", | ||
"ava": "^2.4.0", | ||
"chai": "^4.1.2", | ||
"chai-fs": "^2.0.0", | ||
"coveralls": "^3.0.6", | ||
"cross-env": "^5.2.1", | ||
"cross-env": "^6.0.3", | ||
"docdash": "^1.1.1", | ||
@@ -139,3 +139,3 @@ "eslint": "^5.16.0", | ||
"recursive-readdir": "^2.1.1", | ||
"sinon": "^7.4.1", | ||
"sinon": "^7.5.0", | ||
"tap-nyan": "^1.1.0", | ||
@@ -142,0 +142,0 @@ "tap-xunit": "^2.4.1" |
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
631890
16690
Updatedterser@^4.3.8
Updatedxml2js@^0.4.22