all things javascript - smc

Post on 09-Dec-2021

1 Views

Category:

Documents

0 Downloads

Preview:

Click to see full reader

TRANSCRIPT

All Things JavaScriptSu Liferay DXP 7.x e Liferay Portal CE 7.x

Carlo CervellinFront-End Engineer

Pier Paolo RamonHead of Digital

Liferay DXP è una pia;aforma

per realizzare Composite Applica.ons

Liferay DXP è una pia;aforma

per realizzare Composite Applica.ons

Liferay DXP è una pia;aforma

per realizzare Composite Applica.ons

!!

La cara1eris3ca principale delle Composite Applica3ons

è non avere un Single Point of Build

Sfide da tenerein considerazione

Minificazionee peso della pagina

Concatenazione e Bundling

Caricamentoe Lazy Loading

Ordine di esecuzionee dipendenze

Coordinazionetra componen9

Scriptse Moduli

Concatenazione Combo Loader

Caching Sta9c Resource URLs + CDN Configura9on

Minificazione Minificatore automa9co(Google Closure Compiler)

Turbolinks SPA Framework(Senna.js)

Bundling Liferay AMD Loader+ Combo Loader

Registrazione come dipendenza di Portlet

Registrazione come dipendenza di Portlet

@Component( service = Portlet.class, properties = { "com.liferay.portlet.header-portlet-css=/css/main.css", "com.liferay.portlet.header-portlet-javascript=/js/main.js"

} ) public class AwesomePortlet extends MVCPortlet { … }

Registrazione come dipendenza di Portlet

<head> header-portlet-javascript

!</head>

<body> Contenuto della pagina footer-portlet-javascript

!</body>

Registrazione come dipendenza di Portlet

Vengono concatenate in Combo Load?

Quando viene caricata?

Quando viene eseguita?

Viene eseguita ogni navigazione?

Solo una volta e solo quando la portlet è in pagina

Subito prima / dopo del corpo

Sì — è uno “script”

Caricamento manuale via <script>

Caricamento manuale via <script>

<script src="/o/awesome-portlet-web/js/utility.js">!</script>

Nei frammen9 JSPdei Dynamic Include

Web Content Templates Applica9on Display Templates

Fragments

Nei frammen9 JSPdelle Portlet

FTL del tema

Caricamento manuale via <script>

<script src="<%= request.getContextPath() + "/js/utility.js"

%>">!</script>

Questo ci perme\e di evitare di dover conoscere

il Web Context Path del bundle OSGi

Caricamento manuale via <script>

<script src="<%= PortalUtil.getPathContext(request) + "/js/utility.js"

%>">!</script>

ATTENZIONE! L’ordine di «Path» e «Context»è al contrario rispe\o a prima!

Questo ci perme\e di supportare casi in cui il portale non è nella

root del server. Il 9pico /portal

Caricamento manuale via <script>

<script src="<%= PortalUtil.getStaticResourceURL(

request, PortalUtil.getPathContext(request) + "/js/utility.js", ""...

) %>">!</script>

Aggiunge i parametri in query string necessari ad abvare il minificatore

automa9co

Ci sono alcuneconfigurazioni

possibili. Per scoprirle…

…leggete il sorgentedi PortalImpl :)

Caricamento manuale via <script>

<script src="<%= PortalUtil.getStaticResourceURL(

request, themeDisplay.getCDNDynamicResourcesHost() + PortalUtil.getPathContext(request) + "/js/utility.js", !!...

) %>">!</script> Se configurata una CDN

dinamica (capace di fare cache on-demand delle

risorse) questo ci perme\e di sfru\arla.

<head> header-portlet-javascript

!</head>

<body> Contenuto della pagina

Script manuali footer-portlet-javascript

!</body>

Caricamento manuale via <script>

Vengono concatenate in Combo Load?

Quando viene caricata?

Quando viene eseguita?

Viene eseguita ogni navigazione?

No

N volte, nel corpo della pagina

N volte, ad ogni presenza nella pagina

Sì — è uno “script”

Caricamento manuale via <script>

Caricamento manuale via <script> e a1ributo data-senna-track

<script data-senna-track="permanent" src="<%= PortalUtil.getStaticResourceURL(

request, themeDisplay.getCDNDynamicResourcesHost() + PortalUtil.getPathContext(request) + "/js/utility.js", !!...

) %>">!</script>

Caricamento manuale via <script> e a1ributo data-senna-track

Vengono concatenate in Combo Load?

Quando viene caricata?

