RE: Liferay NPM Bundler with ReactJS and Clay

René Hengstermann, modified 6 Years ago. New Member Posts: 8 Join Date: 8/29/15 Recent Posts
Hello Community,

I like to use the Liferay NPM Bundler with the Clay web components to make use of the prebuild components in Clay as well as ReactJS for fast dom traversal and loading, as described here: https://github.com/liferay/clay/tree/2.x/examples/react-with-clay

If I start my React app standalone 'npm run start' the clay components are visible and actionable.

The Versions of the components I am using are:
  • Liferay 7.1
  • Clay 2.14.2
  • React 16.3.2
  • NPM Bundler 2.6.2

If I run 'npm deploy' to bundle an OSGI bundle and deploy it to Liferay, I get two errors:

Bowser JS Console: see attached file "Error-JS-Console.png"

In the Liferay logs I am seeing a corresponding errors of the NPMPackageResolver:
07:58:29,797 ERROR [http-nio-8080-exec-5][DynamicIncludeUtil:79] java.lang.NullPointerException
java.lang.NullPointerException
        at com.liferay.frontend.js.loader.modules.extender.internal.npm.NPMResolverImpl.resolveModuleName(NPMResolverImpl.java:83)
        at com.liferay.frontend.js.spa.web.internal.servlet.taglib.SPATopHeadJSPDynamicInclude.include(SPATopHeadJSPDynamicInclude.java:103)
        at com.liferay.portal.kernel.servlet.taglib.DynamicIncludeUtil.include(DynamicIncludeUtil.java:76)
        at com.liferay.taglib.util.DynamicIncludeTag.doEndTag(DynamicIncludeTag.java:32)
...
07:58:31,431 ERROR [http-nio-8080-exec-1][ComboServlet:90] java.lang.IllegalArgumentException: Path [metal-dom/src/all/dom.js] does not start with a "/" character
java.lang.IllegalArgumentException: Path [metal-dom/src/all/dom.js] does not start with a "/" character
        at org.apache.catalina.core.ApplicationContext.getRequestDispatcher(ApplicationContext.java:404)
        at org.apache.catalina.core.ApplicationContextFacade.getRequestDispatcher(ApplicationContextFacade.java:222)
        at com.liferay.portal.servlet.ComboServlet.getResourceRequestDispatcher(ComboServlet.java:429)
...


Has any one a hint on how to investigate this error further ?

Thank you,
Rene
thumbnail
Ivan Zaera, modified 6 Years ago. Regular Member Posts: 119 Join Date: 10/1/13 Recent Posts
Looks like there's an issue with your "com.liferay.frontend.js.spa.web" bundle because, looking at the stack trace, this call is failing because this code is throwing a NPE.

That is probably caused by the NPMRegistry not knowing anything about the frontend-js-spa-web bundle.

Said that, I have no idea of what could be causing this. There may be a variety of reasons.

Have you had a look at http://localhost:8080/o/js_loader_modules ? Maybe you can see there if there's something wrong with frontend-js-spa-web...
René Hengstermann, modified 6 Years ago. New Member Posts: 8 Join Date: 8/29/15 Recent Posts
Hello Ivan,

thanks for your reply :-)

I also discovered that the module thows an exception on deployment:
java.lang.NullPointerException
        at com.github.yuchi.semver.Version.compareTo(Version.java:158)
        at com.github.yuchi.semver.Version.compareTo(Version.java:5)
        at java.util.Comparator.lambda$comparing$77a9974f$1(Comparator.java:469)
        at java.util.Collections$ReverseComparator2.compare(Collections.java:5178)
        at java.util.TimSort.binarySort(TimSort.java:296)
        at java.util.TimSort.sort(TimSort.java:239)
        at java.util.Arrays.sort(Arrays.java:1512)
        at java.util.ArrayList.sort(ArrayList.java:1460)
        at com.liferay.frontend.js.loader.modules.extender.internal.npm.NPMRegistryImpl._refreshJSModuleCaches(NPMRegistryImpl.java:341)
        at com.liferay.frontend.js.loader.modules.extender.internal.npm.NPMRegistryImpl._processBundle(NPMRegistryImpl.java:279)

