Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

[FEATURE] Add minify task and processor #666

Merged
merged 25 commits into from
Jan 17, 2022
Merged
Show file tree
Hide file tree
Changes from 24 commits
Commits
Show all changes
25 commits
Select commit Hold shift + click to select a range
1ea1bb7
[FEATURE] BuildContext: Introduce global tags 'IsDebugVariant', 'HasD…
RandomByte Nov 23, 2021
30c87d8
[FEATURE] Add 'minify' task and processor
RandomByte Nov 23, 2021
90d95bc
[INTERNAL] Bundle generation: Filter (non-)debug resources
RandomByte Nov 23, 2021
a4d31f9
[INTERNAL] lbt/bundle/Builder: Remove compression
RandomByte Nov 24, 2021
c0d4c30
[INTERNAL] minifier: Preserve 'sap' variables during mangling
RandomByte Nov 25, 2021
705c54c
[INTERNAL] minifier: Skip debug-variant check, rename return value, f…
RandomByte Dec 2, 2021
e14933b
[INTERNAL] minifier: Merge createDebugFiles and uglify tests into min…
RandomByte Dec 2, 2021
d780860
[INTERNAL] Update tests
RandomByte Dec 2, 2021
36b6e98
[INTERNAL] Update way too many expected files
RandomByte Dec 2, 2021
7885d19
[INTERNAL] BuildContext: Update tests
RandomByte Dec 2, 2021
dcc6047
[INTERNAL] Bundle generators: Adapt to latest ReaderFilter changes
RandomByte Dec 2, 2021
801b508
[INTERNAL] builder integration tests: Add tests for optimize: false w…
RandomByte Dec 4, 2021
4003b79
[INTERNAL] generateStandaloneAppBundle: Add filtering of -dbg variants
RandomByte Dec 7, 2021
f91f11d
[INTERNAL] LocatorResourcePool: Add option to remove -dbg from resour…
RandomByte Dec 7, 2021
6c432d6
[INTERNAL] Use ReaderTransformer to remove -dbg from resource names
RandomByte Dec 17, 2021
ff1b7e6
[INTERNAL] minifier: Do not minify .support.js resources
RandomByte Dec 17, 2021
9562ef9
[INTERNAL] generateBundle: Make transformer callback sync
RandomByte Dec 21, 2021
a6e7b64
[INTERNAL] TaskUtil: Allow resource path instead of instance
RandomByte Dec 22, 2021
59dc7bd
[INTERNAL] generateLibraryPreload: Apply resource transformation for …
RandomByte Dec 22, 2021
9ea9288
[INTERNAL] generateLibraryPreload: Update sap.ui.core integration test
RandomByte Dec 23, 2021
ca7423f
[INTERNAL] generateStandaloneAppBundle: Update integration test
RandomByte Dec 23, 2021
cc3553e
[INTERNAL] taskRepository: Helpful error message when retrieving remo…
RandomByte Dec 23, 2021
c32c5a8
[INTERNAL] Cleanup based on code review
RandomByte Dec 23, 2021
c6c1e84
[INTERNAL] Minifer: Exclude .support.js files using glob pattern in b…
RandomByte Dec 23, 2021
c0676d6
[INTERNAL] TaskUtil: Remove unused function getResourceTagCollection
RandomByte Jan 14, 2022
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
The table of contents is too big for display.
Diff view
Diff view
  •  
  •  
  •  
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.

Loading