Message Boards

Various problems when including React dependencies

thumbnail
André Bräkling, modified 2 Years ago.

Various problems when including React dependencies

Junior Member Posts: 30 Join Date: 7/8/13 Recent Posts

Hello everybody,

for some time now we have been migrating our existing portlets to React components to create a modern and flexible frontend.

Sadly, we face various problems when we try to include predefined components as dependecies, so that a meaningful use of React is hardly possible. At first we assumed that we might have chosen too exotic components, or that we were doing the inclusion incorrectly, but the problems are occurring with more and more proven components, and in environments outside of Liferay (even in simple sandboxes like codesandbox.ai) everything works fine.

Generally, the problems mostly relate to further dependencies or to versions or version conflicts. However, since the error messages are very different, we have no real point of attack here. 

Lastly, we tried to update the embedded Node/NPM version, but without finding any effect here. We are using Liferay 7.1 (DXP/Enterprise).

Here a list of examples:

I can't imagine we're the only ones using React and want to incorporate existing components/modules. Either we are doing something fundamentally wrong here or have a thinking error, or these problems should have been noticed by one or the other of you already.

Does anyone have a starting point for us? Maybe links that go beyond the basic Liferay tutorials & docs, which are unfortunately once again not very helpful here, and address such things? Best practices?

Right now it seems easier for us to build the frontend as a standalone React application and run Liferay behind it as a headless CMS, but that can't be in the spirit of the inventor, can it?

If any details (package.json, stacktraces, ...) help you further, please let me know (if necessary also in relation to which component/error message, as we are dealing with different modules in our system), I'll submit anything that could help further.

Thanks in advance!

 

Sascha Hofrichter, modified 2 Years ago.

RE: Various problems when including React dependencies

New Member Posts: 8 Join Date: 1/17/20 Recent Posts

Hey André,
how do you create the React portlets?
Do you use the 'generator-liferay-js' like this https://help.liferay.com/hc/en-us/articles/360029147411-Installing-the-JS-Generator-and-Generating-a-Bundle?
I know, this document relates to the Liferay 7.2 DXP but it could help you to generate the React portlets.

We use the React portlets in Liferay 7.4.1 CE and generate the portlets with this tool. By this reason, I don't know if this will help you.
Note: if you want to use this, you must make adjustments in the .babelrc file to add some plugins. Otherwise you have some strange side effects with JS arrow functions etc. Add the plugins do you need like that in the .babelrc:

"plugins": [
    "@babel/plugin-transform-arrow-functions",
    "@babel/plugin-proposal-class-properties",
    "syntax-async-functions"
]
If you use the 'generator-liferay-js'  it will generate a package.json for you. The package.json contains a 'build' script where babel and other liferay build tasks are called. These build script will copy (into a 'build' folder inside your portlet directory) all your NPM modules which are listed in your 'dependencies' section of the package.json. After that, the 'liferay-npm-bundler' will create the deployable *.jar file. This *.jar file contains your NPM modules. 

Another Blog post might be interesting for you: https://liferay.dev/blogs/-/blogs/how-to-use-shared-library-javascript-with-react-in-liferay
This post describes how you create a 'shared' JS library which you can use in other ReactJS portlets.


I hope this will help you.

thumbnail
André Bräkling, modified 2 Years ago.

RE: RE: Various problems when including React dependencies

Junior Member Posts: 30 Join Date: 7/8/13 Recent Posts

Hello Sascha,

thanks for your reply!

I'll give this a try and see if this will make a difference. But our problems occur not on building the modules, but on using them. Anyway, I'll try and will post my feedback later today! :-)

We create our React Modules within IntelliJ by using the Liferay Module template npm-react-portlet.

Our working package.json files look like this:

{
	"dependencies": {
		"react": "16.8.6",
		"react-dom": "16.8.6"
	},
	"devDependencies": {
		"babel-cli": "^6.26.0",
		"babel-preset-env": "^1.7.0",
		"babel-preset-react": "6.24.1",
		"liferay-npm-bundler": "2.19.4",
		"liferay-npm-bundler-loader-json-loader": "^2.20.0"
	},
	"main": "lib/index.es.js",
	"name": "our-module-name",
	"scripts": {
		"build": "babel --source-maps -d build/resources/main/META-INF/resources src/main/resources/META-INF/resources && liferay-npm-bundler"
	},
	"version": "1.0.0"
}

What we want to do is to load some additional react components from npm modules as dependencies, but just a few work, all other fail because of several error messages (version constraints, additional depenencies, etc.). Anyway, the amcharts, for example, are succesfully downloaded and appear within the node_modules folder, but no chance to import and use them.

