Skip to content

Commit

Permalink
[FEATURE] Add minify task and processor (#666)
Browse files Browse the repository at this point in the history
Combines debug-file creation, source-map generation and minification.
Replaces existing tasks/processors 'uglify' and 'createDebugFiles'.

Also introduce new global tags `IsDebugVariant` and `HasDebugVariant`.

BREAKING CHANGE:
The following tasks have been removed:
- createDebugFiles
- uglify

The following processors have been removed:
- debugFileCreator
- resourceCopier
- uglifier

As a replacement, the new 'minify' task and 'minifier' processor can be
used.

Note: The minify task is executed earlier, before the bundling
process takes place. Existing 'beforeTask' and 'afterTask' configuration of
custom tasks might need to be adapted to cater for this change.
  • Loading branch information
RandomByte committed Jan 17, 2022
1 parent c110dbc commit a3af604
Show file tree
Hide file tree
Showing 366 changed files with 2,730 additions and 1,219 deletions.
20 changes: 4 additions & 16 deletions index.js
Original file line number Diff line number Diff line change
Expand Up @@ -42,9 +42,9 @@ module.exports = {
*/
bootstrapHtmlTransformer: "./lib/processors/bootstrapHtmlTransformer",
/**
* @type {import('./lib/processors/debugFileCreator')}
* @type {import('./lib/processors/minifier')}
*/
debugFileCreator: "./lib/processors/debugFileCreator",
minifier: "./lib/processors/minifier",
/**
* @type {import('./lib/processors/libraryLessGenerator')}
*/
Expand All @@ -53,10 +53,6 @@ module.exports = {
* @type {import('./lib/processors/manifestCreator')}
*/
manifestCreator: "./lib/processors/manifestCreator",
/**
* @type {import('./lib/processors/resourceCopier')}
*/
resourceCopier: "./lib/processors/resourceCopier",
/**
* @type {import('./lib/processors/nonAsciiEscaper')}
*/
Expand All @@ -69,10 +65,6 @@ module.exports = {
* @type {import('./lib/processors/themeBuilder')}
*/
themeBuilder: "./lib/processors/themeBuilder",
/**
* @type {import('./lib/processors/uglifier')}
*/
uglifier: "./lib/processors/uglifier",
/**
* @type {import('./lib/processors/versionInfoGenerator')}
*/
Expand Down Expand Up @@ -121,9 +113,9 @@ module.exports = {
*/
buildThemes: "./lib/tasks/buildThemes",
/**
* @type {import('./lib/tasks/createDebugFiles')}
* @type {import('./lib/tasks/minify')}
*/
createDebugFiles: "./lib/tasks/createDebugFiles",
minify: "./lib/tasks/minify",
/**
* @type {import('./lib/tasks/jsdoc/executeJsdocSdkTransformation')}
*/
Expand Down Expand Up @@ -160,10 +152,6 @@ module.exports = {
* @type {import('./lib/tasks/transformBootstrapHtml')}
*/
transformBootstrapHtml: "./lib/tasks/transformBootstrapHtml",
/**
* @type {import('./lib/tasks/uglify')}
*/
uglify: "./lib/tasks/uglify",
/**
* @type {import('./lib/tasks/taskRepository')}
*/
Expand Down
17 changes: 17 additions & 0 deletions lib/builder/BuildContext.js
Original file line number Diff line number Diff line change
@@ -1,5 +1,13 @@
const ResourceTagCollection = require("@ui5/fs").ResourceTagCollection;
const ProjectBuildContext = require("./ProjectBuildContext");

// Note: When adding standard tags, always update the public documentation in TaskUtil
// (Type "module:@ui5/builder.tasks.TaskUtil~StandardBuildTags")
const GLOBAL_TAGS = Object.freeze({
IsDebugVariant: "ui5:IsDebugVariant",
HasDebugVariant: "ui5:HasDebugVariant",
});

/**
* Context of a build process
*
Expand All @@ -13,6 +21,10 @@ class BuildContext {
}
this.rootProject = rootProject;
this.projectBuildContexts = [];

this._resourceTagCollection = new ResourceTagCollection({
allowedTags: Object.values(GLOBAL_TAGS)
});
}

getRootProject() {
Expand All @@ -22,6 +34,7 @@ class BuildContext {
createProjectContext({project, resources}) {
const projectBuildContext = new ProjectBuildContext({
buildContext: this,
globalTags: GLOBAL_TAGS,
project,
resources
});
Expand All @@ -34,6 +47,10 @@ class BuildContext {
return ctx.executeCleanupTasks();
}));
}

getResourceTagCollection() {
return this._resourceTagCollection;
}
}

module.exports = BuildContext;
16 changes: 9 additions & 7 deletions lib/builder/ProjectBuildContext.js
Original file line number Diff line number Diff line change
Expand Up @@ -2,10 +2,10 @@ const ResourceTagCollection = require("@ui5/fs").ResourceTagCollection;

// Note: When adding standard tags, always update the public documentation in TaskUtil
// (Type "module:@ui5/builder.tasks.TaskUtil~StandardBuildTags")
const STANDARD_TAGS = Object.freeze({
const STANDARD_TAGS = {
OmitFromBuildResult: "ui5:OmitFromBuildResult",
IsBundle: "ui5:IsBundle"
});
IsBundle: "ui5:IsBundle",
};

/**
* Build context of a single project. Always part of an overall
Expand All @@ -15,8 +15,8 @@ const STANDARD_TAGS = Object.freeze({
* @memberof module:@ui5/builder.builder
*/
class ProjectBuildContext {
constructor({buildContext, project, resources}) {
if (!buildContext || !project || !resources) {
constructor({buildContext, globalTags, project, resources}) {
if (!buildContext || !globalTags || !project || !resources) {
throw new Error(`One or more mandatory parameters are missing`);
}
this._buildContext = buildContext;
Expand All @@ -26,10 +26,12 @@ class ProjectBuildContext {
cleanup: []
};

this.STANDARD_TAGS = STANDARD_TAGS;
this.STANDARD_TAGS = Object.assign({}, STANDARD_TAGS, globalTags);
Object.freeze(this.STANDARD_TAGS);

this._resourceTagCollection = new ResourceTagCollection({
allowedTags: Object.values(this.STANDARD_TAGS)
allowedTags: Object.values(this.STANDARD_TAGS),
superCollection: this._buildContext.getResourceTagCollection()
});
}

Expand Down
3 changes: 1 addition & 2 deletions lib/builder/builder.js
Original file line number Diff line number Diff line change
Expand Up @@ -94,8 +94,7 @@ function composeTaskList({dev, selfContained, jsdoc, includedTasks, excludedTask
selectedTasks.generateComponentPreload = false;
selectedTasks.generateLibraryPreload = false;
selectedTasks.generateLibraryManifest = false;
selectedTasks.createDebugFiles = false;
selectedTasks.uglify = false;
selectedTasks.minify = false;
selectedTasks.generateFlexChangesBundle = false;
selectedTasks.generateManifestBundle = false;
}
Expand Down
54 changes: 13 additions & 41 deletions lib/lbt/bundle/Builder.js
Original file line number Diff line number Diff line change
Expand Up @@ -3,7 +3,6 @@
"use strict";

const path = require("path");
const terser = require("terser");
const {pd} = require("pretty-data");
const {parseJS, Syntax} = require("../utils/parseUtils");
// const MOZ_SourceMap = require("source-map");
Expand All @@ -19,7 +18,6 @@ const {SectionType} = require("./BundleDefinition");
const BundleWriter = require("./BundleWriter");
const log = require("@ui5/logger").getLogger("lbt:bundle:Builder");

const copyrightCommentsPattern = /copyright|\(c\)(?:[0-9]+|\s+[0-9A-za-z])|released under|license|\u00a9|^@ui5-bundle-raw-include |^@ui5-bundle /i;
const xmlHtmlPrePattern = /<(?:\w+:)?pre\b/;

const strReplacements = {
Expand Down Expand Up @@ -282,12 +280,9 @@ class BundleBuilder {
}

async writeRawModule(module, resource) {
let fileContent = await resource.buffer();
if ( /\.js$/.test(module) ) {
fileContent = await this.compressJS( fileContent, resource );
}
const fileContent = await resource.string();
this.outW.ensureNewLine();
this.outW.write( fileContent );
this.outW.write(fileContent);
}

async writePreloadFunction(section) {
Expand Down Expand Up @@ -331,28 +326,6 @@ class BundleBuilder {
// this.afterWriteFunctionPreloadSection();
}

async compressJS(fileContent, resource) {
if ( this.optimize ) {
const result = await terser.minify({
[resource.name]: String(fileContent)
}, {
compress: false, // TODO configure?
output: {
comments: copyrightCommentsPattern,
wrap_func_args: false
}
// , outFileName: resource.name
// , outSourceMap: true
});
// console.log(result.map);
// const map = new MOZ_SourceMap.SourceMapConsumer(result.map);
// map.eachMapping(function (m) { console.log(m); }); // console.log(map);
fileContent = result.code;
// throw new Error();
}
return fileContent;
}

beforeWriteFunctionPreloadSection(sequence) {
// simple version: just sort alphabetically
sequence.sort();
Expand All @@ -367,13 +340,12 @@ class BundleBuilder {
if ( /\.js$/.test(module) ) {
// console.log("Processing " + module);
const resource = await this.pool.findResourceWithInfo(module);
let code = await resource.buffer();
code = rewriteDefine(this.targetBundleFormat, code, module);
if ( code ) {
let moduleContent = await resource.string();
moduleContent = rewriteDefine(this.targetBundleFormat, moduleContent, module);
if ( moduleContent ) {
outW.startSegment(module);
outW.ensureNewLine();
const fileContent = await this.compressJS(code, resource);
outW.write( fileContent );
outW.write(moduleContent);
outW.ensureNewLine();
const compressedSize = outW.endSegment();
log.verbose(" %s (%d,%d)", module,
Expand Down Expand Up @@ -409,17 +381,17 @@ class BundleBuilder {
const outW = this.outW;

if ( /\.js$/.test(module) && (info == null || !info.requiresTopLevelScope) ) {
const compressedContent = await this.compressJS( await resource.buffer(), resource );
const moduleContent = await resource.string();
outW.write(`function(){`);
outW.write( compressedContent );
outW.write(moduleContent);
this.exportGlobalNames(info);
outW.ensureNewLine();
outW.write(`}`);
} else if ( /\.js$/.test(module) /* implicitly: && info != null && info.requiresTopLevelScope */ ) {
log.warn("**** warning: module %s requires top level scope" +
" and can only be embedded as a string (requires 'eval')", module);
const compressedContent = await this.compressJS( await resource.buffer(), resource );
outW.write( makeStringLiteral( compressedContent ) );
const moduleContent = await resource.buffer();
outW.write(makeStringLiteral(moduleContent));
} else if ( /\.html$/.test(module) ) {
const fileContent = await resource.buffer();
outW.write( makeStringLiteral( fileContent ) );
Expand All @@ -435,13 +407,13 @@ class BundleBuilder {
}
outW.write(makeStringLiteral(fileContent));
} else if ( /\.xml$/.test(module) ) {
let fileContent = await resource.buffer();
let fileContent = await resource.string();
if ( this.optimize ) {
// For XML we use the pretty data
// Do not minify if XML(View) contains an <*:pre> tag,
// because whitespace of HTML <pre> should be preserved (should only happen rarely)
if (!xmlHtmlPrePattern.test(fileContent.toString())) {
fileContent = pd.xmlmin(fileContent.toString(), false);
if (!xmlHtmlPrePattern.test(fileContent)) {
fileContent = pd.xmlmin(fileContent, false);
}
}
outW.write( makeStringLiteral( fileContent ) );
Expand Down
2 changes: 0 additions & 2 deletions lib/lbt/resources/LocatorResource.js
Original file line number Diff line number Diff line change
@@ -1,11 +1,9 @@
const Resource = require("./Resource");


function extractName(path) {
return path.slice( "/resources/".length);
}


class LocatorResource extends Resource {
constructor(pool, resource) {
super(pool, extractName(resource.getPath()), null, resource.getStatInfo());
Expand Down
7 changes: 7 additions & 0 deletions lib/lbt/resources/Resource.js
Original file line number Diff line number Diff line change
Expand Up @@ -18,6 +18,13 @@ class Resource {
async buffer() {
return readFile(this.file);
}

/**
* @returns {Promise<string>} String of the file content
*/
async string() {
return (await this.buffer()).toString();
}
}

module.exports = Resource;
52 changes: 0 additions & 52 deletions lib/processors/debugFileCreator.js

This file was deleted.

0 comments on commit a3af604

Please sign in to comment.