Message Boards
How to override JavaScript modules?
How to override JavaScript modules?
New Member Posts: 16 Join Date: 1/22/20 Recent PostsRE: How to override JavaScript modules?
Regular Member Posts: 119 Join Date: 10/1/13 Recent PostsWhat have you tried exactly? An OSGi fragment bundle to overwrite a certain .js file?
RE: How to override JavaScript modules?
New Member Posts: 16 Join Date: 1/22/20 Recent PostsYes, I tried an OSGI fragment to override module https://github.com/liferay/liferay-portal/tree/7.2.1-ga2/modules/apps/map/map-common. I've added files:
- .npmbridgerrc - with the same content as original file in Liferay's repository
- .npmbundlerrc - I was testing
- package.json - with the same content as original file in Liferay's repository
- bnd.bnd - with added Fragment-Host: com.liferay.map.common;bundle-version="[4.0.0,5.0.0)"
- src/main/resources/META-INF/resources/js/ - all files (MapBase.es.js, MarkerBase.es.js, validators.es.js, GeoJSONBase.es.js)
RE: How to override JavaScript modules?
Regular Member Posts: 119 Join Date: 10/1/13 Recent PostsI would open the browser dev tools and check the network tab when the DDM geolocation field appears. Then I would inspect each JavaScript file downloaded to see where they are coming from (URL) and what are their contents. It may be several things: a caching issue, another URL being used, ....
RE: How to override JavaScript modules?
New Member Posts: 16 Join Date: 1/22/20 Recent PostsRE: How to override JavaScript modules?
Regular Member Posts: 119 Join Date: 10/1/13 Recent PostsEvery JS file served by the NPMRegistry (the ones downloaded from /o/js/....) are retrieved from the OSGi bundles using the Bundle API (from OSGi) so, as long, as that API returns the fragment file, it should work (see https://github.com/liferay/liferay-portal/blob/02caaf9ddb812523a225b4d6b77450aad11a69e8/modules/apps/frontend-js/frontend-js-loader-modules-extender/src/main/java/com/liferay/frontend/js/loader/modules/extender/internal/npm/flat/FlatJSBundle.java#L65 and https://github.com/liferay/liferay-portal/blob/02caaf9ddb812523a225b4d6b77450aad11a69e8/modules/apps/frontend-js/frontend-js-loader-modules-extender/src/main/java/com/liferay/frontend/js/loader/modules/extender/internal/npm/flat/FlatJSBundle.java#L87).
Maybe you can do a little test in Java: grab the map-common Bundle object from OSGi and ask it for the MapBase.es.js file to see what you get (if the original or the modified file). That could shed some light to the issue...
RE: How to override JavaScript modules?
New Member Posts: 16 Join Date: 1/22/20 Recent Posts- http://localhost:8080/o/js/resolved-module/map-common@4.0.17/js/MapBase.es.js - contains default implementation without my changes
- http://localhost:8080/o/js/module/2118/map-common@4.0.17/js/MapBase.es.js - contains default implementation without my changes
- http://localhost:8080/o/map-common/js/MapBase.es.js - my changes are visible
- test.txt directly inside resources folder (next to js folder)
- index.es.js inside resources/js/ folder
I also did a test with grabbing bundle object from OSGi (example code below)
package bundle.module;import java.net.URL;
import org.apache.commons.io.IOUtils;
import org.osgi.framework.Bundle;
import org.osgi.framework.BundleActivator;
import org.osgi.framework.BundleContext;
public class BundleModuleActivator implements BundleActivator {
@Override
public void start(BundleContext bundleContext) throws Exception {
try {
Bundle b = null;
Bundle[] bundles = bundleContext.getBundles();
for (Bundle bundle : bundles) {
if ("com.liferay.map.common".equals(bundle.getSymbolicName())) {
b = bundle;
}
}
System.out.println(b.getLocation());
URL url = b.getResource("/META-INF/resources/js/MapBase.es.js");
System.out.println("URL: " + url);
System.out.println("URL: " + IOUtils.toString(url));
} catch (Exception ex) {
System.err.println(ex.getMessage());
ex.printStackTrace();
}
}
@Override
public void stop(BundleContext bundleContext) throws Exception {
}
}
It returns original file instead modified. Honestly I've no idea how to override this file. I checked documentation, but it looks like there is no information or example how to do this.
RE: How to override JavaScript modules?
New Member Posts: 10 Join Date: 2/26/18 Recent PostsFrom your last post, it seems that your fragment is adding its contents (given the fact that your custom files are visible) but not overriding the contents (as the resolved-module .es.js source code is stil resolved to the original content).
How are you deploying the fragment? Do you have the fragment code accesible in any repository so anyone else could try to repdroduce your scenario?
RE: How to override JavaScript modules?
New Member Posts: 16 Join Date: 1/22/20 Recent PostsI've created GitHub repository -> https://github.com/mardrof/liferay-js-overriding and added map-common-fragment module. In MapBase.es.js I added alert function in 100 line. As you said, adding works, but overriding not.
RE: How to override JavaScript modules?
New Member Posts: 16 Join Date: 1/22/20 Recent PostsRE: How to override JavaScript modules?
New Member Posts: 2 Join Date: 3/29/22 Recent PostsHello,
Anyone found a solution to resolve the problem of overring a JS file in a JS module ? I'm facing the same issue in Liferay 7.4...
RE: How to override JavaScript modules?
New Member Posts: 2 Join Date: 7/20/22 Recent PostsPerhaps you are confusing the JSP method of of override using OSGI
fragments directly for the indrect approach needed to do the same
with javascript modules, which are using strict mode by default. This
might help: https://www.surekhatech.com/blog/override-liferay-portal-javascript
RE: How to override JavaScript modules?
New Member Post: 1 Join Date: 8/4/22 Recent PostsYou can override any built-in function by just re-declaring it. parseFloat = function(a){ alert(a) }; Now parseFloat(3) will alert 3.
RE: RE: How to override JavaScript modules?
New Member Posts: 2 Join Date: 7/20/22 Recent PostsThis is only the case if strict mode is not being used. Since the
class in question, MapBase is part of an ES module strict mode is the
default so only the first declaration will be respected. That is my
understanding of it anyways. Some info below
https://262.ecma-international.org/6.0/#sec-strict-mode-code
RE: How to override JavaScript modules?
Liferay Legend Posts: 14919 Join Date: 9/2/06 Recent PostsFor clarification purposes and for anyone else who stumbles upon this post in the future...
Liferay does not support overriding a JS file via a fragment bundle.
I don't care what it says above, it simply is not supported.
In vanilla OSGi, a fragment bundle can only add new files to the host bundle, it cannot override files from the host bundle. When accessing a file, OSGi will pick from the host bundle first (if it exists), and only if not found will it go to the fragment bundle.
Liferay does have an override in place exclusively for .jsp and .jspf files so fragment bundles can override these files from the host bundle. But this customization is only for JSP files and does not work for other types of files such as JS files.
There is no supported way to override a JS file in a Liferay module.
You can use the technique documented here: https://liferay.dev/blogs/-/blogs/extending-liferay-osgi-modules-revisited but it is important to point out that this is completely unsupported by Liferay.