We tried as devDependency and as "normal" dependency as well. Yesterday we failed using react-markdown, so we now count five non-exotic react components we are not able to use within a Liferay module, but anywhere else where we use React.

Creating a common library is a nice thing, but first we want to get the dependencies working in just one module before we start sharing them ;-)

Sascha Hofrichter, modified 2 Years ago.

RE: Various problems when including React dependencies

New Member Posts: 8 Join Date: 1/17/20 Recent Posts

Hi André,

OK. Sorry, I can't check this at the moment. Because these npm-react-portlets are not genereted by the Liferay IntelliJ Plugin if your Liferay version is 7.2+.
In InteliJ I get this error:


Look at this: https://issues.liferay.com/browse/LPS-97950
I don't know if Liferay 7.1 DXP supports the React portlets made with 'generator-liferay-js'. But if it does, I would take this way.
Otherwise you have the next 'bigger' migrations if you update your Liferay from 7.1 to 7.2+.

I don't know how the npm-react-portlet works but I in your screenshot the 'main' points to 'lib/index.es.js'.
Is this the right file? 

 

thumbnail
André Bräkling, modified 2 Years ago.

RE: RE: Various problems when including React dependencies

Junior Member Posts: 30 Join Date: 7/8/13 Recent Posts

Hi Sascha,

thanks again for your help!

Yes, the main file configuration is correct. As I said, our React modules work fine, only as soon as we want to add a component as a dependency, it becomes a gamble.

I wasn't aware that npm-react-portlet was deprecated - thanks for pointing that out. We're migrating to 7.3 right now and haven't encountered any problems so far, but then that's probably just a matter of time. generator-liferay-js I've tested and I'm thrilled at first sight - unlike npm-react-portlet, using React in the frontend feels "right" with it, especially we don't have unnecessary overhead like the Java classes anymore. I really like it!

But our problems still persist. I tried with amcharts again. I create the demo code which was offered by generator-liferay-js, and then just added the dependency for amcharts:

{
	"name": "amcharts-demo",
	"version": "1.0.0",
	"description": "Amcharts Demo",
	"devDependencies": {
		"liferay-npm-bundler": "^2.26.0",
		"liferay-npm-build-support": "^2.26.0",
		"copy-webpack-plugin": "4.6.0",
		"webpack": "4.29.6",
		"webpack-cli": "3.3.0",
		"webpack-dev-server": "3.2.1",
		"@babel/cli": "^7.7.5",
		"@babel/core": "^7.7.5",
		"@babel/preset-env": "^7.7.6",
		"@babel/preset-react": "^7.7.4",
		"@amcharts/amcharts4": "^4.10.19"
	},
	"dependencies": {
		"react": "16.8.6",
		"react-dom": "16.8.6"
	},
	"scripts": {
		"build": "babel --source-maps -d build src && npm run copy-assets && liferay-npm-bundler",
		"copy-assets": "lnbs-copy-assets",
		"translate": "lnbs-translate",
		"deploy": "npm run build && lnbs-deploy",
		"start": "lnbs-start"
	},
	"portlet": {
		"com.liferay.portlet.display-category": "JS Demo",
		"com.liferay.portlet.header-portlet-css": "/css/styles.css",
		"com.liferay.portlet.instanceable": true,
		"javax.portlet.name": "amchartsdemo",
		"javax.portlet.security-role-ref": "power-user,user",
		"javax.portlet.resource-bundle": "content.Language"
	},
	"main": "index.js"
}

Then, I created a small component to use some amCharts demo code:

import React, { useRef, useLayoutEffect } from 'react';
import logo from './logo.svg';
import './App.css';
import * as am4core from "amcharts/amcharts4/core";
import * as am4charts from "@amcharts/amcharts4/charts";
import am4themes_animated from "@amcharts/amcharts4/themes/animated";

am4core.useTheme(am4themes_animated);

function Graph(props) {
  const chart = useRef(null);

  useLayoutEffect(() => {
    let x = am4core.create("chartdiv", am4charts.XYChart);

    x.paddingRight = 20;

    let data = [];
    let visits = 10;

    for (let i = 1; i < 366; i++) {
      visits += Math.round((Math.random() < 0.5 ? 1 : -1) * Math.random() * 10);
      data.push({ date: new Date(2018, 0, i), name: "name" + i, value: visits });
    }

    x.data = data;

    let dateAxis = x.xAxes.push(new am4charts.DateAxis());
    dateAxis.renderer.grid.template.location = 0;

    let valueAxis = x.yAxes.push(new am4charts.ValueAxis());
    valueAxis.tooltip.disabled = true;
    valueAxis.renderer.minWidth = 35;

    let series = x.series.push(new am4charts.LineSeries());
    series.dataFields.dateX = "date";
    series.dataFields.valueY = "value";
    series.tooltipText = "{valueY.value}";
    x.cursor = new am4charts.XYCursor();

    let scrollbarX = new am4charts.XYChartScrollbar();
    scrollbarX.series.push(series);
    x.scrollbarX = scrollbarX;

    chart.current = x;

    return () => {
      x.dispose();
    };
  }, []);

  return (
    <div id="chartdiv" style={{ width: "100%", height: "500px" }}></div>
  );
}
export { Graph };

