From 2ccd4a61f4165176a0af5e5299be8a00ba964cf0 Mon Sep 17 00:00:00 2001 From: Kenn Jacobsen Date: Thu, 18 Feb 2021 08:23:14 +0100 Subject: [PATCH 1/2] Minify client JS as part of the build conditionally (not for dev) and reference only minified JS libraries --- .../Configuration/Models/ContentSettings.cs | 2 +- .../WebAssets/JsInitialize.js | 40 +++--- .../WebAssets/PreviewInitialize.js | 16 +-- src/Umbraco.Web.UI.Client/gulp/config.js | 9 +- .../gulp/tasks/dependencies.js | 18 +-- src/Umbraco.Web.UI.Client/gulp/tasks/js.js | 15 ++ .../gulp/util/processJs.js | 16 +++ src/Umbraco.Web.UI.Client/package-lock.json | 135 ++++++++++++++++++ src/Umbraco.Web.UI.Client/package.json | 1 + .../src/install.loader.js | 20 +-- .../test/config/karma.conf.js | 24 ++-- 11 files changed, 233 insertions(+), 63 deletions(-) diff --git a/src/Umbraco.Core/Configuration/Models/ContentSettings.cs b/src/Umbraco.Core/Configuration/Models/ContentSettings.cs index 01ffffa190..36083feb98 100644 --- a/src/Umbraco.Core/Configuration/Models/ContentSettings.cs +++ b/src/Umbraco.Core/Configuration/Models/ContentSettings.cs @@ -145,7 +145,7 @@ namespace Umbraco.Core.Configuration.Models width:1em; }} - "; + "; /// /// Gets or sets a value for the content notification settings. diff --git a/src/Umbraco.Infrastructure/WebAssets/JsInitialize.js b/src/Umbraco.Infrastructure/WebAssets/JsInitialize.js index d7ede6dfa6..0cfd9384ba 100644 --- a/src/Umbraco.Infrastructure/WebAssets/JsInitialize.js +++ b/src/Umbraco.Infrastructure/WebAssets/JsInitialize.js @@ -1,26 +1,26 @@ -[ +[ 'lib/jquery/jquery.min.js', 'lib/jquery-ui/jquery-ui.min.js', 'lib/jquery-ui-touch-punch/jquery.ui.touch-punch.min.js', - 'lib/angular/angular.js', + 'lib/angular/angular.min.js', 'lib/underscore/underscore-min.js', 'lib/moment/moment.min.js', - 'lib/flatpickr/flatpickr.js', + 'lib/flatpickr/flatpickr.min.js', 'lib/animejs/anime.min.js', - 'lib/angular-route/angular-route.js', - 'lib/angular-cookies/angular-cookies.js', + 'lib/angular-route/angular-route.min.js', + 'lib/angular-cookies/angular-cookies.min.js', 'lib/angular-aria/angular-aria.min.js', - 'lib/angular-touch/angular-touch.js', - 'lib/angular-sanitize/angular-sanitize.js', - 'lib/angular-animate/angular-animate.js', - 'lib/angular-messages/angular-messages.js', + 'lib/angular-touch/angular-touch.min.js', + 'lib/angular-sanitize/angular-sanitize.min.js', + 'lib/angular-animate/angular-animate.min.js', + 'lib/angular-messages/angular-messages.min.js', - 'lib/angular-ui-sortable/sortable.js', + 'lib/angular-ui-sortable/sortable.min.js', 'lib/angular-dynamic-locale/tmhDynamicLocale.min.js', 'lib/ng-file-upload/ng-file-upload.min.js', @@ -35,16 +35,16 @@ 'lib/umbraco/NamespaceManager.js', 'lib/umbraco/LegacySpeechBubble.js', - 'js/utilities.js', + 'js/utilities.min.js', - 'js/app.js', + 'js/app.min.js', - 'js/umbraco.resources.js', - 'js/umbraco.directives.js', - 'js/umbraco.filters.js', - 'js/umbraco.services.js', - 'js/umbraco.interceptors.js', - 'js/umbraco.controllers.js', - 'js/routes.js', - 'js/init.js' + 'js/umbraco.resources.min.js', + 'js/umbraco.directives.min.js', + 'js/umbraco.filters.min.js', + 'js/umbraco.services.min.js', + 'js/umbraco.interceptors.min.js', + 'js/umbraco.controllers.min.js', + 'js/routes.min.js', + 'js/init.min.js' ] diff --git a/src/Umbraco.Infrastructure/WebAssets/PreviewInitialize.js b/src/Umbraco.Infrastructure/WebAssets/PreviewInitialize.js index c19f99c02a..de8cd3669e 100644 --- a/src/Umbraco.Infrastructure/WebAssets/PreviewInitialize.js +++ b/src/Umbraco.Infrastructure/WebAssets/PreviewInitialize.js @@ -1,14 +1,14 @@ -[ +[ 'lib/jquery/jquery.min.js', - 'lib/angular/angular.js', + 'lib/angular/angular.min.js', 'lib/underscore/underscore-min.js', 'lib/umbraco/Extensions.js', - 'js/utilities.js', - 'js/app.js', - 'js/umbraco.resources.js', - 'js/umbraco.services.js', - 'js/umbraco.interceptors.js', + 'js/utilities.min.js', + 'js/app.min.js', + 'js/umbraco.resources.min.js', + 'js/umbraco.services.min.js', + 'js/umbraco.interceptors.min.js', 'ServerVariables', 'lib/signalr/signalr.min.js', - 'js/umbraco.preview.js' + 'js/umbraco.preview.min.js' ] diff --git a/src/Umbraco.Web.UI.Client/gulp/config.js b/src/Umbraco.Web.UI.Client/gulp/config.js index 511b6da945..bd4c406e0f 100755 --- a/src/Umbraco.Web.UI.Client/gulp/config.js +++ b/src/Umbraco.Web.UI.Client/gulp/config.js @@ -4,15 +4,18 @@ module.exports = { compile: { build: { sourcemaps: false, - embedtemplates: true + embedtemplates: true, + minify: true }, dev: { sourcemaps: true, - embedtemplates: true + embedtemplates: true, + minify: false }, test: { sourcemaps: false, - embedtemplates: true + embedtemplates: true, + minify: true } }, sources: { diff --git a/src/Umbraco.Web.UI.Client/gulp/tasks/dependencies.js b/src/Umbraco.Web.UI.Client/gulp/tasks/dependencies.js index e8336b2177..44f16ccefe 100644 --- a/src/Umbraco.Web.UI.Client/gulp/tasks/dependencies.js +++ b/src/Umbraco.Web.UI.Client/gulp/tasks/dependencies.js @@ -46,7 +46,7 @@ function dependencies() { }, { "name": "angular", - "src": ["./node_modules/angular/angular.js"], + "src": ["./node_modules/angular/angular.min.js"], "base": "./node_modules/angular" }, { @@ -57,7 +57,7 @@ function dependencies() { }, { "name": "angular-cookies", - "src": ["./node_modules/angular-cookies/angular-cookies.js"], + "src": ["./node_modules/angular-cookies/angular-cookies.min.js"], "base": "./node_modules/angular-cookies" }, { @@ -70,27 +70,27 @@ function dependencies() { }, { "name": "angular-sanitize", - "src": ["./node_modules/angular-sanitize/angular-sanitize.js"], + "src": ["./node_modules/angular-sanitize/angular-sanitize.min.js"], "base": "./node_modules/angular-sanitize" }, { "name": "angular-touch", - "src": ["./node_modules/angular-touch/angular-touch.js"], + "src": ["./node_modules/angular-touch/angular-touch.min.js"], "base": "./node_modules/angular-touch" }, { "name": "angular-ui-sortable", - "src": ["./node_modules/angular-ui-sortable/dist/sortable.js"], + "src": ["./node_modules/angular-ui-sortable/dist/sortable.min.js"], "base": "./node_modules/angular-ui-sortable/dist" }, { "name": "angular-route", - "src": ["./node_modules/angular-route/angular-route.js"], + "src": ["./node_modules/angular-route/angular-route.min.js"], "base": "./node_modules/angular-route" }, { "name": "angular-animate", - "src": ["./node_modules/angular-animate/angular-animate.js"], + "src": ["./node_modules/angular-animate/angular-animate.min.js"], "base": "./node_modules/angular-animate" }, { @@ -111,7 +111,7 @@ function dependencies() { }, { "name": "angular-messages", - "src": ["./node_modules/angular-messages/angular-messages.js"], + "src": ["./node_modules/angular-messages/angular-messages.min.js"], "base": "./node_modules/angular-messages" }, { @@ -153,7 +153,7 @@ function dependencies() { { "name": "flatpickr", "src": [ - "./node_modules/flatpickr/dist/flatpickr.js", + "./node_modules/flatpickr/dist/flatpickr.min.js", "./node_modules/flatpickr/dist/flatpickr.css", "./node_modules/flatpickr/dist/l10n/*.js" ], diff --git a/src/Umbraco.Web.UI.Client/gulp/tasks/js.js b/src/Umbraco.Web.UI.Client/gulp/tasks/js.js index b46e105942..c9d855b175 100644 --- a/src/Umbraco.Web.UI.Client/gulp/tasks/js.js +++ b/src/Umbraco.Web.UI.Client/gulp/tasks/js.js @@ -3,6 +3,8 @@ var config = require('../config'); var gulp = require('gulp'); +var minify = require('gulp-minify'); +var rename = require('gulp-rename'); var _ = require('lodash'); var MergeStream = require('merge-stream'); @@ -17,6 +19,19 @@ function js() { var stream = new MergeStream(); var task = gulp.src(config.sources.globs.js); + if (config.compile.current.minify === true) { + task = task.pipe( + minify({ + noSource: true, + ext: { min: '.min.js' }, + mangle: false + }) + ); + } else { + task = task.pipe(rename(function(path) { + path.basename += '.min'; + })); + } _.forEach(config.roots, function(root){ task = task.pipe( gulp.dest(root + config.targets.js) ) }) diff --git a/src/Umbraco.Web.UI.Client/gulp/util/processJs.js b/src/Umbraco.Web.UI.Client/gulp/util/processJs.js index 6c6f1276e7..ecb65af101 100644 --- a/src/Umbraco.Web.UI.Client/gulp/util/processJs.js +++ b/src/Umbraco.Web.UI.Client/gulp/util/processJs.js @@ -8,6 +8,8 @@ var sort = require('gulp-sort'); var concat = require('gulp-concat'); var wrap = require("gulp-wrap-js"); var embedTemplates = require('gulp-angular-embed-templates'); +var minify = require('gulp-minify'); +var rename = require('gulp-rename'); var _ = require('lodash'); module.exports = function (files, out) { @@ -34,6 +36,20 @@ module.exports = function (files, out) { task = task.pipe(concat(out)).pipe(wrap('(function(){\n%= body %\n})();')) + if (config.compile.current.minify === true) { + task = task.pipe( + minify({ + noSource:true, + ext: {min:'.min.js'}, + mangle: false + }) + ); + } else { + task = task.pipe(rename(function(path) { + path.basename += '.min'; + })); + } + _.forEach(config.roots, function(root){ task = task.pipe(gulp.dest(root + config.targets.js)); }) diff --git a/src/Umbraco.Web.UI.Client/package-lock.json b/src/Umbraco.Web.UI.Client/package-lock.json index 452b5c2071..9ae397af79 100644 --- a/src/Umbraco.Web.UI.Client/package-lock.json +++ b/src/Umbraco.Web.UI.Client/package-lock.json @@ -6783,6 +6783,104 @@ } } }, + "gulp-minify": { + "version": "3.1.0", + "resolved": "https://registry.npmjs.org/gulp-minify/-/gulp-minify-3.1.0.tgz", + "integrity": "sha512-ixF41aYg+NQikI8hpoHdEclYcQkbGdXQu1CBdHaU7Epg8H6e8d2jWXw1+rBPgYwl/XpKgjHj7NI6gkhoSNSSAg==", + "dev": true, + "requires": { + "ansi-colors": "^1.0.1", + "minimatch": "^3.0.2", + "plugin-error": "^0.1.2", + "terser": "^3.7.6", + "through2": "^2.0.3", + "vinyl": "^2.1.0" + }, + "dependencies": { + "arr-diff": { + "version": "1.1.0", + "resolved": "https://registry.npmjs.org/arr-diff/-/arr-diff-1.1.0.tgz", + "integrity": "sha1-aHwydYFjWI/vfeezb6vklesaOZo=", + "dev": true, + "requires": { + "arr-flatten": "^1.0.1", + "array-slice": "^0.2.3" + } + }, + "arr-union": { + "version": "2.1.0", + "resolved": "https://registry.npmjs.org/arr-union/-/arr-union-2.1.0.tgz", + "integrity": "sha1-IPnqtexw9cfSFbEHexw5Fh0pLH0=", + "dev": true + }, + "array-slice": { + "version": "0.2.3", + "resolved": "https://registry.npmjs.org/array-slice/-/array-slice-0.2.3.tgz", + "integrity": "sha1-3Tz7gO15c6dRF82sabC5nshhhvU=", + "dev": true + }, + "clone": { + "version": "2.1.2", + "resolved": "https://registry.npmjs.org/clone/-/clone-2.1.2.tgz", + "integrity": "sha1-G39Ln1kfHo+DZwQBYANFoCiHQ18=", + "dev": true + }, + "clone-stats": { + "version": "1.0.0", + "resolved": "https://registry.npmjs.org/clone-stats/-/clone-stats-1.0.0.tgz", + "integrity": "sha1-s3gt/4u1R04Yuba/D9/ngvh3doA=", + "dev": true + }, + "extend-shallow": { + "version": "1.1.4", + "resolved": "https://registry.npmjs.org/extend-shallow/-/extend-shallow-1.1.4.tgz", + "integrity": "sha1-Gda/lN/AnXa6cR85uHLSH/TdkHE=", + "dev": true, + "requires": { + "kind-of": "^1.1.0" + } + }, + "kind-of": { + "version": "1.1.0", + "resolved": "https://registry.npmjs.org/kind-of/-/kind-of-1.1.0.tgz", + "integrity": "sha1-FAo9LUGjbS78+pN3tiwk+ElaXEQ=", + "dev": true + }, + "plugin-error": { + "version": "0.1.2", + "resolved": "https://registry.npmjs.org/plugin-error/-/plugin-error-0.1.2.tgz", + "integrity": "sha1-O5uzM1zPAPQl4HQ34ZJ2ln2kes4=", + "dev": true, + "requires": { + "ansi-cyan": "^0.1.1", + "ansi-red": "^0.1.1", + "arr-diff": "^1.0.1", + "arr-union": "^2.0.1", + "extend-shallow": "^1.1.2" + } + }, + "replace-ext": { + "version": "1.0.1", + "resolved": "https://registry.npmjs.org/replace-ext/-/replace-ext-1.0.1.tgz", + "integrity": "sha512-yD5BHCe7quCgBph4rMQ+0KkIRKwWCrHDOX1p1Gp6HwjPM5kVoCdKGNhN7ydqqsX6lJEnQDKZ/tFMiEdQ1dvPEw==", + "dev": true + }, + "vinyl": { + "version": "2.2.1", + "resolved": "https://registry.npmjs.org/vinyl/-/vinyl-2.2.1.tgz", + "integrity": "sha512-LII3bXRFBZLlezoG5FfZVcXflZgWP/4dCwKtxd5ky9+LOtM4CS3bIRQsmR1KMnMW07jpE8fqR2lcxPZ+8sJIcw==", + "dev": true, + "requires": { + "clone": "^2.1.1", + "clone-buffer": "^1.0.0", + "clone-stats": "^1.0.0", + "cloneable-readable": "^1.0.0", + "remove-trailing-separator": "^1.0.1", + "replace-ext": "^1.0.0" + } + } + } + }, "gulp-notify": { "version": "3.2.0", "resolved": "https://registry.npmjs.org/gulp-notify/-/gulp-notify-3.2.0.tgz", @@ -15021,6 +15119,24 @@ "urix": "^0.1.0" } }, + "source-map-support": { + "version": "0.5.19", + "resolved": "https://registry.npmjs.org/source-map-support/-/source-map-support-0.5.19.tgz", + "integrity": "sha512-Wonm7zOCIJzBGQdB+thsPar0kYuCIzYvxZwlBa87yi/Mdjv7Tip2cyVbLj5o0cFPN4EVkuTwb3GDDyUx2DGnGw==", + "dev": true, + "requires": { + "buffer-from": "^1.0.0", + "source-map": "^0.6.0" + }, + "dependencies": { + "source-map": { + "version": "0.6.1", + "resolved": "https://registry.npmjs.org/source-map/-/source-map-0.6.1.tgz", + "integrity": "sha512-UjgapumWlbMhkBgzT7Ykc5YXUT46F0iKu8SGXq0bcwP5dz/h0Plj6enJqjz1Zbq2l5WaqYnrVbwWOWMyF3F47g==", + "dev": true + } + } + }, "source-map-url": { "version": "0.4.0", "resolved": "https://registry.npmjs.org/source-map-url/-/source-map-url-0.4.0.tgz", @@ -15548,6 +15664,25 @@ "uuid": "^3.0.1" } }, + "terser": { + "version": "3.17.0", + "resolved": "https://registry.npmjs.org/terser/-/terser-3.17.0.tgz", + "integrity": "sha512-/FQzzPJmCpjAH9Xvk2paiWrFq+5M6aVOf+2KRbwhByISDX/EujxsK+BAvrhb6H+2rtrLCHK9N01wO014vrIwVQ==", + "dev": true, + "requires": { + "commander": "^2.19.0", + "source-map": "~0.6.1", + "source-map-support": "~0.5.10" + }, + "dependencies": { + "source-map": { + "version": "0.6.1", + "resolved": "https://registry.npmjs.org/source-map/-/source-map-0.6.1.tgz", + "integrity": "sha512-UjgapumWlbMhkBgzT7Ykc5YXUT46F0iKu8SGXq0bcwP5dz/h0Plj6enJqjz1Zbq2l5WaqYnrVbwWOWMyF3F47g==", + "dev": true + } + } + }, "text-hex": { "version": "1.0.0", "resolved": "https://registry.npmjs.org/text-hex/-/text-hex-1.0.0.tgz", diff --git a/src/Umbraco.Web.UI.Client/package.json b/src/Umbraco.Web.UI.Client/package.json index b7a4779e07..dc2cfd3948 100644 --- a/src/Umbraco.Web.UI.Client/package.json +++ b/src/Umbraco.Web.UI.Client/package.json @@ -74,6 +74,7 @@ "gulp-watch": "5.0.1", "gulp-wrap": "0.15.0", "gulp-wrap-js": "0.4.1", + "gulp-minify": "3.1.0", "jasmine-core": "3.5.0", "jsdom": "16.4.0", "karma": "4.4.1", diff --git a/src/Umbraco.Web.UI.Client/src/install.loader.js b/src/Umbraco.Web.UI.Client/src/install.loader.js index 8c17b8cd64..832e28ad34 100644 --- a/src/Umbraco.Web.UI.Client/src/install.loader.js +++ b/src/Umbraco.Web.UI.Client/src/install.loader.js @@ -1,20 +1,20 @@ LazyLoad.js([ 'lib/jquery/jquery.min.js', - 'lib/angular/angular.js', - 'lib/angular-cookies/angular-cookies.js', - 'lib/angular-touch/angular-touch.js', - 'lib/angular-sanitize/angular-sanitize.js', - 'lib/angular-messages/angular-messages.js', + 'lib/angular/angular.min.js', + 'lib/angular-cookies/angular-cookies.min.js', + 'lib/angular-touch/angular-touch.min.js', + 'lib/angular-sanitize/angular-sanitize.min.js', + 'lib/angular-messages/angular-messages.min.js', 'lib/angular-aria/angular-aria.min.js', 'lib/underscore/underscore-min.js', - 'lib/angular-ui-sortable/sortable.js', + 'lib/angular-ui-sortable/sortable.min.js', - 'js/utilities.js', + 'js/utilities.min.js', - 'js/installer.app.js', - 'js/umbraco.directives.js', - 'js/umbraco.installer.js' + 'js/installer.app.min.js', + 'js/umbraco.directives.min.js', + 'js/umbraco.installer.min.js' ], function () { jQuery(document).ready(function () { diff --git a/src/Umbraco.Web.UI.Client/test/config/karma.conf.js b/src/Umbraco.Web.UI.Client/test/config/karma.conf.js index 2ece03c02a..86a65d1698 100644 --- a/src/Umbraco.Web.UI.Client/test/config/karma.conf.js +++ b/src/Umbraco.Web.UI.Client/test/config/karma.conf.js @@ -15,15 +15,15 @@ module.exports = function (config) { //libraries 'node_modules/jquery/dist/jquery.min.js', - 'node_modules/angular/angular.js', - 'node_modules/angular-animate/angular-animate.js', - 'node_modules/angular-cookies/angular-cookies.js', + 'node_modules/angular/angular.min.js', + 'node_modules/angular-animate/angular-animate.min.js', + 'node_modules/angular-cookies/angular-cookies.min.js', 'node_modules/angular-aria/angular-aria.min.js', 'node_modules/angular-local-storage/dist/angular-local-storage.min.js', - 'node_modules/angular-route/angular-route.js', - 'node_modules/angular-sanitize/angular-sanitize.js', + 'node_modules/angular-route/angular-route.min.js', + 'node_modules/angular-sanitize/angular-sanitize.min.js', 'node_modules/angular-mocks/angular-mocks.js', - 'node_modules/angular-ui-sortable/dist/sortable.js', + 'node_modules/angular-ui-sortable/dist/sortable.min.js', 'node_modules/underscore/underscore-min.js', 'node_modules/moment/min/moment-with-locales.js', 'lib/umbraco/Extensions.js', @@ -34,12 +34,12 @@ module.exports = function (config) { 'test/config/app.unit.js', //application files - '../Umbraco.Web.UI/Umbraco/js/*.controllers.js', - '../Umbraco.Web.UI/Umbraco/js/*.directives.js', - '../Umbraco.Web.UI/Umbraco/js/*.filters.js', - '../Umbraco.Web.UI/Umbraco/js/*.services.js', - '../Umbraco.Web.UI/Umbraco/js/*.interceptors.js', - '../Umbraco.Web.UI/Umbraco/js/*.resources.js', + '../Umbraco.Web.UI/Umbraco/js/*.controllers.min.js', + '../Umbraco.Web.UI/Umbraco/js/*.directives.min.js', + '../Umbraco.Web.UI/Umbraco/js/*.filters.min.js', + '../Umbraco.Web.UI/Umbraco/js/*.services.min.js', + '../Umbraco.Web.UI/Umbraco/js/*.interceptors.min.js', + '../Umbraco.Web.UI/Umbraco/js/*.resources.min.js', //mocked data and routing 'src/common/mocks/umbraco.servervariables.js', From cfa9adc87eb66a8c5f2aa31771e4c768c83d66e3 Mon Sep 17 00:00:00 2001 From: Kenn Jacobsen Date: Thu, 18 Feb 2021 10:07:09 +0100 Subject: [PATCH 2/2] Split backoffice core and extensions JS into two different bundles and disable minification for all core JS bundles --- .../WebAssets/IRuntimeMinifier.cs | 3 ++- .../WebAssets/BackOfficeWebAssets.cs | 23 ++++++++++--------- .../WebAssets/RuntimeMinifierExtensions.cs | 6 +++-- .../SmidgeRuntimeMinifier.cs | 5 ++-- 4 files changed, 21 insertions(+), 16 deletions(-) diff --git a/src/Umbraco.Core/WebAssets/IRuntimeMinifier.cs b/src/Umbraco.Core/WebAssets/IRuntimeMinifier.cs index 2b68a2f4ec..1edf134171 100644 --- a/src/Umbraco.Core/WebAssets/IRuntimeMinifier.cs +++ b/src/Umbraco.Core/WebAssets/IRuntimeMinifier.cs @@ -40,6 +40,7 @@ namespace Umbraco.Core.WebAssets /// Creates a JS bundle /// /// + /// /// /// /// All files must be absolute paths, relative paths will throw @@ -47,7 +48,7 @@ namespace Umbraco.Core.WebAssets /// /// Thrown if any of the paths specified are not absolute /// - void CreateJsBundle(string bundleName, params string[] filePaths); + void CreateJsBundle(string bundleName, bool optimizeOutput, params string[] filePaths); /// /// Renders the html script tag for the bundle diff --git a/src/Umbraco.Infrastructure/WebAssets/BackOfficeWebAssets.cs b/src/Umbraco.Infrastructure/WebAssets/BackOfficeWebAssets.cs index 93250ef981..3e82fd1dc4 100644 --- a/src/Umbraco.Infrastructure/WebAssets/BackOfficeWebAssets.cs +++ b/src/Umbraco.Infrastructure/WebAssets/BackOfficeWebAssets.cs @@ -21,7 +21,8 @@ namespace Umbraco.Web.WebAssets public const string UmbracoPreviewCssBundleName = "umbraco-preview-css"; public const string UmbracoCssBundleName = "umbraco-backoffice-css"; public const string UmbracoInitCssBundleName = "umbraco-backoffice-init-css"; - public const string UmbracoJsBundleName = "umbraco-backoffice-js"; + public const string UmbracoCoreJsBundleName = "umbraco-backoffice-js"; + public const string UmbracoExtensionsJsBundleName = "umbraco-backoffice-extensions-js"; public const string UmbracoTinyMceJsBundleName = "umbraco-tinymce-js"; public const string UmbracoUpgradeCssBundleName = "umbraco-authorize-upgrade-css"; @@ -62,20 +63,23 @@ namespace Umbraco.Web.WebAssets _runtimeMinifier.CreateCssBundle(UmbracoPreviewCssBundleName, FormatPaths("assets/css/canvasdesigner.css")); - _runtimeMinifier.CreateJsBundle(UmbracoPreviewJsBundleName, + _runtimeMinifier.CreateJsBundle(UmbracoPreviewJsBundleName, false, FormatPaths(GetScriptsForPreview())); - _runtimeMinifier.CreateJsBundle(UmbracoTinyMceJsBundleName, + _runtimeMinifier.CreateJsBundle(UmbracoTinyMceJsBundleName, false, FormatPaths(GetScriptsForTinyMce())); + _runtimeMinifier.CreateJsBundle(UmbracoCoreJsBundleName, false, + FormatPaths(GetScriptsForBackOfficeCore())); + var propertyEditorAssets = ScanPropertyEditors() .GroupBy(x => x.AssetType) .ToDictionary(x => x.Key, x => x.Select(c => c.FilePath)); _runtimeMinifier.CreateJsBundle( - UmbracoJsBundleName, + UmbracoExtensionsJsBundleName, true, FormatPaths( - GetScriptsForBackOffice( + GetScriptsForBackOfficeExtensions( propertyEditorAssets.TryGetValue(AssetType.Javascript, out var scripts) ? scripts : Enumerable.Empty()))); _runtimeMinifier.CreateCssBundle( @@ -89,12 +93,9 @@ namespace Umbraco.Web.WebAssets /// Returns scripts used to load the back office /// /// - private string[] GetScriptsForBackOffice(IEnumerable propertyEditorScripts) + private string[] GetScriptsForBackOfficeExtensions(IEnumerable propertyEditorScripts) { - var umbracoInit = GetInitBackOfficeScripts(); var scripts = new HashSet(); - foreach (var script in umbracoInit) - scripts.Add(script); foreach (var script in _parser.Manifest.Scripts) scripts.Add(script); foreach (var script in propertyEditorScripts) @@ -107,10 +108,10 @@ namespace Umbraco.Web.WebAssets /// Returns the list of scripts for back office initialization /// /// - private IEnumerable GetInitBackOfficeScripts() + private string[] GetScriptsForBackOfficeCore() { var resources = JsonConvert.DeserializeObject(Resources.JsInitialize); - return resources.Where(x => x.Type == JTokenType.String).Select(x => x.ToString()); + return resources.Where(x => x.Type == JTokenType.String).Select(x => x.ToString()).ToArray(); } /// diff --git a/src/Umbraco.Infrastructure/WebAssets/RuntimeMinifierExtensions.cs b/src/Umbraco.Infrastructure/WebAssets/RuntimeMinifierExtensions.cs index cc3be4d785..ec60f632d7 100644 --- a/src/Umbraco.Infrastructure/WebAssets/RuntimeMinifierExtensions.cs +++ b/src/Umbraco.Infrastructure/WebAssets/RuntimeMinifierExtensions.cs @@ -1,4 +1,5 @@ using System; +using System.Linq; using System.Text; using System.Threading.Tasks; using Umbraco.Core.Configuration.Models; @@ -15,8 +16,9 @@ namespace Umbraco.Web.WebAssets /// public static async Task GetScriptForLoadingBackOfficeAsync(this IRuntimeMinifier minifier, GlobalSettings globalSettings, IHostingEnvironment hostingEnvironment) { - var files = await minifier.GetAssetPathsAsync(BackOfficeWebAssets.UmbracoJsBundleName); - var result = BackOfficeJavaScriptInitializer.GetJavascriptInitialization(files, "umbraco", globalSettings, hostingEnvironment); + var coreScripts = await minifier.GetAssetPathsAsync(BackOfficeWebAssets.UmbracoCoreJsBundleName); + var extensionsScripts = await minifier.GetAssetPathsAsync(BackOfficeWebAssets.UmbracoExtensionsJsBundleName); + var result = BackOfficeJavaScriptInitializer.GetJavascriptInitialization(coreScripts.Union(extensionsScripts), "umbraco", globalSettings, hostingEnvironment); result += await GetStylesheetInitializationAsync(minifier); return result; diff --git a/src/Umbraco.Web.Common/RuntimeMinification/SmidgeRuntimeMinifier.cs b/src/Umbraco.Web.Common/RuntimeMinification/SmidgeRuntimeMinifier.cs index 29a0e41998..d3e1be65b3 100644 --- a/src/Umbraco.Web.Common/RuntimeMinification/SmidgeRuntimeMinifier.cs +++ b/src/Umbraco.Web.Common/RuntimeMinification/SmidgeRuntimeMinifier.cs @@ -74,7 +74,7 @@ namespace Umbraco.Web.Common.RuntimeMinification public async Task RenderCssHereAsync(string bundleName) => (await _smidge.SmidgeHelper.CssHereAsync(bundleName, _hostingEnvironment.IsDebugMode)).ToString(); - public void CreateJsBundle(string bundleName, params string[] filePaths) + public void CreateJsBundle(string bundleName, bool optimizeOutput, params string[] filePaths) { if (filePaths.Any(f => !f.StartsWith("/") && !f.StartsWith("~/"))) throw new InvalidOperationException("All file paths must be absolute"); @@ -85,7 +85,8 @@ namespace Umbraco.Web.Common.RuntimeMinification // Here we could configure bundle options instead of using smidge's global defaults. // For example we can use our own custom cache buster for this bundle without having the global one // affect this or vice versa. - var bundle = _bundles.Create(bundleName, _jsPipeline.Value, WebFileType.Js, filePaths); + var pipeline = optimizeOutput ? _jsPipeline.Value : _bundles.PipelineFactory.Create(); + var bundle = _bundles.Create(bundleName, pipeline, WebFileType.Js, filePaths); } public async Task RenderJsHereAsync(string bundleName) => (await _smidge.SmidgeHelper.JsHereAsync(bundleName, _hostingEnvironment.IsDebugMode)).ToString();