Quando viene eseguita?

Viene eseguita ogni navigazione?

No

N volte, nel corpo della pagina

N volte, ad ogni presenza nella pagina

No! Viene tra;ato come modulo!

Caricamento manuale via <script> e a1ributo data-senna-track

Caricamento manuale via <script> e <liferay-util:html-top/bottom>

Caricamento manuale via <script> e <liferay-util:html-top/bottom>

<liferay-util:html-top> <script src="!!.../js/utility.js">!</script>

"</liferay-util:html-top>

<liferay-util:html-bottom> <script src="!!.../js/utility.js">!</script>

"</liferay-util:html-bottom>

Questo porta nella <head>

Questo porta a fondo <body>

<head> header-portlet-javascriptliferay-util:html-top

!</head>

<body> Contenuto della pagina

Script manuali footer-portlet-javascriptliferay-util:html-bottom

!</body>

Caricamento manuale via <script> e <liferay-util:html-top/bottom>

Vengono concatenate in Combo Load?

Quando viene caricata?

Quando viene eseguita?

Viene eseguita ogni navigazione?

No

N volte, inizio o fine pagina

N volte, inizio o fine pagina

Sì — è uno “script”

Caricamento manuale via <script> e <liferay-util:html-top/bottom>

Caricamento manuale via <script> e <liferay-util:html-top/bottom>

e a1ributo outputKey="..."

Caricamento manuale via <script> e <liferay-util:html-top/bottom>

e a1ributo outputKey="..."

<liferay-util:html-top> <script src="!!.../js/utility.js">!</script>

!</liferay-util:html-top>

Caricamento manuale via <script> e <liferay-util:html-top/bottom>

e a1ributo outputKey="..."

<liferay-util:html-top outputKey="awesome-key"> <script src="!!.../js/utility.js">!</script>

!</liferay-util:html-top>

Assicura che il frammento incluso nel tag <liferay-u2l:html-top>venga riportato nella pagina finale una sola volta

Vengono concatenate in Combo Load?

Quando viene caricata?

Quando viene eseguita?

Viene eseguita ogni navigazione?

No

1 volta, inizio o fine pagina

1 volta, inizio o fine pagina

Sì — è uno “script”

Caricamento manuale via <script> e <liferay-util:html-top/bottom>

e a1ributo outputKey="..."

Caricamento via Theme Contributor

Caricamento via Theme Contributor

bnd.bnd Liferay-Theme-Contributor-Type: some-unique-name

Nessuna relazione con i temi! Da non confondere con i Template Context Contributor!

TuG i file staIci (.js e .css) del modulovengono carica9 in tu;e le pagine.

<head> header-portlet-javascriptliferay-util:html-top Theme Contributor resources

!</head>

<body> Contenuto della pagina

Script manuali footer-portlet-javascriptliferay-util:html-bottom

!</body>

Caricamento via Theme Contributor

Vengono concatenate in Combo Load?

Quando viene caricata?

Quando viene eseguita?

Viene eseguita ogni navigazione?

1 volta, ad inizio pagina

1 volta, alla prima navigazione

No! Vengono tra;aI come moduli!

Caricamento via Theme Contributor

Caricamento via Liferay AMD Loader

Caricamento via Liferay AMD Loader

