diff --git a/modules/_node-scripts/bundle/cssLoad/writeCSSExportsLoaderModules.mjs b/modules/_node-scripts/bundle/cssLoad/writeCSSExportsLoaderModules.mjs index 994aca6da2f88f..beec4df58a640f 100644 --- a/modules/_node-scripts/bundle/cssLoad/writeCSSExportsLoaderModules.mjs +++ b/modules/_node-scripts/bundle/cssLoad/writeCSSExportsLoaderModules.mjs @@ -6,8 +6,13 @@ import fs from 'fs/promises'; import path from 'path'; -import {BUILD_NPM_EXPORTS_PATH} from '../../util/constants.mjs'; +import { + BUILD_CSS_EXPORTS_PATH, + BUILD_NPM_EXPORTS_PATH, +} from '../../util/constants.mjs'; import getFlatName from '../../util/getFlatName.mjs'; +import calculateFileHash from '../util/calculateFileHash.mjs'; +import extractFileHash from '../util/extractFileHash.mjs'; import getCSSLoadJavaScript from '../util/getCSSLoadJavaScript.mjs'; export default async function writeCSSExportsLoaderModules( @@ -30,17 +35,31 @@ export default async function writeCSSExportsLoaderModules( async function writeCSSExportLoaderModule(webContextPath, moduleName) { const flatModuleName = getFlatName(moduleName); + const baseFlatModuleName = flatModuleName.substring( + 0, + flatModuleName.length - 4 + ); + + const cssFiles = await fs.readdir(path.join(BUILD_CSS_EXPORTS_PATH)); + + const cssFile = cssFiles.find((cssFile) => + cssFile.startsWith(`${baseFlatModuleName}.(`) + ); + + const cssFileHash = extractFileHash(cssFile); + + const source = getCSSLoadJavaScript( + webContextPath, + `__liferay__/css/${baseFlatModuleName}.(${cssFileHash}).css` + ); + + const hash = await calculateFileHash(source); + const cssLoaderPath = path.join( BUILD_NPM_EXPORTS_PATH, - `${flatModuleName}.js` + `${flatModuleName}.(${hash}).js` ); await fs.mkdir(path.dirname(cssLoaderPath), {recursive: true}); - await fs.writeFile( - cssLoaderPath, - getCSSLoadJavaScript( - webContextPath, - `__liferay__/css/${flatModuleName}` - ) - ); + await fs.writeFile(cssLoaderPath, source); } diff --git a/modules/_node-scripts/bundle/esbuild/bundleCSSExports.mjs b/modules/_node-scripts/bundle/esbuild/bundleCSSExports.mjs index 394a4b8ca745aa..c71cc9a99eeefd 100644 --- a/modules/_node-scripts/bundle/esbuild/bundleCSSExports.mjs +++ b/modules/_node-scripts/bundle/esbuild/bundleCSSExports.mjs @@ -30,6 +30,7 @@ async function bundle(moduleName) { const entryPoint = getEntryPoint(moduleName); const esbuildConfig = { + entryNames: '[dir]/[name].([hash])', entryPoints: [entryPoint], loader: { '.png': 'empty', diff --git a/modules/_node-scripts/bundle/esbuild/bundleJavaScriptExports.mjs b/modules/_node-scripts/bundle/esbuild/bundleJavaScriptExports.mjs index dbc1707a59933c..9818a77ae2b887 100644 --- a/modules/_node-scripts/bundle/esbuild/bundleJavaScriptExports.mjs +++ b/modules/_node-scripts/bundle/esbuild/bundleJavaScriptExports.mjs @@ -57,6 +57,7 @@ async function bundle( const esbuildConfig = { alias: projectAlias, bundle: true, + entryNames: '[dir]/[name].([hash])', entryPoints: [entryPoint], format: 'esm', outdir: BUILD_MAIN_EXPORTS_PATH, @@ -103,14 +104,17 @@ async function bundle( const flatModuleName = getFlatName(moduleName); - await runEsbuild(esbuildConfig, flatModuleName); + const {metafile} = await runEsbuild(esbuildConfig, flatModuleName); + const {outputs} = metafile; - await relocateSourcemap( - path.join( - BUILD_MAIN_EXPORTS_PATH, - 'exports', - `${flatModuleName}.js.map` - ), - projectWebContextPath - ); + await Promise.all([ + ...Object.keys(outputs).map(async (output) => { + if (output.endsWith('.map')) { + return relocateSourcemap( + path.join(output), + projectWebContextPath + ); + } + }), + ]); } diff --git a/modules/_node-scripts/bundle/esbuild/bundleJavaScriptMain.mjs b/modules/_node-scripts/bundle/esbuild/bundleJavaScriptMain.mjs index 2f0b9fa8d7afad..6b663512790730 100644 --- a/modules/_node-scripts/bundle/esbuild/bundleJavaScriptMain.mjs +++ b/modules/_node-scripts/bundle/esbuild/bundleJavaScriptMain.mjs @@ -41,6 +41,7 @@ export default async function bundleJavaScriptMain( const esbuildConfig = { alias: projectAlias, bundle: true, + entryNames: '[dir]/[name].([hash])', entryPoints: [ ...Object.keys(submodules).map((submoduleName) => ({ in: path.resolve(submodules[submoduleName]), @@ -97,19 +98,18 @@ export default async function bundleJavaScriptMain( ); } - await runEsbuild(esbuildConfig, 'main'); + const {metafile} = await runEsbuild(esbuildConfig, 'main'); + const {outputs} = metafile; await Promise.all([ - relocateSourcemap( - path.join(BUILD_MAIN_EXPORTS_PATH, 'index.js.map'), - projectWebContextPath - ), - ...Object.keys(submodules).map((submodule) => - relocateSourcemap( - path.join(BUILD_MAIN_EXPORTS_PATH, `${submodule}.js.map`), - projectWebContextPath - ) - ), + ...Object.keys(outputs).map(async (output) => { + if (output.endsWith('.map')) { + return relocateSourcemap( + path.join(output), + projectWebContextPath + ); + } + }), writeLanguageJSON(languageJSON), ]); } diff --git a/modules/_node-scripts/bundle/esbuild/plugins/getScssLoaderPlugin.mjs b/modules/_node-scripts/bundle/esbuild/plugins/getScssLoaderPlugin.mjs index c831b8a26c4092..6c3f63816730e6 100644 --- a/modules/_node-scripts/bundle/esbuild/plugins/getScssLoaderPlugin.mjs +++ b/modules/_node-scripts/bundle/esbuild/plugins/getScssLoaderPlugin.mjs @@ -29,6 +29,8 @@ export default function getScssLoaderPlugin(projectWebContextPath) { async (args) => { const projectPath = path.relative(SRC_PATH, args.path); + const projectBasePath = projectPath.replace(/\.scss$/, ''); + const cssFiles = await fs.readdir( path.join( BUILD_SASS_CACHE_PATH, @@ -36,8 +38,6 @@ export default function getScssLoaderPlugin(projectWebContextPath) { ) ); - const projectBasePath = projectPath.replace(/\.scss$/, ''); - const cssBasename = cssFiles.find((cssFile) => cssFile.startsWith( `${path.basename(projectBasePath)}.(` diff --git a/modules/_node-scripts/bundle/esbuild/runEsbuild.mjs b/modules/_node-scripts/bundle/esbuild/runEsbuild.mjs index bec8b08b981c0e..f350d5f76a19b9 100644 --- a/modules/_node-scripts/bundle/esbuild/runEsbuild.mjs +++ b/modules/_node-scripts/bundle/esbuild/runEsbuild.mjs @@ -8,17 +8,21 @@ import fs from 'fs/promises'; import path from 'path'; export default async function runEsbuild(esbuildConfig, configName) { - await Promise.all([ + const [result] = await Promise.all([ doRunEsbuild(esbuildConfig, configName), writeDebugEsbuildConfig(esbuildConfig, configName), ]); + + return result; } async function doRunEsbuild(esbuildesbuildConfig, configName) { + let result; + const start = performance.now(); try { - await esbuild.build({ + result = await esbuild.build({ define: { // Flag to use React 16 instead of React 18. See render.tsx in frontend-js-react-web. @@ -27,6 +31,7 @@ async function doRunEsbuild(esbuildesbuildConfig, configName) { ? 'true' : 'false', }, + metafile: true, minify: process.env.NODE_ENV === 'production', ...esbuildesbuildConfig, }); @@ -40,6 +45,8 @@ async function doRunEsbuild(esbuildesbuildConfig, configName) { console.log( `⌛ Esbuild for ${configName} took: ${(lapse / 1000).toFixed(3)} s` ); + + return result; } async function writeDebugEsbuildConfig(esbuildConfig, configName) { diff --git a/modules/_node-scripts/bundle/index.mjs b/modules/_node-scripts/bundle/index.mjs index afe5a857544803..a98c423bf181ed 100644 --- a/modules/_node-scripts/bundle/index.mjs +++ b/modules/_node-scripts/bundle/index.mjs @@ -74,7 +74,6 @@ export default async function main() { // CSS exports bundling bundleCSSExports(projectExports), - writeCSSExportsLoaderModules(projectExports, projectWebContextPath), // AMD bridging @@ -100,5 +99,7 @@ export default async function main() { ), ]); + await writeCSSExportsLoaderModules(projectExports, projectWebContextPath); + await writeTimings(start, endConfig); } diff --git a/modules/_node-scripts/package.json b/modules/_node-scripts/package.json index 18bb8736849432..cbf865afdea9da 100644 --- a/modules/_node-scripts/package.json +++ b/modules/_node-scripts/package.json @@ -4,7 +4,7 @@ "node-scripts": "./bin.js" }, "com.liferay": { - "sha256": "00d2a972afe65186b666efa058975f387ea44673708b4158204d3bbdba5cc781" + "sha256": "731360bca3b133cedbdc76f8b0ee91196992ac777cbd90f7b21ae9f4105701fd" }, "dependencies": { "@babel/preset-env": "7.24.7", diff --git a/modules/apps/frontend-editor/frontend-editor-alloyeditor-web/src/main/resources/META-INF/resources/resources.jsp b/modules/apps/frontend-editor/frontend-editor-alloyeditor-web/src/main/resources/META-INF/resources/resources.jsp index 6eb65951dd0075..ecc7ea29b14fc2 100644 --- a/modules/apps/frontend-editor/frontend-editor-alloyeditor-web/src/main/resources/META-INF/resources/resources.jsp +++ b/modules/apps/frontend-editor/frontend-editor-alloyeditor-web/src/main/resources/META-INF/resources/resources.jsp @@ -8,6 +8,12 @@ <%@ include file="/init.jsp" %> <% +String alloyEditorServletContextName = PortalWebResourcesUtil.getServletContext( + PortalWebResourceConstants.RESOURCE_TYPE_EDITOR_ALLOYEDITOR +).getServletContextName(); +String ckEditorServletContextName = PortalWebResourcesUtil.getServletContext( + PortalWebResourceConstants.RESOURCE_TYPE_EDITOR_CKEDITOR +).getServletContextName(); String editorName = (String)request.getAttribute(AlloyEditorConstants.ATTRIBUTE_NAMESPACE + ":editorName"); %> @@ -16,18 +22,14 @@ String editorName = (String)request.getAttribute(AlloyEditorConstants.ATTRIBUTE_ > - <% - long javaScriptLastModified = PortalWebResourcesUtil.getLastModified(PortalWebResourceConstants.RESOURCE_TYPE_EDITOR_ALLOYEDITOR); - %> - window.ALLOYEDITOR_BASEPATH = '<%= PortalUtil.getPathProxy() + application.getContextPath() %>/alloyeditor/'; - + - + diff --git a/modules/apps/frontend-editor/frontend-editor-ckeditor-web/src/main/resources/META-INF/resources/init.jsp b/modules/apps/frontend-editor/frontend-editor-ckeditor-web/src/main/resources/META-INF/resources/init.jsp index d65cf6c70a1e78..85e49e97ac629b 100644 --- a/modules/apps/frontend-editor/frontend-editor-ckeditor-web/src/main/resources/META-INF/resources/init.jsp +++ b/modules/apps/frontend-editor/frontend-editor-ckeditor-web/src/main/resources/META-INF/resources/init.jsp @@ -30,7 +30,6 @@ page import="com.liferay.portal.kernel.util.GetterUtil" %><%@ page import="com.liferay.portal.kernel.util.HashMapBuilder" %><%@ page import="com.liferay.portal.kernel.util.HtmlUtil" %><%@ page import="com.liferay.portal.kernel.util.JavaConstants" %><%@ -page import="com.liferay.portal.kernel.util.PortalUtil" %><%@ page import="com.liferay.portal.kernel.util.SessionClicks" %><%@ page import="com.liferay.portal.kernel.util.TextFormatter" %><%@ page import="com.liferay.portal.kernel.util.URLCodec" %><%@ diff --git a/modules/apps/frontend-editor/frontend-editor-ckeditor-web/src/main/resources/META-INF/resources/resources.jsp b/modules/apps/frontend-editor/frontend-editor-ckeditor-web/src/main/resources/META-INF/resources/resources.jsp index 7e38ca0b61e263..85a133b99f9033 100644 --- a/modules/apps/frontend-editor/frontend-editor-ckeditor-web/src/main/resources/META-INF/resources/resources.jsp +++ b/modules/apps/frontend-editor/frontend-editor-ckeditor-web/src/main/resources/META-INF/resources/resources.jsp @@ -8,6 +8,9 @@ <%@ include file="/init.jsp" %> <% +String ckEditorServletContextName = PortalWebResourcesUtil.getServletContext( + PortalWebResourceConstants.RESOURCE_TYPE_EDITOR_CKEDITOR +).getServletContextName(); String editorName = (String)request.getAttribute(CKEditorConstants.ATTRIBUTE_NAMESPACE + ":editorName"); boolean inlineEdit = GetterUtil.getBoolean((String)request.getAttribute(CKEditorConstants.ATTRIBUTE_NAMESPACE + ":inlineEdit")); String inlineEditSaveURL = GetterUtil.getString((String)request.getAttribute(CKEditorConstants.ATTRIBUTE_NAMESPACE + ":inlineEditSaveURL")); @@ -22,14 +25,10 @@ String inlineEditSaveURL = GetterUtil.getString((String)request.getAttribute(CKE } - <% - long javaScriptLastModified = PortalWebResourcesUtil.getLastModified(PortalWebResourceConstants.RESOURCE_TYPE_EDITOR_CKEDITOR); - %> - - + - + diff --git a/modules/apps/frontend-js/frontend-js-importmaps-extender/src/main/java/com/liferay/frontend/js/importmaps/extender/internal/configuration/JSImportMapsConfiguration.java b/modules/apps/frontend-js/frontend-js-importmaps-extender/src/main/java/com/liferay/frontend/js/importmaps/extender/internal/configuration/JSImportMapsConfiguration.java deleted file mode 100644 index 3bae08e59ef196..00000000000000 --- a/modules/apps/frontend-js/frontend-js-importmaps-extender/src/main/java/com/liferay/frontend/js/importmaps/extender/internal/configuration/JSImportMapsConfiguration.java +++ /dev/null @@ -1,33 +0,0 @@ -/** - * SPDX-FileCopyrightText: (c) 2000 Liferay, Inc. https://liferay.com - * SPDX-License-Identifier: LGPL-2.1-or-later OR LicenseRef-Liferay-DXP-EULA-2.0.0-2023-06 - */ - -package com.liferay.frontend.js.importmaps.extender.internal.configuration; - -import aQute.bnd.annotation.metatype.Meta; - -import com.liferay.portal.configuration.metatype.annotations.ExtendedObjectClassDefinition; - -/** - * @author Iván Zaera Avellón - */ -@ExtendedObjectClassDefinition(category = "infrastructure", generateUI = false) -@Meta.OCD( - description = "frontend-js-import-maps-description", - id = "com.liferay.frontend.js.importmaps.extender.internal.configuration.JSImportMapsConfiguration", - localization = "content/Language", - name = "frontend-js-import-maps-configuration-name" -) -public interface JSImportMapsConfiguration { - - @Meta.AD(deflt = "true", name = "enable-import-maps", required = false) - public boolean enableImportMaps(); - - @Meta.AD( - deflt = "false", description = "enable-es-module-shims-help", - name = "enable-es-module-shims", required = false - ) - public boolean enableESModuleShims(); - -} \ No newline at end of file diff --git a/modules/apps/frontend-js/frontend-js-importmaps-extender/src/main/java/com/liferay/frontend/js/importmaps/extender/internal/servlet/taglib/JSImportMapsExtenderTopHeadDynamicInclude.java b/modules/apps/frontend-js/frontend-js-importmaps-extender/src/main/java/com/liferay/frontend/js/importmaps/extender/internal/servlet/taglib/JSImportMapsExtenderTopHeadDynamicInclude.java index 277357017a9db6..394c3c38b4f7d8 100644 --- a/modules/apps/frontend-js/frontend-js-importmaps-extender/src/main/java/com/liferay/frontend/js/importmaps/extender/internal/servlet/taglib/JSImportMapsExtenderTopHeadDynamicInclude.java +++ b/modules/apps/frontend-js/frontend-js-importmaps-extender/src/main/java/com/liferay/frontend/js/importmaps/extender/internal/servlet/taglib/JSImportMapsExtenderTopHeadDynamicInclude.java @@ -7,18 +7,12 @@ import com.liferay.frontend.js.importmaps.extender.DynamicJSImportMapsContributor; import com.liferay.frontend.js.importmaps.extender.JSImportMapsContributor; -import com.liferay.frontend.js.importmaps.extender.internal.configuration.JSImportMapsConfiguration; import com.liferay.frontend.js.importmaps.extender.internal.osgi.util.tracker.DynamicJSImportMapsContributorServiceTrackerCustomizer; import com.liferay.frontend.js.importmaps.extender.internal.osgi.util.tracker.JSImportMapsContributorServiceTrackerCustomizer; -import com.liferay.portal.configuration.metatype.bnd.util.ConfigurableUtil; import com.liferay.portal.kernel.content.security.policy.ContentSecurityPolicyNonceProviderUtil; -import com.liferay.portal.kernel.frontend.esm.FrontendESMUtil; import com.liferay.portal.kernel.servlet.taglib.BaseDynamicInclude; import com.liferay.portal.kernel.servlet.taglib.DynamicInclude; -import com.liferay.portal.kernel.util.HashMapBuilder; import com.liferay.portal.kernel.util.Portal; -import com.liferay.portal.url.builder.AbsolutePortalURLBuilder; -import com.liferay.portal.url.builder.AbsolutePortalURLBuilderFactory; import jakarta.servlet.http.HttpServletRequest; import jakarta.servlet.http.HttpServletResponse; @@ -30,7 +24,6 @@ import org.osgi.service.component.annotations.Activate; import org.osgi.service.component.annotations.Component; import org.osgi.service.component.annotations.Deactivate; -import org.osgi.service.component.annotations.Modified; import org.osgi.service.component.annotations.Reference; import org.osgi.util.tracker.ServiceTracker; @@ -38,7 +31,6 @@ * @author Iván Zaera Avellón */ @Component( - configurationPid = "com.liferay.frontend.js.importmaps.extender.internal.configuration.JSImportMapsConfiguration", property = "service.ranking:Integer=" + Integer.MAX_VALUE, service = DynamicInclude.class ) @@ -53,51 +45,15 @@ public void include( PrintWriter printWriter = httpServletResponse.getWriter(); - if (_jsImportMapsConfiguration.enableImportMaps()) { - printWriter.print(""); - - _jsImportMapsCache.writeImportMaps(httpServletRequest, printWriter); - - printWriter.print(""); - } - - if (_jsImportMapsConfiguration.enableESModuleShims()) { - printWriter.print("{\"shimMode\": "); - printWriter.print("true}\n"); - } + printWriter.print(""); + + _jsImportMapsCache.writeImportMaps(httpServletRequest, printWriter); + + printWriter.print(""); } @Override @@ -109,8 +65,6 @@ public void register(DynamicIncludeRegistry dynamicIncludeRegistry) { protected void activate(BundleContext bundleContext) { _bundleContext = bundleContext; - modified(); - _jsImportMapsCache = new JSImportMapsCache(_portal); _dynamicJSImportMapsContributorServiceTracker = new ServiceTracker<>( @@ -141,33 +95,11 @@ protected void deactivate() { _jsImportMapsContributorServiceTracker = null; } - @Modified - protected void modified() { - - // See LPS-165021 - - _jsImportMapsConfiguration = ConfigurableUtil.createConfigurable( - JSImportMapsConfiguration.class, - HashMapBuilder.put( - "enable-es-module-shims", false - ).put( - "enable-import-maps", true - ).build()); - - FrontendESMUtil.setScriptType( - _jsImportMapsConfiguration.enableESModuleShims() ? "module-shim" : - "module"); - } - - @Reference - private AbsolutePortalURLBuilderFactory _absolutePortalURLBuilderFactory; - private volatile BundleContext _bundleContext; private ServiceTracker _dynamicJSImportMapsContributorServiceTracker; private JSImportMapsCache _jsImportMapsCache; - private volatile JSImportMapsConfiguration _jsImportMapsConfiguration; private ServiceTracker _jsImportMapsContributorServiceTracker; diff --git a/modules/apps/frontend-js/frontend-js-loader-modules-extender/src/main/java/com/liferay/frontend/js/loader/modules/extender/internal/servlet/taglib/JSLoaderTopHeadDynamicInclude.java b/modules/apps/frontend-js/frontend-js-loader-modules-extender/src/main/java/com/liferay/frontend/js/loader/modules/extender/internal/servlet/taglib/JSLoaderTopHeadDynamicInclude.java index a88b7a7df70969..52e7056adb66d3 100644 --- a/modules/apps/frontend-js/frontend-js-loader-modules-extender/src/main/java/com/liferay/frontend/js/loader/modules/extender/internal/servlet/taglib/JSLoaderTopHeadDynamicInclude.java +++ b/modules/apps/frontend-js/frontend-js-loader-modules-extender/src/main/java/com/liferay/frontend/js/loader/modules/extender/internal/servlet/taglib/JSLoaderTopHeadDynamicInclude.java @@ -11,7 +11,6 @@ import com.liferay.portal.kernel.content.security.policy.ContentSecurityPolicyNonceProvider; import com.liferay.portal.kernel.content.security.policy.ContentSecurityPolicyNonceProviderUtil; import com.liferay.portal.kernel.feature.flag.FeatureFlagManagerUtil; -import com.liferay.portal.kernel.frontend.esm.FrontendESMUtil; import com.liferay.portal.kernel.servlet.PortalWebResourceConstants; import com.liferay.portal.kernel.servlet.PortalWebResourcesUtil; import com.liferay.portal.kernel.servlet.taglib.BaseDynamicInclude; @@ -82,9 +81,8 @@ public void include( printWriter.write(Boolean.toString(_details.exposeGlobal())); printWriter.write(", logLevel: '"); printWriter.write(_details.logLevel()); - printWriter.write("', moduleType: '"); - printWriter.write(FrontendESMUtil.getScriptType()); - printWriter.write("', namespace:'Liferay', nonce: '"); + printWriter.write("', moduleType: 'module', namespace:'Liferay', "); + printWriter.write("nonce: '"); printWriter.write( _contentSecurityPolicyNonceProvider.getNonce(httpServletRequest)); printWriter.write( @@ -105,8 +103,8 @@ public void include( httpServletRequest); printWriter.write( - absolutePortalURLBuilder.forBundleScript( - _bundle, "/loader.js" + absolutePortalURLBuilder.forWebContextScript( + "frontend-js-loader-modules-extender", "/loader.js" ).build()); printWriter.write("\" type=\""); diff --git a/modules/apps/frontend-js/frontend-js-lodash-web/src/main/java/com/liferay/frontend/js/lodash/web/internal/servlet/taglib/LodashTopHeadDynamicInclude.java b/modules/apps/frontend-js/frontend-js-lodash-web/src/main/java/com/liferay/frontend/js/lodash/web/internal/servlet/taglib/LodashTopHeadDynamicInclude.java index d81ac879d14ac5..3bf0be4a073ac3 100644 --- a/modules/apps/frontend-js/frontend-js-lodash-web/src/main/java/com/liferay/frontend/js/lodash/web/internal/servlet/taglib/LodashTopHeadDynamicInclude.java +++ b/modules/apps/frontend-js/frontend-js-lodash-web/src/main/java/com/liferay/frontend/js/lodash/web/internal/servlet/taglib/LodashTopHeadDynamicInclude.java @@ -61,8 +61,8 @@ public void include( printWriter.print(" data-senna-track=\"permanent\" src=\""); printWriter.print( - absolutePortalURLBuilder.forBundleScript( - _bundleContext.getBundle(), fileName + absolutePortalURLBuilder.forWebContextScript( + "frontend-js-lodash-web", fileName ).build()); printWriter.println("\" type=\"text/javascript\">"); diff --git a/modules/apps/frontend-js/frontend-js-svg4everybody-web/node-scripts.config.js b/modules/apps/frontend-js/frontend-js-svg4everybody-web/node-scripts.config.js index 4c334868a2b5f1..0234e6c9a48914 100644 --- a/modules/apps/frontend-js/frontend-js-svg4everybody-web/node-scripts.config.js +++ b/modules/apps/frontend-js/frontend-js-svg4everybody-web/node-scripts.config.js @@ -9,7 +9,7 @@ module.exports = { customBuild: { esbuild: { bundle: true, - entryNames: 'index', + entryNames: 'index.([hash])', entryPoints: [ path.resolve( 'src', diff --git a/modules/apps/frontend-js/frontend-js-svg4everybody-web/src/main/java/com/liferay/frontend/js/svg4everybody/web/internal/servlet/taglib/SVG4EverybodyTopHeadDynamicInclude.java b/modules/apps/frontend-js/frontend-js-svg4everybody-web/src/main/java/com/liferay/frontend/js/svg4everybody/web/internal/servlet/taglib/SVG4EverybodyTopHeadDynamicInclude.java index 1e5de0f4e3d18f..a49eebcee67904 100644 --- a/modules/apps/frontend-js/frontend-js-svg4everybody-web/src/main/java/com/liferay/frontend/js/svg4everybody/web/internal/servlet/taglib/SVG4EverybodyTopHeadDynamicInclude.java +++ b/modules/apps/frontend-js/frontend-js-svg4everybody-web/src/main/java/com/liferay/frontend/js/svg4everybody/web/internal/servlet/taglib/SVG4EverybodyTopHeadDynamicInclude.java @@ -24,7 +24,7 @@ import com.liferay.portal.kernel.util.WebKeys; import com.liferay.portal.url.builder.AbsolutePortalURLBuilder; import com.liferay.portal.url.builder.AbsolutePortalURLBuilderFactory; -import com.liferay.portal.url.builder.BundleScriptAbsolutePortalURLBuilder; +import com.liferay.portal.url.builder.WebContextScriptAbsolutePortalURLBuilder; import jakarta.servlet.http.HttpServletRequest; import jakarta.servlet.http.HttpServletResponse; @@ -109,16 +109,16 @@ public void include( httpServletRequest)); printWriter.print(" data-senna-track=\"permanent\" src=\""); - BundleScriptAbsolutePortalURLBuilder - bundleScriptAbsolutePortalURLBuilder = - absolutePortalURLBuilder.forBundleScript( - _bundleContext.getBundle(), jsFileName); + WebContextScriptAbsolutePortalURLBuilder + webContextScriptAbsolutePortalURLBuilder = + absolutePortalURLBuilder.forWebContextScript( + "frontend-js-svg4everybody-web", jsFileName); if (!cdnDynamicResourcesEnabled) { - bundleScriptAbsolutePortalURLBuilder.ignoreCDNHost(); + webContextScriptAbsolutePortalURLBuilder.ignoreCDNHost(); } - printWriter.print(bundleScriptAbsolutePortalURLBuilder.build()); + printWriter.print(webContextScriptAbsolutePortalURLBuilder.build()); printWriter.println("\" type=\"text/javascript\">"); } diff --git a/modules/apps/frontend-js/frontend-js-web/build.gradle b/modules/apps/frontend-js/frontend-js-web/build.gradle index ff1d8e83304576..4fac57ab3ee700 100644 --- a/modules/apps/frontend-js/frontend-js-web/build.gradle +++ b/modules/apps/frontend-js/frontend-js-web/build.gradle @@ -9,7 +9,6 @@ dependencies { compileOnly group: "org.osgi", name: "org.osgi.service.cm", version: "1.6.0" compileOnly group: "org.osgi", name: "org.osgi.service.component.annotations", version: "1.4.0" compileOnly group: "org.osgi", name: "osgi.core", version: "6.0.0" - compileOnly project(":apps:configuration-admin:configuration-admin-api") compileOnly project(":apps:frontend-js:frontend-js-importmaps-extender-api") compileOnly project(":apps:frontend-js:frontend-js-loader-modules-extender-api") compileOnly project(":apps:portal-configuration:portal-configuration-module-configuration-api") diff --git a/modules/apps/frontend-js/frontend-js-web/node-scripts.config.js b/modules/apps/frontend-js/frontend-js-web/node-scripts.config.js index d4494145dbb21f..7f3e024b453cbf 100644 --- a/modules/apps/frontend-js/frontend-js-web/node-scripts.config.js +++ b/modules/apps/frontend-js/frontend-js-web/node-scripts.config.js @@ -9,7 +9,7 @@ module.exports = { customBuild: { esbuild: { bundle: true, - entryNames: 'Liferay', + entryNames: 'Liferay.([hash])', entryPoints: [ path.resolve( 'src', diff --git a/modules/apps/frontend-js/frontend-js-web/src/main/java/com/liferay/frontend/js/web/internal/configuration/FrontendCachingConfiguration.java b/modules/apps/frontend-js/frontend-js-web/src/main/java/com/liferay/frontend/js/web/internal/configuration/FrontendCachingConfiguration.java index 578abd6943093e..78973d971b490e 100644 --- a/modules/apps/frontend-js/frontend-js-web/src/main/java/com/liferay/frontend/js/web/internal/configuration/FrontendCachingConfiguration.java +++ b/modules/apps/frontend-js/frontend-js-web/src/main/java/com/liferay/frontend/js/web/internal/configuration/FrontendCachingConfiguration.java @@ -7,7 +7,6 @@ import aQute.bnd.annotation.metatype.Meta; -import com.liferay.portal.configuration.metatype.annotations.ExtendedAttributeDefinition; import com.liferay.portal.configuration.metatype.annotations.ExtendedObjectClassDefinition; /** @@ -30,9 +29,6 @@ public interface FrontendCachingConfiguration { ) public long cssStyleSheetsMaxAge(); - @ExtendedAttributeDefinition( - visibilityControllerKey = "com.liferay.frontend.js.web.internal.configuration.admin.display.FrontendCachingConfigurationVisibilityController" - ) @Meta.AD( deflt = "86400", description = "es-modules-max-age-help", name = "es-modules-max-age", required = false @@ -46,9 +42,6 @@ public interface FrontendCachingConfiguration { ) public boolean sendNoCacheForCSSStyleSheets(); - @ExtendedAttributeDefinition( - visibilityControllerKey = "com.liferay.frontend.js.web.internal.configuration.admin.display.FrontendCachingConfigurationVisibilityController" - ) @Meta.AD( deflt = "false", description = "send-no-cache-for-es-modules-help", name = "send-no-cache-for-es-modules", required = false diff --git a/modules/apps/frontend-js/frontend-js-web/src/main/java/com/liferay/frontend/js/web/internal/configuration/admin/display/FrontendCachingConfigurationVisibilityController.java b/modules/apps/frontend-js/frontend-js-web/src/main/java/com/liferay/frontend/js/web/internal/configuration/admin/display/FrontendCachingConfigurationVisibilityController.java deleted file mode 100644 index e6a6c08e58d38b..00000000000000 --- a/modules/apps/frontend-js/frontend-js-web/src/main/java/com/liferay/frontend/js/web/internal/configuration/admin/display/FrontendCachingConfigurationVisibilityController.java +++ /dev/null @@ -1,31 +0,0 @@ -/** - * SPDX-FileCopyrightText: (c) 2025 Liferay, Inc. https://liferay.com - * SPDX-License-Identifier: LGPL-2.1-or-later OR LicenseRef-Liferay-DXP-EULA-2.0.0-2023-06 - */ - -package com.liferay.frontend.js.web.internal.configuration.admin.display; - -import com.liferay.configuration.admin.display.ConfigurationVisibilityController; -import com.liferay.portal.configuration.metatype.annotations.ExtendedObjectClassDefinition; - -import java.io.Serializable; - -import org.osgi.service.component.annotations.Component; - -/** - * @author Iván Zaera Avellón - */ -@Component(service = ConfigurationVisibilityController.class) -public class FrontendCachingConfigurationVisibilityController - implements ConfigurationVisibilityController { - - @Override - public boolean isVisible( - ExtendedObjectClassDefinition.Scope scope, Serializable scopePK) { - - // LPD-69957 - - return false; - } - -} \ No newline at end of file diff --git a/modules/apps/frontend-js/frontend-js-web/src/main/java/com/liferay/frontend/js/web/internal/resource/handler/HashedFileFrontendResourceRequestHandler.java b/modules/apps/frontend-js/frontend-js-web/src/main/java/com/liferay/frontend/js/web/internal/resource/handler/HashedFileFrontendResourceRequestHandler.java index a5f2475ccd8c3c..fd4c8147a3156c 100644 --- a/modules/apps/frontend-js/frontend-js-web/src/main/java/com/liferay/frontend/js/web/internal/resource/handler/HashedFileFrontendResourceRequestHandler.java +++ b/modules/apps/frontend-js/frontend-js-web/src/main/java/com/liferay/frontend/js/web/internal/resource/handler/HashedFileFrontendResourceRequestHandler.java @@ -7,6 +7,8 @@ import com.liferay.frontend.js.web.internal.resource.FrontendResource; import com.liferay.frontend.js.web.internal.resource.HashedFileFrontendResource; +import com.liferay.petra.string.StringBundler; +import com.liferay.petra.string.StringPool; import com.liferay.portal.kernel.frontend.hashed.files.HashedFilesRegistry; import com.liferay.portal.kernel.frontend.hashed.files.HashedFilesUtil; import com.liferay.portal.kernel.log.Log; @@ -56,12 +58,6 @@ public boolean canHandleRequest(HttpServletRequest httpServletRequest) { return true; } - // LPD-52709 - - if (true) { - return false; - } - String hashedFileURI = _hashedFilesRegistry.getHashedFileURI( requestURI); @@ -87,6 +83,10 @@ public FrontendResource handleRequest(HttpServletRequest httpServletRequest) String requestHash = HashedFilesUtil.getHash(requestURI); if (requestHash != null) { + if (_log.isDebugEnabled()) { + _log.debug("Handling request " + requestURI); + } + return _createFrontendResource( _portal.getCompanyId(httpServletRequest), requestHash, true, requestURI); @@ -96,11 +96,22 @@ public FrontendResource handleRequest(HttpServletRequest httpServletRequest) requestURI); if (hashedFileURI == null) { + if (_log.isDebugEnabled()) { + _log.debug("Handling request " + requestURI); + } + return _createFrontendResource( _portal.getCompanyId(httpServletRequest), null, false, requestURI); } + if (_log.isDebugEnabled()) { + _log.debug( + StringBundler.concat( + "Handling request ", requestURI, " [static file: ", + hashedFileURI, StringPool.CLOSE_BRACKET)); + } + return _createFrontendResource( _portal.getCompanyId(httpServletRequest), HashedFilesUtil.getHash(hashedFileURI), false, hashedFileURI); diff --git a/modules/apps/frontend-js/frontend-js-web/src/main/java/com/liferay/frontend/js/web/internal/resource/handler/StyleSheetFrontendResourceRequestHandler.java b/modules/apps/frontend-js/frontend-js-web/src/main/java/com/liferay/frontend/js/web/internal/resource/handler/StyleSheetFrontendResourceRequestHandler.java index e860c9424b1094..078dc37554f0e9 100644 --- a/modules/apps/frontend-js/frontend-js-web/src/main/java/com/liferay/frontend/js/web/internal/resource/handler/StyleSheetFrontendResourceRequestHandler.java +++ b/modules/apps/frontend-js/frontend-js-web/src/main/java/com/liferay/frontend/js/web/internal/resource/handler/StyleSheetFrontendResourceRequestHandler.java @@ -8,10 +8,13 @@ import com.liferay.frontend.js.web.internal.configuration.FrontendCachingConfiguration; import com.liferay.frontend.js.web.internal.resource.FrontendResource; import com.liferay.frontend.js.web.internal.resource.StyleSheetFrontendResource; +import com.liferay.petra.string.StringBundler; import com.liferay.petra.string.StringPool; import com.liferay.portal.kernel.exception.PortalException; import com.liferay.portal.kernel.frontend.hashed.files.HashedFilesRegistry; import com.liferay.portal.kernel.frontend.hashed.files.HashedFilesUtil; +import com.liferay.portal.kernel.log.Log; +import com.liferay.portal.kernel.log.LogFactoryUtil; import com.liferay.portal.kernel.model.Theme; import com.liferay.portal.kernel.service.ThemeLocalService; import com.liferay.portal.kernel.util.Portal; @@ -83,6 +86,10 @@ public FrontendResource handleRequest(HttpServletRequest httpServletRequest) SortedMap tokens = _getTokens(httpServletRequest); if (requestHash != null) { + if (_log.isDebugEnabled()) { + _log.debug("Handling request: " + requestURI); + } + return _createFrontendResource( requestHash, tokens == null, requestURI, tokens); } @@ -91,9 +98,20 @@ public FrontendResource handleRequest(HttpServletRequest httpServletRequest) requestURI); if (hashedFileURI == null) { + if (_log.isDebugEnabled()) { + _log.debug("Handling request: " + requestURI); + } + return _createFrontendResource(null, false, requestURI, tokens); } + if (_log.isDebugEnabled()) { + _log.debug( + StringBundler.concat( + "Handling request ", requestURI, " [static file: ", + hashedFileURI, StringPool.CLOSE_BRACKET)); + } + return _createFrontendResource( HashedFilesUtil.getHash(hashedFileURI), false, hashedFileURI, tokens); @@ -166,6 +184,9 @@ private SortedMap _getTokens( return tokens; } + private static final Log _log = LogFactoryUtil.getLog( + StyleSheetFrontendResourceRequestHandler.class); + private final FrontendCachingConfiguration _frontendCachingConfiguration; private final HashedFilesRegistry _hashedFilesRegistry; private final Portal _portal; diff --git a/modules/apps/frontend-js/frontend-js-web/src/main/java/com/liferay/frontend/js/web/internal/servlet/taglib/LiferayGlobalObjectPostAUIDynamicInclude.java b/modules/apps/frontend-js/frontend-js-web/src/main/java/com/liferay/frontend/js/web/internal/servlet/taglib/LiferayGlobalObjectPostAUIDynamicInclude.java index c78f9dbd5df51a..b0ba5cca3811a9 100644 --- a/modules/apps/frontend-js/frontend-js-web/src/main/java/com/liferay/frontend/js/web/internal/servlet/taglib/LiferayGlobalObjectPostAUIDynamicInclude.java +++ b/modules/apps/frontend-js/frontend-js-web/src/main/java/com/liferay/frontend/js/web/internal/servlet/taglib/LiferayGlobalObjectPostAUIDynamicInclude.java @@ -5,6 +5,7 @@ package com.liferay.frontend.js.web.internal.servlet.taglib; +import com.liferay.petra.string.StringPool; import com.liferay.portal.kernel.content.security.policy.ContentSecurityPolicyNonceProviderUtil; import com.liferay.portal.kernel.log.Log; import com.liferay.portal.kernel.log.LogFactoryUtil; @@ -14,7 +15,7 @@ import com.liferay.portal.kernel.util.Validator; import com.liferay.portal.url.builder.AbsolutePortalURLBuilder; import com.liferay.portal.url.builder.AbsolutePortalURLBuilderFactory; -import com.liferay.portal.url.builder.BundleScriptAbsolutePortalURLBuilder; +import com.liferay.portal.url.builder.WebContextScriptAbsolutePortalURLBuilder; import jakarta.servlet.http.HttpServletRequest; import jakarta.servlet.http.HttpServletResponse; @@ -57,15 +58,22 @@ public void include( _absolutePortalURLBuilderFactory.getAbsolutePortalURLBuilder( httpServletRequest); - BundleScriptAbsolutePortalURLBuilder - bundleScriptAbsolutePortalURLBuilder = - absolutePortalURLBuilder.forBundleScript( - _bundle, "/Liferay.js"); + WebContextScriptAbsolutePortalURLBuilder + webContextScriptAbsolutePortalURLBuilder = + absolutePortalURLBuilder.forWebContextScript( + "frontend-js-web", "/Liferay.js"); _renderScript( - httpServletRequest, httpServletResponse.getWriter(), - bundleScriptAbsolutePortalURLBuilder.build(), + null, httpServletRequest, httpServletResponse.getWriter(), + webContextScriptAbsolutePortalURLBuilder.build(), "text/javascript"); + + _renderScript( + "await import(`@liferay/language" + + "/${Liferay.ThemeDisplay.getLanguageId()}/frontend-js-web" + + "/all.js`);", + httpServletRequest, httpServletResponse.getWriter(), null, + "module"); } catch (Exception exception) { _log.error(exception); @@ -90,8 +98,8 @@ protected void deactivate() { } private void _renderScript( - HttpServletRequest httpServletRequest, PrintWriter printWriter, - String src, String type) { + String content, HttpServletRequest httpServletRequest, + PrintWriter printWriter, String src, String type) { printWriter.print(""); + printWriter.print("\">"); + + if (Validator.isNotNull(content)) { + printWriter.print(content); + } + + printWriter.println(""); } private static final Log _log = LogFactoryUtil.getLog( diff --git a/modules/apps/frontend-js/frontend-js-web/src/main/java/com/liferay/frontend/js/web/internal/servlet/taglib/aui/PortletDataRendererImpl.java b/modules/apps/frontend-js/frontend-js-web/src/main/java/com/liferay/frontend/js/web/internal/servlet/taglib/aui/PortletDataRendererImpl.java index e791d74da708a6..0a3ad2dc31b380 100644 --- a/modules/apps/frontend-js/frontend-js-web/src/main/java/com/liferay/frontend/js/web/internal/servlet/taglib/aui/PortletDataRendererImpl.java +++ b/modules/apps/frontend-js/frontend-js-web/src/main/java/com/liferay/frontend/js/web/internal/servlet/taglib/aui/PortletDataRendererImpl.java @@ -8,7 +8,6 @@ import com.liferay.petra.string.StringBundler; import com.liferay.petra.string.StringPool; import com.liferay.portal.kernel.content.security.policy.ContentSecurityPolicyNonceProviderUtil; -import com.liferay.portal.kernel.frontend.esm.FrontendESMUtil; import com.liferay.portal.kernel.servlet.taglib.aui.AMDRequire; import com.liferay.portal.kernel.servlet.taglib.aui.ESImport; import com.liferay.portal.kernel.servlet.taglib.aui.JSFragment; @@ -66,9 +65,7 @@ public void write(Collection portletDatas, Writer writer) writer.write("\n"); + writer.write(" type=\"module\">\n"); } // Write ES prologue diff --git a/modules/apps/frontend-js/frontend-js-web/src/main/resources/META-INF/resources/language.json b/modules/apps/frontend-js/frontend-js-web/src/main/resources/META-INF/resources/language.json new file mode 100644 index 00000000000000..629655881227f9 --- /dev/null +++ b/modules/apps/frontend-js/frontend-js-web/src/main/resources/META-INF/resources/language.json @@ -0,0 +1,19 @@ +{ + "keys": [ + "are-you-sure-you-want-to-remove-this-component", + "danger", + "due-to-inactivity-your-session-has-expired", + "due-to-inactivity-your-session-will-expire", + "no-reviewers-were-found", + "extend", + "minimize", + "page-x", + "please-contact-the-administrator-to-assign-reviewers", + "proceed", + "restore", + "reviewer", + "session-expires-in-x", + "there-was-an-unexpected-error.-please-refresh-the-current-page", + "this-change-will-only-be-shown-after-you-refresh-the-page" + ] +} \ No newline at end of file diff --git a/modules/apps/frontend-js/frontend-js-web/src/test/java/com/liferay/frontend/js/web/internal/resource/handler/HashedFileFrontendResourceRequestHandlerTest.java b/modules/apps/frontend-js/frontend-js-web/src/test/java/com/liferay/frontend/js/web/internal/resource/handler/HashedFileFrontendResourceRequestHandlerTest.java index ab5e4cf95f47dc..d8120282b6474b 100644 --- a/modules/apps/frontend-js/frontend-js-web/src/test/java/com/liferay/frontend/js/web/internal/resource/handler/HashedFileFrontendResourceRequestHandlerTest.java +++ b/modules/apps/frontend-js/frontend-js-web/src/test/java/com/liferay/frontend/js/web/internal/resource/handler/HashedFileFrontendResourceRequestHandlerTest.java @@ -32,7 +32,6 @@ import org.junit.After; import org.junit.Assert; import org.junit.Before; -import org.junit.Ignore; import org.junit.Test; import org.mockito.MockedStatic; @@ -63,12 +62,8 @@ public void tearDown() { } } - @Ignore @Test public void testCanHandleRequest() throws Exception { - - // LPD-52709 - _mockFallbackKeysSettingsUtil( HashMapBuilder.put( "maxAgeKey", RandomTestUtil.randomLong() @@ -132,12 +127,8 @@ public void testHandleRequestWithHash() throws Exception { Assert.assertFalse(frontendResource.isSendNoCache()); } - @Ignore @Test public void testHandleRequestWithNoConfiguration() throws Exception { - - // LPD-52709 - _mockFallbackKeysSettingsUtil(null); long maxAge = RandomTestUtil.randomLong(); diff --git a/modules/apps/portal-url-builder/portal-url-builder-impl/src/main/java/com/liferay/portal/url/builder/internal/AbsolutePortalURLBuilderImpl.java b/modules/apps/portal-url-builder/portal-url-builder-impl/src/main/java/com/liferay/portal/url/builder/internal/AbsolutePortalURLBuilderImpl.java index 9965933d1d0327..966795f2e9418e 100644 --- a/modules/apps/portal-url-builder/portal-url-builder-impl/src/main/java/com/liferay/portal/url/builder/internal/AbsolutePortalURLBuilderImpl.java +++ b/modules/apps/portal-url-builder/portal-url-builder-impl/src/main/java/com/liferay/portal/url/builder/internal/AbsolutePortalURLBuilderImpl.java @@ -96,8 +96,8 @@ public ESModuleAbsolutePortalURLBuilder forESModule( String webContextPath, String esModulePath) { return new ESModuleAbsolutePortalURLBuilderImpl( - esModulePath, _getCDNHost(_httpServletRequest), _pathModule, - _pathProxy, webContextPath); + _getCDNHost(_httpServletRequest), esModulePath, + _hashedFilesRegistry, _pathModule, _pathProxy, webContextPath); } @Override diff --git a/modules/apps/portal-url-builder/portal-url-builder-impl/src/main/java/com/liferay/portal/url/builder/internal/ESModuleAbsolutePortalURLBuilderImpl.java b/modules/apps/portal-url-builder/portal-url-builder-impl/src/main/java/com/liferay/portal/url/builder/internal/ESModuleAbsolutePortalURLBuilderImpl.java index 87566dd69ea98c..b3d14142d80212 100644 --- a/modules/apps/portal-url-builder/portal-url-builder-impl/src/main/java/com/liferay/portal/url/builder/internal/ESModuleAbsolutePortalURLBuilderImpl.java +++ b/modules/apps/portal-url-builder/portal-url-builder-impl/src/main/java/com/liferay/portal/url/builder/internal/ESModuleAbsolutePortalURLBuilderImpl.java @@ -5,68 +5,25 @@ package com.liferay.portal.url.builder.internal; -import com.liferay.petra.string.StringBundler; -import com.liferay.petra.string.StringPool; +import com.liferay.portal.kernel.frontend.hashed.files.HashedFilesRegistry; import com.liferay.portal.url.builder.ESModuleAbsolutePortalURLBuilder; -import com.liferay.portal.url.builder.internal.util.URLUtil; /** * @author Iván Zaera Avellón */ public class ESModuleAbsolutePortalURLBuilderImpl + extends BaseWebContextResourceAbsolutePortalURLBuilderImpl + implements ESModuleAbsolutePortalURLBuilder { public ESModuleAbsolutePortalURLBuilderImpl( - String esModulePath, String cdnHost, String pathModule, + String cdnHost, String esModulePath, + HashedFilesRegistry hashedFilesRegistry, String pathModule, String pathProxy, String webContextPath) { - if (!esModulePath.startsWith(StringPool.SLASH)) { - esModulePath = StringPool.SLASH + esModulePath; - } - - if (!webContextPath.startsWith(StringPool.SLASH)) { - webContextPath = StringPool.SLASH + webContextPath; - } - - _esModulePath = esModulePath; - _cdnHost = cdnHost; - _pathModule = pathModule; - _pathProxy = pathProxy; - _webContextPath = webContextPath; + super( + cdnHost, hashedFilesRegistry, pathModule, pathProxy, + "/__liferay__/" + esModulePath, webContextPath); } - @Override - public String build() { - StringBundler sb = new StringBundler(); - - URLUtil.appendURL( - sb, _cdnHost, _ignoreCDNHost, _ignorePathProxy, - _pathModule + _webContextPath + "/__liferay__", _pathProxy, - _esModulePath); - - return sb.toString(); - } - - @Override - public ESModuleAbsolutePortalURLBuilder ignoreCDNHost() { - _ignoreCDNHost = true; - - return this; - } - - @Override - public ESModuleAbsolutePortalURLBuilder ignorePathProxy() { - _ignorePathProxy = true; - - return this; - } - - private final String _cdnHost; - private final String _esModulePath; - private boolean _ignoreCDNHost; - private boolean _ignorePathProxy; - private final String _pathModule; - private final String _pathProxy; - private final String _webContextPath; - } \ No newline at end of file diff --git a/modules/test/playwright/tests/frontend-js-web/main/liferayGlobalObject.spec.ts b/modules/test/playwright/tests/frontend-js-web/main/liferayGlobalObject.spec.ts index c004450aab1e68..cb0d1a72829c5f 100644 --- a/modules/test/playwright/tests/frontend-js-web/main/liferayGlobalObject.spec.ts +++ b/modules/test/playwright/tests/frontend-js-web/main/liferayGlobalObject.spec.ts @@ -37,7 +37,7 @@ test( const crossoriginAttr = await page .locator( - 'script[src^="http://127.0.0.1/o/frontend-js-web/Liferay.js"]' + 'script[src^="http://127.0.0.1/o/frontend-js-web/Liferay.("]' ) .getAttribute('crossorigin', {timeout: 1000}); @@ -52,7 +52,7 @@ test( await page.getByRole('button', {name: 'Save'}).click(); await expect( - page.locator('script[src^="/o/frontend-js-web/Liferay.js"]') + page.locator('script[src^="/o/frontend-js-web/Liferay.("]') ).not.toHaveAttribute('crossorigin', ''); }); } diff --git a/portal-impl/src/portal-osgi-configuration.properties b/portal-impl/src/portal-osgi-configuration.properties index 879e766f6e7fa2..dd9c03cd0f5d02 100644 --- a/portal-impl/src/portal-osgi-configuration.properties +++ b/portal-impl/src/portal-osgi-configuration.properties @@ -2891,14 +2891,6 @@ # #configuration.override.com.liferay.frontend.js.aui.web.internal.configuration.AUIConfiguration_enableAUIPreload= # - # Env: LIFERAY_CONFIGURATION_PERIOD_OVERRIDE_PERIOD_COM_PERIOD_LIFERAY_PERIOD_FRONTEND_PERIOD_JS_PERIOD_IMPORTMAPS_PERIOD_EXTENDER_PERIOD_INTERNAL_PERIOD_CONFIGURATION_PERIOD__UPPERCASEJ__UPPERCASES__UPPERCASEI_MPORT_UPPERCASEM_APS_UPPERCASEC_ONFIGURATION_UNDERLINE_ENABLE_UPPERCASEE__UPPERCASES__UPPERCASEM_ODULE_UPPERCASES_HIMS - # - #configuration.override.com.liferay.frontend.js.importmaps.extender.internal.configuration.JSImportMapsConfiguration_enableESModuleShims= - # - # Env: LIFERAY_CONFIGURATION_PERIOD_OVERRIDE_PERIOD_COM_PERIOD_LIFERAY_PERIOD_FRONTEND_PERIOD_JS_PERIOD_IMPORTMAPS_PERIOD_EXTENDER_PERIOD_INTERNAL_PERIOD_CONFIGURATION_PERIOD__UPPERCASEJ__UPPERCASES__UPPERCASEI_MPORT_UPPERCASEM_APS_UPPERCASEC_ONFIGURATION_UNDERLINE_ENABLE_UPPERCASEI_MPORT_UPPERCASEM_APS - # - #configuration.override.com.liferay.frontend.js.importmaps.extender.internal.configuration.JSImportMapsConfiguration_enableImportMaps= - # # Env: LIFERAY_CONFIGURATION_PERIOD_OVERRIDE_PERIOD_COM_PERIOD_LIFERAY_PERIOD_FRONTEND_PERIOD_JS_PERIOD_LODASH_PERIOD_WEB_PERIOD_INTERNAL_PERIOD_CONFIGURATION_PERIOD__UPPERCASEJ__UPPERCASES__UPPERCASEL_ODASH_UPPERCASEC_ONFIGURATION_UNDERLINE_ENABLE_UPPERCASEL_ODASH # #configuration.override.com.liferay.frontend.js.lodash.web.internal.configuration.JSLodashConfiguration_enableLodash= diff --git a/portal-kernel/src/com/liferay/portal/kernel/frontend/esm/FrontendESMUtil.java b/portal-kernel/src/com/liferay/portal/kernel/frontend/esm/FrontendESMUtil.java index d0c2c6f071525e..788e0cef0a1bdd 100644 --- a/portal-kernel/src/com/liferay/portal/kernel/frontend/esm/FrontendESMUtil.java +++ b/portal-kernel/src/com/liferay/portal/kernel/frontend/esm/FrontendESMUtil.java @@ -8,8 +8,6 @@ import com.liferay.petra.string.StringBundler; import com.liferay.portal.kernel.theme.ThemeDisplay; -import java.util.concurrent.atomic.AtomicReference; - /** * @author Iván Zaera Avellón */ @@ -39,15 +37,4 @@ public static String buildURL( submodule, ".js"); } - public static String getScriptType() { - return _scriptType.get(); - } - - public static void setScriptType(String scriptType) { - _scriptType.set(scriptType); - } - - private static final AtomicReference _scriptType = - new AtomicReference<>("module"); - } \ No newline at end of file diff --git a/portal-kernel/src/com/liferay/portal/kernel/frontend/esm/packageinfo b/portal-kernel/src/com/liferay/portal/kernel/frontend/esm/packageinfo index b1793a21a72389..682b435622a0aa 100644 --- a/portal-kernel/src/com/liferay/portal/kernel/frontend/esm/packageinfo +++ b/portal-kernel/src/com/liferay/portal/kernel/frontend/esm/packageinfo @@ -1 +1 @@ -version 1.1.0 \ No newline at end of file +version 2.0.0 \ No newline at end of file diff --git a/portal-kernel/src/com/liferay/portal/kernel/portlet/render/PortletRenderUtil.java b/portal-kernel/src/com/liferay/portal/kernel/portlet/render/PortletRenderUtil.java index 3293afa3436308..0c63a04c8e3b92 100644 --- a/portal-kernel/src/com/liferay/portal/kernel/portlet/render/PortletRenderUtil.java +++ b/portal-kernel/src/com/liferay/portal/kernel/portlet/render/PortletRenderUtil.java @@ -6,17 +6,14 @@ package com.liferay.portal.kernel.portlet.render; import com.liferay.petra.io.StreamUtil; -import com.liferay.petra.string.StringBundler; import com.liferay.petra.string.StringPool; import com.liferay.portal.kernel.content.security.policy.ContentSecurityPolicyNonceProviderUtil; -import com.liferay.portal.kernel.frontend.esm.FrontendESMUtil; import com.liferay.portal.kernel.frontend.hashed.files.HashedFilesRegistryUtil; import com.liferay.portal.kernel.frontend.hashed.files.HashedFilesUtil; import com.liferay.portal.kernel.log.Log; import com.liferay.portal.kernel.log.LogFactoryUtil; import com.liferay.portal.kernel.model.LayoutTypePortlet; import com.liferay.portal.kernel.model.Portlet; -import com.liferay.portal.kernel.model.Theme; import com.liferay.portal.kernel.theme.ThemeDisplay; import com.liferay.portal.kernel.util.HashMapBuilder; import com.liferay.portal.kernel.util.HtmlUtil; @@ -47,7 +44,6 @@ import java.util.Map; import java.util.Set; import java.util.concurrent.ConcurrentHashMap; -import java.util.function.Predicate; /** * @author Iván Zaera Avellón @@ -197,110 +193,6 @@ private static List _getAllPortlets( return allPortlets; } - private static List _getComboServletURLs( - Collection portletResourceAccessors, - Collection portlets, Predicate predicate, - long timestamp, String urlPrefix, Set visitedURLs) { - - if (predicate == null) { - predicate = s -> true; - } - - List urls = new ArrayList<>(); - - StringBundler comboServletSB = new StringBundler(); - - for (Portlet portlet : portlets) { - for (PortletResourceAccessor portletResourceAccessor : - portletResourceAccessors) { - - String contextPath = null; - - if (portletResourceAccessor.isPortalResource()) { - contextPath = PortalUtil.getPathContext(); - } - else { - contextPath = - PortalUtil.getPathProxy() + portlet.getContextPath(); - } - - Collection portletResources = - portletResourceAccessor.get(portlet); - - for (String portletResource : portletResources) { - if (!predicate.test(portletResource)) { - continue; - } - - String prefix = null; - - for (String specialPrefix : _specialPrefixes) { - if (portletResource.startsWith(specialPrefix)) { - portletResource = portletResource.substring( - specialPrefix.length()); - - prefix = specialPrefix; - - break; - } - } - - boolean absolute = HttpComponentsUtil.hasProtocol( - portletResource); - - if (!absolute) { - portletResource = contextPath + portletResource; - } - - if (Validator.isNotNull(prefix)) { - portletResource = prefix + portletResource; - } - - if (visitedURLs.contains(portletResource)) { - continue; - } - - visitedURLs.add(portletResource); - - if (absolute || Validator.isNotNull(prefix)) { - urls.add(portletResource); - } - else { - comboServletSB.append(StringPool.AMPERSAND); - - if (!portletResourceAccessor.isPortalResource()) { - comboServletSB.append(portlet.getPortletId()); - comboServletSB.append(StringPool.COLON); - } - - comboServletSB.append( - HtmlUtil.escapeURL(portletResource)); - - timestamp = Math.max(timestamp, portlet.getTimestamp()); - } - } - } - } - - if (comboServletSB.length() > 0) { - String url = urlPrefix + comboServletSB; - - url = HttpComponentsUtil.addParameter(url, "t", timestamp); - - urls.add(url); - } - - return urls; - } - - private static String _getMinifierType(URLType urlType) { - if (urlType == URLType.CSS) { - return "css"; - } - - return "js"; - } - private static PortletRenderParts _getPortletRenderParts( HttpServletRequest httpServletRequest, String portletHTML, Portlet portlet, boolean portletOnLayout) { @@ -435,12 +327,15 @@ private static List _getStaticURLs( contextPath + portletResource, themeDisplay); } else if (urlType == URLType.JAVASCRIPT) { - Portlet rootPortlet = portlet.getRootPortlet(); + portletResource = contextPath + portletResource; - portletResource = PortalUtil.getStaticResourceURL( - httpServletRequest, - contextPath + portletResource, - rootPortlet.getTimestamp()); + String hashedFileURI = + HashedFilesRegistryUtil.getHashedFileURI( + portletResource); + + if (hashedFileURI != null) { + portletResource = hashedFileURI; + } } else { throw new UnsupportedOperationException( @@ -489,43 +384,11 @@ private static Collection _getURLs( List urls; - if (urlType == URLType.CSS) { + if ((urlType == URLType.CSS) || (urlType == URLType.JAVASCRIPT)) { urls = _getStaticURLs( httpServletRequest, portletResourceAccessors, portlets, urlType, visitedURLs); } - else if (urlType == URLType.JAVASCRIPT) { - ThemeDisplay themeDisplay = - (ThemeDisplay)httpServletRequest.getAttribute( - WebKeys.THEME_DISPLAY); - - boolean fastLoad = themeDisplay.isThemeJsFastLoad(); - - if (fastLoad) { - Predicate predicate = - resource -> !themeDisplay.isIncludedJs(resource); - - Theme theme = themeDisplay.getTheme(); - - urls = _getComboServletURLs( - portletResourceAccessors, portlets, predicate, - theme.getTimestamp(), - PortalUtil.getStaticResourceURL( - httpServletRequest, - themeDisplay.getCDNDynamicResourcesHost() + - themeDisplay.getPathContext() + "/combo", - StringBundler.concat( - "minifierType=", _getMinifierType(urlType), - "&themeId=", themeDisplay.getThemeId()), - -1), - visitedURLs); - } - else { - urls = _getStaticURLs( - httpServletRequest, portletResourceAccessors, portlets, - urlType, visitedURLs); - } - } else { throw new UnsupportedOperationException( "Unsupported URL type " + urlType); @@ -606,7 +469,7 @@ private static void _writeJavaScriptPath( if (javaScriptPath.startsWith("module:")) { javaScriptPath = javaScriptPath.substring(7); - type = FrontendESMUtil.getScriptType(); + type = "module"; } printWriter.print("false true + + hashedFile + false + true + id false diff --git a/util-taglib/src/com/liferay/taglib/aui/LinkTag.java b/util-taglib/src/com/liferay/taglib/aui/LinkTag.java index e46dd973500a9e..0444536e7d879f 100644 --- a/util-taglib/src/com/liferay/taglib/aui/LinkTag.java +++ b/util-taglib/src/com/liferay/taglib/aui/LinkTag.java @@ -7,11 +7,9 @@ import com.liferay.petra.string.StringPool; import com.liferay.portal.kernel.content.security.policy.ContentSecurityPolicyNonceProviderUtil; -import com.liferay.portal.kernel.exception.PortalException; -import com.liferay.portal.kernel.frontend.hashed.files.HashedFilesRegistryUtil; -import com.liferay.portal.kernel.util.PortalUtil; import com.liferay.portal.kernel.util.Validator; import com.liferay.taglib.aui.base.BaseLinkTag; +import com.liferay.taglib.util.HashedFileUtil; import jakarta.servlet.jsp.JspException; import jakarta.servlet.jsp.JspWriter; @@ -52,26 +50,7 @@ public int doEndTag() throws JspException { if (Validator.isNotNull(href)) { if (getHashedFile()) { - String prefix = PortalUtil.getPathModule(); - - String proxyPath = PortalUtil.getPathProxy(); - - prefix = prefix.substring(proxyPath.length()); - - String hashedFileURI = - HashedFilesRegistryUtil.getHashedFileURI( - prefix + StringPool.SLASH + href); - - if (hashedFileURI != null) { - try { - href = - PortalUtil.getCDNHost(getRequest()) + - proxyPath + hashedFileURI; - } - catch (PortalException portalException) { - throw new RuntimeException(portalException); - } - } + href = HashedFileUtil.getURL(getRequest(), href); } _write(jspWriter, "href", href); diff --git a/util-taglib/src/com/liferay/taglib/aui/ScriptTag.java b/util-taglib/src/com/liferay/taglib/aui/ScriptTag.java index 7e610b01147bfa..586be20ff24766 100644 --- a/util-taglib/src/com/liferay/taglib/aui/ScriptTag.java +++ b/util-taglib/src/com/liferay/taglib/aui/ScriptTag.java @@ -15,6 +15,7 @@ import com.liferay.portal.kernel.util.Validator; import com.liferay.portal.kernel.util.WebKeys; import com.liferay.taglib.aui.base.BaseScriptTag; +import com.liferay.taglib.util.HashedFileUtil; import com.liferay.taglib.util.PortalIncludeUtil; import jakarta.servlet.http.HttpServletRequest; @@ -265,7 +266,14 @@ private int _endTag() throws IOException, JspException { _write(jspWriter, "id", getId()); _write(jspWriter, "integrity", getIntegrity()); _write(jspWriter, "referrerpolicy", getReferrerPolicy()); - _write(jspWriter, "src", getSrc()); + + String src = getSrc(); + + if (getHashedFile()) { + src = HashedFileUtil.getURL(getRequest(), src); + } + + _write(jspWriter, "src", src); _write(jspWriter, "type", getType()); String senna = getSenna(); diff --git a/util-taglib/src/com/liferay/taglib/aui/base/BaseScriptTag.java b/util-taglib/src/com/liferay/taglib/aui/base/BaseScriptTag.java index 6a267154cb4603..be62a35eec1687 100644 --- a/util-taglib/src/com/liferay/taglib/aui/base/BaseScriptTag.java +++ b/util-taglib/src/com/liferay/taglib/aui/base/BaseScriptTag.java @@ -40,6 +40,14 @@ public java.lang.String getFetchPriority() { return _fetchPriority; } + public boolean getHashedFile() { + return _hashedFile; + } + + public void setHashedFile(boolean hashedFile) { + _hashedFile = hashedFile; + } + public java.lang.String getId() { return _id; } @@ -138,6 +146,7 @@ protected void cleanUp() { _crossOrigin = null; _defer = false; _fetchPriority = null; + _hashedFile = false; _id = null; _integrity = null; _referrerPolicy = null; @@ -161,6 +170,7 @@ protected String getPage() { private java.lang.String _crossOrigin = null; private boolean _defer = false; private java.lang.String _fetchPriority = null; + private boolean _hashedFile; private java.lang.String _id = null; private java.lang.String _integrity = null; private java.lang.String _referrerPolicy = null; diff --git a/util-taglib/src/com/liferay/taglib/aui/base/packageinfo b/util-taglib/src/com/liferay/taglib/aui/base/packageinfo index e456c681cd9f35..dfded4826d974f 100644 --- a/util-taglib/src/com/liferay/taglib/aui/base/packageinfo +++ b/util-taglib/src/com/liferay/taglib/aui/base/packageinfo @@ -1 +1 @@ -version 18.1.0 \ No newline at end of file +version 18.2.0 \ No newline at end of file diff --git a/util-taglib/src/com/liferay/taglib/aui/packageinfo b/util-taglib/src/com/liferay/taglib/aui/packageinfo index 6b1cd2d89d4aa3..baa016bd1a7785 100644 --- a/util-taglib/src/com/liferay/taglib/aui/packageinfo +++ b/util-taglib/src/com/liferay/taglib/aui/packageinfo @@ -1 +1 @@ -version 19.1.0 \ No newline at end of file +version 19.2.0 \ No newline at end of file diff --git a/util-taglib/src/com/liferay/taglib/liferay-aui.xml b/util-taglib/src/com/liferay/taglib/liferay-aui.xml index e80cfe98f3feeb..8620d07776242b 100644 --- a/util-taglib/src/com/liferay/taglib/liferay-aui.xml +++ b/util-taglib/src/com/liferay/taglib/liferay-aui.xml @@ -1061,6 +1061,11 @@ java.lang.String java.lang.String + + hashedFile + java.lang.Boolean + java.lang.Boolean + id java.lang.String diff --git a/util-taglib/src/com/liferay/taglib/util/HashedFileUtil.java b/util-taglib/src/com/liferay/taglib/util/HashedFileUtil.java new file mode 100644 index 00000000000000..0451a2aa215561 --- /dev/null +++ b/util-taglib/src/com/liferay/taglib/util/HashedFileUtil.java @@ -0,0 +1,44 @@ +/** + * SPDX-FileCopyrightText: (c) 2025 Liferay, Inc. https://liferay.com + * SPDX-License-Identifier: LGPL-2.1-or-later OR LicenseRef-Liferay-DXP-EULA-2.0.0-2023-06 + */ + +package com.liferay.taglib.util; + +import com.liferay.petra.string.StringPool; +import com.liferay.portal.kernel.exception.PortalException; +import com.liferay.portal.kernel.frontend.hashed.files.HashedFilesRegistryUtil; +import com.liferay.portal.kernel.util.PortalUtil; + +import jakarta.servlet.http.HttpServletRequest; + +/** + * @author Iván Zaera Avellón + */ +public class HashedFileUtil { + + public static String getURL( + HttpServletRequest httpServletRequest, String resourcePath) { + + String prefix = PortalUtil.getPathModule(); + + String proxyPath = PortalUtil.getPathProxy(); + + prefix = prefix.substring(proxyPath.length()); + + String unhashedFileURI = prefix + StringPool.SLASH + resourcePath; + + String hashedFileURI = HashedFilesRegistryUtil.getHashedFileURI( + unhashedFileURI); + + String uri = (hashedFileURI == null) ? unhashedFileURI : hashedFileURI; + + try { + return PortalUtil.getCDNHost(httpServletRequest) + proxyPath + uri; + } + catch (PortalException portalException) { + throw new RuntimeException(portalException); + } + } + +} \ No newline at end of file diff --git a/util-taglib/src/com/liferay/taglib/util/packageinfo b/util-taglib/src/com/liferay/taglib/util/packageinfo index f7a759e8701cdb..755bd3f5c7277b 100644 --- a/util-taglib/src/com/liferay/taglib/util/packageinfo +++ b/util-taglib/src/com/liferay/taglib/util/packageinfo @@ -1 +1 @@ -version 15.0.0 \ No newline at end of file +version 15.1.0 \ No newline at end of file