Example to show how Liferay Portlets can be developed with es module functionality
LIFERAY ES MODULE PORTLET
Sample repository to show how to use Liferay portlets with es modules.
Goal
Provide packages and components with a portlet and import them on runtime into a portlet. This should increase build time to a minimum because the liferay-npm-bundler
doesn’t has to transpile files and only creates a jar file.
Explenation
The concept includes two modules. A provider module and a consumer modules. They are connected in a n to n
relation.
Provider Module
A provider module exposes a package or component or basically anything through a portlet and serves the module then through an url.
To make this work, the following steps have to be done.
-
Create an entry which is required for the
liferay-npm-bundler
.export default function main () {}
See
es-react-provider/src/entry.js
as an example -
Create an index module which exports all modules which you’d like to provide through this module.
import SampleModule from './modules/SampleModule' import AnotherSampleModule from './modules/AnotherSampleModule' export { SampleModule, AnotherSampleModule }
See
es-react-provider/src/index.ts
as an example -
Create two bundle processes which bundle the entry for the
liferay-npm-bundler
and theindex.ts
file.- The entry for the
liferay-npm-bundler
needs to be placed inside thebuild
folder in thecommonjs
format for liferay to handle it correctly. - The bundled version of the
index.ts
needs to be placed inside theassets
folder in thees
format, preferably in thelib
subfolder.
See
es-react-provider/rollup.config.js
as an example - The entry for the
-
Define the
liferay-npm-bundler
to- ignore the assets folder
- make the portlet available through a defined url
- create a jar file
See
es-react-provider/.npmbundlerrc
as an example
Consumer Module
A consumer module uses the provided es modules from provider modules.
-
Create an entry which includes a
script
html tag and imports a file.export default function main(entryParams) { const node = document.getElementById(entryParams.portletElementId); const script = document.createElement('script') script.setAttribute('type', 'module') script.innerText = ` import { main } from '/o/es-react-portlet/lib/index.js'; main(${JSON.stringify(entryParams)}); ` node.append(script) }
See
es-react-portlet/src/entry.ts
as an example -
Create an index module, which (in our example) consumes some of the provided modules.
import { SampleModule, AnotherSampleModule } from '/o/es-provider/lib/index.js' export function main (entryParams) { ... }
See
es-react-portlet/src/index.tsx
as an example -
Create two bundle processes which bundle the entry for the
liferay-npm-bundler
and theindex
file.- The entry for the
liferay-npm-bundler
needs to be placed inside thebuild
folder in thecommonjs
format for liferay to handle it correctly. - The bundled version of the
index
needs to be placed inside theassets
folder in thees
format, preferably in thelib
subfolder. - The
/o/es-provider/lib/index.js
has to be defined to be an external module, so the bundler doesn’t throws an error on build time.
See
es-react-portlet/rollup.config.js
as an example - The entry for the
-
Define the
liferay-npm-bundler
to- ignore the assets folder
- make the portlet available through a defined url
- create a jar file
See
es-react-portlet/.npmbundlerrc
as an example
Example
This workspace contains three modules.
Modules
es-react-provider
Contains and exposes react
and react-dom
as es modules.
es-react-components
Contains components which can be imported into a portlet.
es-react-portlet
Contains the actual portlet which uses the react
and react-dom
from the es-react-provider
module and includes a sample component from the es-react-components
module.
How to run
To run this example, all modules need to be built and deployt onto a liferay instance. After that, everything should work as expected.