Liferay.Loader.require( 'some-module', function (someModule) { !// :) } );

Liferay.Loader.define( 'some-module', function () { return { … } } );

1 2

Asynchronous Module Defini9on

Prima deve essere eseguito questo… …poi questo. Non molto asincrono :(

Caricamento via Liferay AMD Loader

Liferay.Loader.require( 'some-module', function (someModule) { !// :) } );

Liferay.Loader.define( 'some-module', function () { return { … } } );

1 2

Asynchronous Module Defini9on

Prima deve essere eseguito questo… …poi questo. Non molto asincrono :(

Caricamento via Liferay AMD Loader

Liferay.Loader.require( 'some-module', function (someModule) { !// :) } );

Liferay.Loader.define( 'some-module', function () { return { … } } );

Liferay.Loader.addModule({ name: 'some-module', path: '/o/blahblah/some-module.js' });

1

2

Caricamento via Liferay AMD Loader

Liferay.Loader.require( 'some-module', function (someModule) { !// :) } );

Liferay.Loader.define( 'some-module', function () { return { … } } );

Liferay.Loader.addModule({ name: 'some-module', path: '/o/blahblah/some-module.js' });

1

2

Caricamento via Liferay AMD Loader

Liferay.Loader.require( 'some-module', function (someModule) { !// :) } );

Liferay.Loader.define( 'some-module', function () { return { … } } );

Liferay.Loader.addModule({ name: 'some-module', path: '/o/blahblah/some-module.js' });

LAZY LOADED

1

2

ASYNC!

bnd.bnd (Liferay Modules) Liferay-JS-Config: /js/config.js

liferay-plugin-package.properties (Themes) Liferay-JS-Config=/js/config.js

/src/main/resources/META-INF/resources/js/config.js Liferay.Loader.addModule({ …… }); Liferay.Loader.addModule({ …… });

Caricamento via Liferay AMD Loader

<head> Liferay-JS-Config

header-portlet-javascriptliferay-util:html-top Theme Contributor resources

!</head>

<body> Contenuto della pagina

Script manuali footer-portlet-javascriptliferay-util:html-bottom

!</body>

Caricamento via Liferay AMD Loader

Caricamento via Liferay AMD Loader

Liferay.Loader.addModule({ name: 'named-module', path: '/o/!!.../named-module.js', anonymous: false, });

Liferay.Loader.define( 'named-module', function () { return { … } } );

Liferay.Loader.addModule({ name: 'named-module', path: '/o/!!.../anon-module.js', anonymous: true, });

Liferay.Loader.define( "// nessun nome :( function () { return { … } } );

Named Module Defini2on Anonymous Module Defini2on

Combo Loading?Nessun problema!

Combo Loading?Assolutamente NO!

Vengono concatenate in Combo Load?

Quando viene caricata?

Quando viene eseguita?

Viene eseguita ogni navigazione?

Sì, ma non per gli anonymous

1 volta, al primo require()

1 volta, al primo require()

No!!!! Sono moduli!!!

Caricamento via Liferay AMD Loader

Caricamento via Liferay npm Bundler

Caricamento via Liferay npm Bundler

Liferay.Loader.require('react', function (React) { !!... });

my-awesome-web/!!.../main.es.js import React from 'react';

Caricamento via Liferay npm Bundler

Liferay.Loader.require('react@16.8.2', function (React) { !!... });

my-awesome-web/!!.../main.es.js import React from 'react';

Caricamento via Liferay npm Bundler

Liferay.Loader.require('react@16.8.2', function (React) { !!... });

my-awesome-web/!!.../main.es.js import React from 'react';

my-awesome-web/package.json "dependencies": { "react": "^16.0.0" }

Caricamento via Liferay npm Bundler

Liferay.Loader.require('react@16.8.2', function (React) { !!... });

node_modules/react-redux/main.js import React from 'react';

my-awesome-web/!!.../main.es.js import { connect } from 'react-redux';

bundle.js

App sviluppata

con un framework

front-end moderno

Compilazione

tradizionale

file per file (Babel)

Liferay

npm Bundler

Liferay

AMD Loader

+

Combo Loader

Compilazione

unificata

(CRA, Vue CLI, Angular CLI)

????

(Lasciamo alle;ore il piacere

di deciderlo)

ES2018+ ES5 + AMD Liferay AMD+ Config

ES2018+ ES5 Caricamento…

bundle.js

Compilazione

tradizionale

file per file (Babel)

Liferay

npm Bundler

Liferay

AMD Loader

+

Combo Loader

Compilazione

unificata

(CRA, Vue CLI, Angular CLI)

✅ Componibile ✅ Dipendenze de-duplicate " Molte richieste dal client " Nessuna dead-code elimina8on

✅ Molto o9mizzato ✅ Integrabile a tu<o il tooling " Output opaco " Complessità di integrazione

????

(Lasciamo alle;ore il piacere

di deciderlo)

my-awesome-react-app/build ├── asset-manifest.json ├── index.html └── static/js ├── 1.4e00e461.chunk.js ├── main.3ff68361.chunk.js └── runtime~main.696ab712.js

my-awesome-react-app/build ├── asset-manifest.json ├── index.html └── static/js ├── 1.4e00e461.chunk.js ├── main.3ff68361.chunk.js └── runtime~main.696ab712.js

my-awesome-react-app/build/asset-manifest.json { "main.js": "/static/js/main.3ff68361.chunk.js", }

Carlo CervellinFront-End Engineer

carlo.cervellin@smc.it

GitHub @crcarlo

Pier Paolo RamonHead of Digital

pierpaolo.ramon@smc.it

GitHub @yuchi

TwiBer @_pier

+39 340 1755621

Domande?

Grazie!

#LRBC19

top related