(Based on https://www.amcharts.com/docs/v4/getting-started/integrations/using-react/)

But I still receive this error message:

Liferay AMD Loader: Unhandled failure: Error: The following problems where detected while resolving modules:
Missing version constraints for amcharts-demo$amcharts in package.json of amcharts-demo@1.0.0/amcharts4/core
Missing version constraints for @amcharts-demo$amcharts/amcharts4 in package.json of amcharts-demo@1.0.0/charts
Missing version constraints for @amcharts-demo$amcharts/amcharts4 in package.json of amcharts-demo@1.0.0/themes/animated
    at Loader._getResolutionError (loader.js:312)
    at loader.js:200 while resolving modules: ["amcharts-demo@1.0.0/index"]

So, switching to generator-liferay-js seems to be a big step forward (thanks again!), but does not solve our dependency issues. I'll ask my collegues who tried the other components I mentioned - maybe they have more luck, after all, the error messages were also partly very different.

Sascha Hofrichter, modified 2 Years ago.

RE: Various problems when including React dependencies

New Member Posts: 8 Join Date: 1/17/20 Recent Posts

Hi André,

First of all. The documentation of the 'generator-liferay-js' and other tools is .... ehm ... confusing at so many places ( sorry Liferay guys :-P ). 
And I don't know why the Liferay guys build up so many self-written tools. That makes the development very hard.
Anyway, there are so many combiniations of loaders and configurations. I have no idea which possibilities are right for you.
To understand how the liferay-npm-bundler works and what options do you have, look at this:


I have tested a fresh generated React portlet with your given example code. Without any adjustments on the .npmbundlerrc. And I have issues too.
But, I get (in my browser) this message first:

Uncaught SyntaxError: Unexpected token 'export'

It caused by following generated code:

//# sourceMappingURL=index.js.map
Liferay.Loader.define("@amcharts-demo$amcharts/amcharts4@4.10.20/core", ['module', 'exports', 'require'], function (module, exports, require) {
  var define = undefined;
  var global = window;
  {
    /**
     * This module houses all core/framework functionality and is required for
     * all charting components to work
     */
    /**
     * Elements: core
     */
    export { System, system } from "./.internal/core/System";
    ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^

   ...
   ...
   ... 
  }
});


I think, that the liferay-npm-bundler doesn't build the JS correctly with the amchart library.
I'm not sure but I seem to remember that the liferay-npm-bundler uses webpack 4.29.x in the background.
And there is a kwon issue in webpack.
Please look at this: https://www.amcharts.com/docs/v4/getting-started/integrations/using-webpack/

I haven't tested this yet.

Maybe it helps you.

Deepak Poyilil, modified 2 Years ago.

RE: Various problems when including React dependencies

New Member Posts: 23 Join Date: 12/24/10 Recent Posts

Hi Andre, I understand your question completely since i have gone through all these issues while working with React portlet in  Liferay 7.2. Liferay using liferay-js-generator and its own bundler called liferay-npm-bundler, because of this bundler you will face build, deployment and loading issue when working with react portlet. when i fixed dependeny issues then, faced deployment issue, since the build process for liferay-npm-bundler will take long time when you use more dependencies. If you move this into a common module probably you can fix this deployment issue but again another issue will come that is initial load issue. The portlet may not load on first time and will never load on a slow network. The solution i have used here is get rid of liferay npm bundler and used webpack instead. But creating react portlet with webpack build need many customization on the project structure and configuration. But its working better than the one generated with liferay-npm-bundler. I have documented my understanding in the below blog, it may help you to get a better picture,

React develoment in liferay

Liferay react with webpack

Moroever from the Liferay Devcon 2021 link, what i understood from Liferay front end engineer is that, they have stopped the liferay-npm-bundler v3.0 project development and webpack federation will replace the existing liferay bundler v2, ( some one correct me if i am wrong on this).

so my question to all front end liferay expert here is, what is your front end recomendation  to develop an application in Liferay 7.3, Liferay MVC with JSP, React portlet with webpack, React with Liferay npm bundler, clay or something else ?