For some reason one of the js packages inside of my module has a empty version number.

Strangely this module seems to contain my index.js (which is the main entrance point of my application), but without the version of my module.
René Hengstermann, modified 6 Years ago. New Member Posts: 8 Join Date: 8/29/15 Recent Posts
I changed now the way how I create the app, as described here: https://dev.liferay.com/develop/reference/-/knowledge_base/7-1/the-structure-of-osgi-bundles-containing-npm-packages

Now I get errors, that several Clay elements are already defined:
Uncaught Error: Namespace "ClayIcon.incrementaldom" already declared.
Any further thoughts ?
thumbnail
Ivan Zaera, modified 6 Years ago. Regular Member Posts: 119 Join Date: 10/1/13 Recent Posts
That is because clay cannot be loaded more than once because it uses SOY under the hood and SOY uses a global namespace :-(. So, even if you use an AMD loader to attain modularity, there's a bottleneck in SOY library because every AMD module shares the same namespace.

The solution to fix this is importing clay libraries from the portal instead of providing your own. This has some limitations because you cannot control which version of clay gets loaded as you are delegating that decission to the portal itself. However, because we also use clay in the portal, chances are that it is always up to date.

If you want to import clay you need to add the following to your .npmbundlerrc file:

"config": {
    "imports": {
        "frontend-taglib-clay": {
            "clay-alert": ">=2.9.0",
            "clay-autocomplete": ">=2.9.0",
            "clay-badge": ">=2.9.0",
            "clay-button": ">=2.9.0",
            "clay-card": ">=2.9.0",
            "clay-card-grid": ">=2.9.0",
            "clay-checkbox": ">=2.9.0",
            "clay-collapse": ">=2.9.0",
            "clay-component": ">=2.9.0",
            "clay-data-provider": ">=2.9.0",
            "clay-dataset-display": ">=2.9.0",
            "clay-dropdown": ">=2.9.0",
            "clay-icon": ">=2.9.0",
            "clay-label": ">=2.9.0",
            "clay-link": ">=2.9.0",
            "clay-list": ">=2.9.0",
            "clay-loading-indicator": ">=2.9.0",
            "clay-management-toolbar": ">=2.9.0",
            "clay-modal": ">=2.9.0",
            "clay-multi-select": ">=2.9.0",
            "clay-navigation-bar": ">=2.9.0",
            "clay-pagination": ">=2.9.0",
            "clay-pagination-bar": ">=2.9.0",
            "clay-portal": ">=2.9.0",
            "clay-progress-bar": ">=2.9.0",
            "clay-radio": ">=2.9.0",
            "clay-select": ">=2.9.0",
            "clay-sticker": ">=2.9.0",
            "clay-table": ">=2.9.0",
            "clay-tooltip": ">=2.9.0"
        }
    }
}

Note that 2.9.0 should be substituted by the version you are using. It will probably make sense to have the same version you are using in package.json with a >= prepended so that if the portal updates clay your module doesn't break.

Currently, portal 7.1 is using these versions of clay -> https://github.com/liferay/liferay-portal/blob/7.1.x/modules/apps/frontend-taglib/frontend-taglib-clay/package.json

Hope this helps.
René Hengstermann, modified 6 Years ago. New Member Posts: 8 Join Date: 8/29/15 Recent Posts
Hello Ivan,

thanks again for your feedback.

I recreated my module from scratch with the Liferay NPM Bundler, now changing the .npmbundlerrc as you suggested.

Now I am able to load my module properly, but now It tells me that the Version of clay which I am referencing is not loaded in the Server:
Liferay AMD Loader: Unhandled failure: Error: The following problems where detected while resolving modules:
Package frontend-taglib-clay$clay-button which is a dependency of planner-test@1.0.0 is not deployed in the server
Package frontend-taglib-clay$clay-badge which is a dependency of planner-test@1.0.0 is not deployed in the server
    at Loader._getResolutionError (combo?browserId=other&minifierType=js&languageId=en_US&b=7110&t=1557762987464&/o/frontend-js-web/jquery/jquery.js&/o/frontend-js-web/clay/popper.js&/o/frontend-js-web/clay/bootstrap.js&/o/frontend-js-web/loader/config.js&/o/frontend-js-web/loader/loader.js&/o/frontend-js-web/aui/aui/aui.js&/o/frontend-js-web/aui/aui-base-html5-shiv/aui-base-html5-shiv.js&/o/frontend-js-web/liferay/browser_selectors.js&/o/frontend-js-web/liferay/modules.js&/o/frontend-js-web/liferay/aui_sandbox.js&/o/frontend-js-web/clay/collapsible-search.js&/o/frontend-js-web/clay/side-navigation.js&/o/frontend-js-web/jquery/fm.js&/o/frontend-js-web/jquery/form.js&/o/frontend-js-web/misc/svg4everybody.js&/o/frontend-js-web/aui/arraylist-add/arraylist-add.js&/o/frontend-js-web/aui/arraylist-filter/arraylist-filter.js&/o/frontend-js-web/aui/arraylist/arraylist.js&/o/frontend-js-web/aui/array-extras/array-extras.js&/o/frontend-js-web/aui/array-invoke/array-invoke.js&/o/frontend-js-web/aui/attribute-base/attribute-base.js&/o/frontend-js-web/aui/attribute-complex/attribute-complex.js&/o/frontend-js-web/aui/attribute-core/attribute-core.js&/o/frontend-js-web/aui/attribute-observable/attribute-observable.js&/o/frontend-js-web/aui/attribute-extras/attribute-extras.js&/o/frontend-js-web/aui/base-base/base-base.js&/o/frontend-js-web/aui/base-pluginhost/base-pluginhost.js&/o/frontend-js-web/aui/classnamemanager/classnamemanager.js&/o/frontend-js-web/aui/datatype-xml-format/datatype-xml-format.js&/o/frontend-js-web/aui/datatype-xml-parse/datatype-xml-parse.js&/o/frontend-js-web/aui/dom-base/dom-base.js&/o/frontend-js-web/aui/dom-core/dom-core.js&/o/frontend-js-web/aui/dom-screen/dom-screen.js&/o/frontend-js-web/aui/dom-style/dom-style.js&/o/frontend-js-web/aui/event-base/event-base.js&/o/frontend-js-web/aui/event-custom-base/event-custom-base.js&/o/frontend-js-web/aui/event-custom-complex/event-custom-complex.js&/o/frontend-js-web/aui/event-delegate/event-delegate.js&/o/frontend-js-web/aui/event-focus/event-focus.js:17425)
thumbnail
Ivan Zaera, modified 6 Years ago. Regular Member Posts: 119 Join Date: 10/1/13 Recent Posts
What version of frontend-taglib-clay$clay-button and frontend-taglib-clay$clay-badge do you have in your portal?

Can you have a look at http://localhost:8080/o/js_loader_modules and look for it?

It should match the semantic versioning expresion you have in the imports section of your .npmbundlerrc file...
René Hengstermann, modified 6 Years ago. New Member Posts: 8 Join Date: 8/29/15 Recent Posts
Hello Ivan,

that was the key :-)

I was looking into the frontend spa module in the Liferay source for the Version, but it was the wrong one.

It now renders and works, thank you very much.

Best regards,
Rene
thumbnail
Ivan Zaera, modified 6 Years ago. Regular Member Posts: 119 Join Date: 10/1/13 Recent Posts
Of course, don't use a version higher than the one the portal is providing, because it won't match unless you change the semantic version expression to somehting less restricting.