Importazioni HTML

Includi per il Web

Perché eseguire le importazioni?

Pensa a come carichi diversi tipi di risorse sul web. Per JS, abbiamo <script src>. Per i CSS, probabilmente il tuo punto di riferimento è <link rel="stylesheet">. Per le immagini è <img>. Il video contiene <video>. Audio, <audio>... Vai al punto! La maggior parte dei contenuti sul web ha un modo semplice e dichiarativo per caricarsi automaticamente. Non è così per l'HTML. Di seguito sono riportate le opzioni a tua disposizione:

  1. <iframe> - comprovato, ma pesante. I contenuti di un iframe si trovano interamente in un contesto separato rispetto alla tua pagina. Questa è per lo più un'ottima funzionalità, ma comporta anche ulteriori sfide (ridurre le dimensioni del frame ai contenuti è difficile, è estremamente frustrante da inserire e uscire dallo script, ed è quasi impossibile da definire uno stile).
  2. AJAX - Adoro xhr.responseType="document", ma stai dicendo che ho bisogno di JavaScript per caricare il codice HTML? Non mi sembra giusto.
  3. CrazyHacksTM: incorporato in stringhe, nascosto come commenti (ad es. <script type="text/html">). Accidenti!

Hai visto l'ironia? La gestione dei contenuti più basilari del web, ovvero l'HTML, richiede il massimo impegno. Fortunatamente, i componenti web ci aiutano a tornare in pista.

Per iniziare

Le importazioni HTML, parte del cast di componenti web, consentono di includere documenti HTML in altri documenti HTML. Non devi neanche limitarti al markup. Un'importazione può anche includere CSS, JavaScript o qualsiasi altro elemento che un file .html può contenere. In altre parole, questo rende le importazioni uno strumento fantastico per caricare i file HTML/CSS/JS correlati.

Nozioni di base

Includi un'importazione nella pagina dichiarando un <link rel="import">:

<head>
    <link rel="import" href="/path/to/imports/stuff.html">
</head>

L'URL di un'importazione è chiamato posizione di importazione. Per caricare i contenuti da un altro dominio, il percorso di importazione deve essere abilitato per CORS:

<!-- Resources on other origins must be CORS-enabled. -->
<link rel="import" href="http://example.com/elements.html">

Rilevamento e supporto delle funzionalità

Per rilevare il supporto, controlla se .import esiste nell'elemento <link>:

function supportsImports() {
    return 'import' in document.createElement('link');
}

if (supportsImports()) {
    // Good to go!
} else {
    // Use other libraries/require systems to load files.
}

Il supporto dei browser è ancora nelle fasi iniziali. Chrome 31 è stato il primo browser a vedere un'implementazione, ma altri fornitori di browser non vedono l'ora di conoscere i risultati di ES Modules. Tuttavia, per altri browser, il polyfill webcomponents.js funziona benissimo fino a quando i contenuti non sono ampiamente supportati.

Raggruppamento delle risorse

Le importazioni forniscono una convenzione per raggruppare i file HTML/CSS/JS (anche altre importazioni HTML) in un unico prodotto. È una funzionalità intrinseca, ma molto potente. Se stai creando un tema o una libreria oppure vuoi semplicemente segmentare la tua app in blocchi logici, fornire agli utenti un singolo URL è accattivante. Puoi persino inviare un'intera app tramite importazione. Pensaci un attimo fa.

Un esempio reale è Bootstrap. Bootstrap è composto da singoli file (bootstrap.css, bootstrap.js, caratteri), richiede JQuery per i suoi plug-in e fornisce esempi di markup. Gli sviluppatori apprezzano la flessibilità à la carte. Permette loro di interagire nelle parti del framework che vogliono utilizzare. Detto questo, scommetto che il tuo tipico JoeDeveloperTM prende il volo più facilmente e scaricherà tutto Bootstrap.

Le importazioni sono molto utili per elementi come il bootstrap. Vi presento il futuro del caricamento di Bootstrap:

<head>
    <link rel="import" href="bootstrap.html">
</head>

Gli utenti caricano semplicemente un link di importazione HTML. Non hanno bisogno di preoccuparsi con i file a dispersione. Al contrario, viene gestito e aggregato l'intero Bootstrap in un'importazione, bootstrap.html:

<link rel="stylesheet" href="bootstrap.css">
<link rel="stylesheet" href="fonts.css">
<script src="jquery.js"></script>
<script src="bootstrap.js"></script>
<script src="bootstrap-tooltip.js"></script>
<script src="bootstrap-dropdown.js"></script>
...

<!-- scaffolding markup -->
<template>
    ...
</template>

Lascia stare. È roba eccitante.

Eventi di caricamento/errore

L'elemento <link> attiva un evento load quando un'importazione viene caricata correttamente e onerror quando il tentativo non va a buon fine (ad es. in caso di errore 404 della risorsa).

Le importazioni vengono caricate immediatamente. Un modo semplice per evitare grattacapi è utilizzare gli attributi onload/onerror:

<script>
    function handleLoad(e) {
    console.log('Loaded import: ' + e.target.href);
    }
    function handleError(e) {
    console.log('Error loading import: ' + e.target.href);
    }
</script>

<link rel="import" href="file.html"
        onload="handleLoad(event)" onerror="handleError(event)">

In alternativa, se stai creando l'importazione in modo dinamico:

var link = document.createElement('link');
link.rel = 'import';
// link.setAttribute('async', ''); // make it async!
link.href = 'file.html';
link.onload = function(e) {...};
link.onerror = function(e) {...};
document.head.appendChild(link);

Utilizzo dei contenuti

Includere un'importazione su una pagina non significa "copiare i contenuti di quel file qui". Significa "analista, esegui il recupero del documento in modo che io possa utilizzarlo". Per utilizzare effettivamente i contenuti, devi agire e scrivere lo script.

Un momento cruciale per aha! è il fatto che un'importazione è solo un documento. Infatti, il contenuto di un'importazione è chiamato documento di importazione. Sei in grado di manipolare le informazioni di un'importazione utilizzando le API DOM standard.

link.import

Per accedere ai contenuti di un'importazione, utilizza la proprietà .import dell'elemento link:

var content = document.querySelector('link[rel="import"]').import;

link.import è null alle seguenti condizioni:

  • Il browser non supporta le importazioni HTML.
  • <link> non ha rel="import".
  • <link> non è stato aggiunto al DOM.
  • <link> è stato rimosso dal DOM.
  • La risorsa non è abilitata per CORS.

Esempio completo

Supponiamo che warnings.html contenga:

<div class="warning">
    <style>
    h3 {
        color: red !important;
    }
    </style>
    <h3>Warning!
    <p>This page is under construction
</div>

<div class="outdated">
    <h3>Heads up!
    <p>This content may be out of date
</div>

Gli importatori possono recuperare una parte specifica di questo documento e clonarla nella propria pagina:

<head>
    <link rel="import" href="warnings.html">
</head>
<body>
    ...
    <script>
    var link = document.querySelector('link[rel="import"]');
    var content = link.import;

    // Grab DOM from warning.html's document.
    var el = content.querySelector('.warning');

    document.body.appendChild(el.cloneNode(true));
    </script>
</body>

Creazione di script nelle importazioni

Le importazioni non sono nel documento principale. Sono satellitari. Tuttavia, l'importazione può comunque funzionare sulla pagina principale anche se il documento principale ha la priorità. Un'importazione può accedere al proprio DOM e/o al DOM della pagina che la importa:

Esempio: import.html che aggiunge uno dei suoi fogli di stile alla pagina principale

<link rel="stylesheet" href="http://www.example.com/styles.css">
<link rel="stylesheet" href="http://www.example.com/styles2.css">

<style>
/* Note: <style> in an import apply to the main
    document by default. That is, style tags don't need to be
    explicitly added to the main document. */
#somecontainer {
color: blue;
}
</style>
...

<script>
// importDoc references this import's document
var importDoc = document.currentScript.ownerDocument;

// mainDoc references the main document (the page that's importing us)
var mainDoc = document;

// Grab the first stylesheet from this import, clone it,
// and append it to the importing document.
    var styles = importDoc.querySelector('link[rel="stylesheet"]');
    mainDoc.head.appendChild(styles.cloneNode(true));
</script>

Guarda cosa succede qui. Lo script all'interno dell'importazione fa riferimento al documento importato (document.currentScript.ownerDocument) e aggiunge parte di questo documento alla pagina di importazione (mainDoc.head.appendChild(...)). È un po' complicato se me lo chiedi.

Regole di JavaScript in un'importazione:

  • Lo script nell'importazione viene eseguito nel contesto della finestra che contiene l'elemento document di importazione. Quindi window.document si riferisce al documento della pagina principale. Ci sono due utili corollari:
    • funzioni definite in un'importazione finiscono in window.
    • non devi fare nulla di difficile come aggiungere i blocchi <script> dell'importazione alla pagina principale. Anche in questo caso, lo script viene eseguito.
  • Le importazioni non bloccano l'analisi della pagina principale. Tuttavia, gli script al loro interno vengono elaborati in ordine. Ciò significa che devi adottare un comportamento simile a quello del differimento, mantenendo al contempo l'ordine corretto per gli script. Continua a leggere per saperne di più.

Pubblicazione di componenti web

La struttura delle importazioni HTML si presta perfettamente al caricamento di contenuti riutilizzabili sul web. In particolare, è un modo ideale per distribuire i componenti web. Qualsiasi cosa, dagli elementi HTML <template> di base agli elementi personalizzati completi con Shadow DOM [1, 2, 3]. Quando queste tecnologie vengono utilizzate in tandem, le importazioni diventano una #include per i componenti web.

Inclusi i modelli

L'elemento Modello HTML è ideale per le importazioni HTML. <template> è ottimo per strutturare sezioni di markup che l'app di importazione può utilizzare come desidera. L'aggregazione di contenuti in un <template> offre inoltre il vantaggio aggiuntivo di rendere i contenuti inerti fino all'utilizzo. In altre parole, gli script non vengono eseguiti finché il modello non viene aggiunto al DOM). Super!

import.html

<template>
    <h1>Hello World!</h1>
    <!-- Img is not requested until the <template> goes live. -->
    <img src="world.png">
    <script>alert("Executed when the template is activated.");</script>
</template>
index.html

<head>
    <link rel="import" href="import.html">
</head>
<body>
    <div id="container"></div>
    <script>
    var link = document.querySelector('link[rel="import"]');

    // Clone the <template> in the import.
    var template = link.import.querySelector('template');
    var clone = document.importNode(template.content, true);

    document.querySelector('#container').appendChild(clone);
    </script>
</body>

Registrazione di elementi personalizzati

Elementi personalizzati è un'altra tecnologia di componenti web che funziona perfettamente con le importazioni HTML. Le importazioni possono eseguire lo script, quindi perché non definire e registrare i tuoi elementi personalizzati in modo che gli utenti non debbano farlo? Chiamala..." - registrazione automatica.

elements.html

<script>
    // Define and register <say-hi>.
    var proto = Object.create(HTMLElement.prototype);

    proto.createdCallback = function() {
    this.innerHTML = 'Hello, <b>' +
                        (this.getAttribute('name') || '?') + '</b>';
    };

    document.registerElement('say-hi', {prototype: proto});
</script>

<template id="t">
    <style>
    ::content > * {
        color: red;
    }
    </style>
    <span>I'm a shadow-element using Shadow DOM!</span>
    <content></content>
</template>

<script>
    (function() {
    var importDoc = document.currentScript.ownerDocument; // importee

    // Define and register <shadow-element>
    // that uses Shadow DOM and a template.
    var proto2 = Object.create(HTMLElement.prototype);

    proto2.createdCallback = function() {
        // get template in import
        var template = importDoc.querySelector('#t');

        // import template into
        var clone = document.importNode(template.content, true);

        var root = this.createShadowRoot();
        root.appendChild(clone);
    };

    document.registerElement('shadow-element', {prototype: proto2});
    })();
</script>

Questa importazione definisce (e registra) due elementi, <say-hi> e <shadow-element>. Il primo mostra un elemento personalizzato di base che si registra all'interno dell'importazione. Il secondo esempio mostra come implementare un elemento personalizzato che crea un DOM shadow da un <template> e poi si registra.

La parte migliore della registrazione di elementi personalizzati all'interno di un'importazione HTML è che l'importatore dichiara semplicemente l'elemento nella propria pagina. Non è necessario alcun cablaggio.

index.html

<head>
    <link rel="import" href="elements.html">
</head>
<body>
    <say-hi name="Eric"></say-hi>
    <shadow-element>
    <div>( I'm in the light dom )</div>
    </shadow-element>
</body>

Ritengo che questo flusso di lavoro da solo rende le importazioni HTML un modo ideale per condividere i componenti web.

Gestione di dipendenze e importazioni secondarie

Importazioni secondarie

Può essere utile che un'importazione ne includa un'altra. Ad esempio, se vuoi riutilizzare o estendere un altro componente, utilizza un'importazione per caricare gli altri elementi.

Di seguito è riportato un esempio reale di Polymer. È un nuovo componente della scheda (<paper-tabs>) che riutilizza un componente di layout e di selettore. Le dipendenze vengono gestite utilizzando le importazioni HTML.

paper-tabs.html (semplificato):

<link rel="import" href="iron-selector.html">
<link rel="import" href="classes/iron-flex-layout.html">

<dom-module id="paper-tabs">
    <template>
    <style>...</style>
    <iron-selector class="layout horizonta center">
        <content select="*"></content>
    </iron-selector>
    </template>
    <script>...</script>
</dom-module>

Gli sviluppatori di app possono importare questo nuovo elemento utilizzando:

<link rel="import" href="paper-tabs.html">
<paper-tabs></paper-tabs>

Quando in futuro arriverà un nuovo e più fantastico <iron-selector2>, puoi sostituire <iron-selector> e iniziare subito a utilizzarlo. Grazie alle importazioni e ai componenti web, i tuoi utenti non verranno danneggiati.

Gestione delle dipendenze

Sappiamo tutti che il caricamento di JQuery più di una volta per pagina causa errori. Questo non sarà un enorme problema per i componenti web quando più componenti utilizzano la stessa libreria? No se usiamo importazioni HTML. Possono essere utilizzati per gestire le dipendenze.

Eseguendo il wrapping delle librerie in un'importazione HTML, deduplica automaticamente le risorse. Il documento viene analizzato una sola volta. Gli script vengono eseguiti una sola volta. Ad esempio, supponiamo che tu definisca un'importazione, jquery.html, che carica una copia di JQuery.

jquery.html

<script src="http://cdn.com/jquery.js"></script>

Questa importazione può essere riutilizzata nelle importazioni successive, in questo modo:

import2.html

<link rel="import" href="jquery.html">
<div>Hello, I'm import 2</div>
ajax-element.html

<link rel="import" href="jquery.html">
<link rel="import" href="import2.html">

<script>
    var proto = Object.create(HTMLElement.prototype);

    proto.makeRequest = function(url, done) {
    return $.ajax(url).done(function() {
        done();
    });
    };

    document.registerElement('ajax-element', {prototype: proto});
</script>

Anche la pagina principale può includere jquery.html se ha bisogno della libreria:

<head>
    <link rel="import" href="jquery.html">
    <link rel="import" href="ajax-element.html">
</head>
<body>

...

<script>
    $(document).ready(function() {
    var el = document.createElement('ajax-element');
    el.makeRequest('http://example.com');
    });
</script>
</body>

Nonostante jquery.html sia incluso in molte strutture di importazione diverse, il documento viene recuperato ed elaborato solo una volta dal browser. L'esame del riquadro della rete prova che:

jquery.html viene richiesto una volta.
jquery.html è richiesto una volta

Considerazioni sul rendimento

Le importazioni HTML sono assolutamente fantastiche, ma, come con qualsiasi nuova tecnologia web, dovresti usarle con saggezza. Le best practice per lo sviluppo web sono ancora valide. Ecco alcuni aspetti da tenere presenti.

Concatena le importazioni

La riduzione delle richieste di rete è sempre importante. Se disponi di molti link di importazione di primo livello, valuta la possibilità di combinarli in un'unica risorsa e di importare il file.

Vulcanize è uno strumento di creazione npm del team Polymer che riunisce in modo ricorsivo un set di importazioni HTML in un unico file. È una procedura di creazione di concatenazione per i componenti web.

Le importazioni sfruttano la memorizzazione nella cache del browser

Molte persone dimenticano che lo stack di rete del browser è stato perfezionato nel corso degli anni. Anche le importazioni (e le importazioni secondarie) sfruttano questa logica. L'importazione http://cdn.com/bootstrap.html potrebbe includere risorse secondarie, che però verranno memorizzate nella cache.

I contenuti sono utili solo se li aggiungi

Pensa ai contenuti come inerti finché non fai ricorso ai relativi servizi. Utilizza un normale foglio di stile creato dinamicamente:

var link = document.createElement('link');
link.rel = 'stylesheet';
link.href = 'styles.css';

Il browser non richiederà stili.css finché link non verrà aggiunto al DOM:

document.head.appendChild(link); // browser requests styles.css

Un altro esempio è il markup creato dinamicamente:

var h2 = document.createElement('h2');
h2.textContent = 'Booyah!';

h2 è relativamente privo di significato finché non lo aggiungi al DOM.

Lo stesso concetto vale per il documento di importazione. Se non ne aggiungi i contenuti al DOM, l'operazione non è semplice. Infatti, l'unica cosa che viene "eseguita" direttamente nel documento di importazione è <script>. Consulta la sezione sullo scripting nelle importazioni.

Ottimizzazione per caricamento asincrono

Le importazioni bloccano il rendering

Importa il blocco del rendering della pagina principale. Questa operazione è simile a quella di <link rel="stylesheet">. Il motivo per cui il browser blocca il rendering sui fogli di stile è inizialmente di ridurre al minimo il FOUC. Le importazioni si comportano in modo simile poiché possono contenere fogli stilizzati.

Per essere completamente asincrono e non bloccare il parser o il rendering, utilizza l'attributo async:

<link rel="import" href="/path/to/import_that_takes_5secs.html" async>

Il motivo per cui async non è l'impostazione predefinita per le importazioni HTML perché richiede agli sviluppatori di lavorare di più. Per impostazione predefinita, sincrona significa che il caricamento e l'upgrade delle importazioni HTML contenenti definizioni di elementi personalizzati sono garantiti in ordine. In un mondo completamente asincrono, gli sviluppatori dovrebbero gestire da soli i tempi e migliorare i tempi.

Puoi anche creare un'importazione asincrona, in modo dinamico:

var l = document.createElement('link');
l.rel = 'import';
l.href = 'elements.html';
l.setAttribute('async', '');
l.onload = function(e) { ... };

Le importazioni non bloccano l'analisi

Le importazioni non bloccano l'analisi della pagina principale. Gli script all'interno delle importazioni vengono elaborati in ordine, ma non bloccano la pagina di importazione. Ciò significa che devi adottare un comportamento simile a quello del differimento, mantenendo al contempo l'ordine corretto per gli script. Uno dei vantaggi dell'importazione nell'elemento <head> è che consente al parser di iniziare a lavorare sui contenuti il prima possibile. Detto questo, è fondamentale ricordare che <script> nel documento principale continua ancora a bloccare la pagina. I primi <script> dopo un'importazione bloccheranno il rendering delle pagine. Questo perché un'importazione può contenere uno script che deve essere eseguito prima dello script nella pagina principale.

<head>
    <link rel="import" href="/path/to/import_that_takes_5secs.html">
    <script>console.log('I block page rendering');</script>
</head>

A seconda della struttura e del caso d'uso dell'app, esistono diversi modi per ottimizzare il comportamento asincrono. Le tecniche riportate di seguito riducono il blocco del rendering della pagina principale.

Scenario 1 (opzione preferita): non hai uno script in <head> o in <body>

Per il posizionamento di <script> ti consiglio di evitare di seguire immediatamente le importazioni. Sposta gli script il più tardi possibile nel gioco... ma stai già seguendo questa best practice, TU? ;)

Esempio:

<head>
    <link rel="import" href="/path/to/import.html">
    <link rel="import" href="/path/to/import2.html">
    <!-- avoid including script -->
</head>
<body>
    <!-- avoid including script -->

    <div id="container"></div>

    <!-- avoid including script -->
    ...

    <script>
    // Other scripts n' stuff.

    // Bring in the import content.
    var link = document.querySelector('link[rel="import"]');
    var post = link.import.querySelector('#blog-post');

    var container = document.querySelector('#container');
    container.appendChild(post.cloneNode(true));
    </script>
</body>

C'è tutto in fondo.

Scenario 1.5: l'importazione si aggiunge

Un'altra opzione è fare in modo che l'importazione aggiunga i propri contenuti. Se l'autore dell'importazione stabilisce un contratto che lo sviluppatore di app deve seguire, l'importazione può aggiungersi a un'area della pagina principale:

import.html:

<div id="blog-post">...</div>
<script>
    var me = document.currentScript.ownerDocument;
    var post = me.querySelector('#blog-post');

    var container = document.querySelector('#container');
    container.appendChild(post.cloneNode(true));
</script>
index.html

<head>
    <link rel="import" href="/path/to/import.html">
</head>
<body>
    <!-- no need for script. the import takes care of things -->
</body>

Scenario 2: hai script in <head> o incorporato in <body>

Se il caricamento di un'importazione richiede molto tempo, il primo <script> che la segue nella pagina impedirà il rendering della pagina. Ad esempio, Google Analytics consiglia di inserire il codice di monitoraggio nel <head>. Se non puoi evitare di inserire <script> nel <head>, l'aggiunta dinamica dell'importazione impedirà il blocco della pagina:

<head>
    <script>
    function addImportLink(url) {
        var link = document.createElement('link');
        link.rel = 'import';
        link.href = url;
        link.onload = function(e) {
        var post = this.import.querySelector('#blog-post');

        var container = document.querySelector('#container');
        container.appendChild(post.cloneNode(true));
        };
        document.head.appendChild(link);
    }

    addImportLink('/path/to/import.html'); // Import is added early :)
    </script>
    <script>
    // other scripts
    </script>
</head>
<body>
    <div id="container"></div>
    ...
</body>

In alternativa, aggiungi l'importazione verso la fine di <body>:

<head>
    <script>
    // other scripts
    </script>
</head>
<body>
    <div id="container"></div>
    ...

    <script>
    function addImportLink(url) { ... }

    addImportLink('/path/to/import.html'); // Import is added very late :(
    </script>
</body>

Da ricordare

  • Il tipo MIME di un'importazione è text/html.

  • Le risorse di altre origini devono essere abilitate per CORS.

  • Le importazioni dallo stesso URL vengono recuperate e analizzate una volta. Ciò significa che lo script di un'importazione viene eseguito solo la prima volta che viene visualizzata l'importazione.

  • Gli script di un'importazione vengono elaborati in ordine, ma non bloccano l'analisi del documento principale.

  • Un link di importazione non significa "#include the content here". Significa "analizzatore, vai al recupero di questo documento per poterlo utilizzare in seguito". Mentre gli script vengono eseguiti al momento dell'importazione, i fogli di stile, il markup e altre risorse devono essere aggiunti esplicitamente alla pagina principale. Nota: non è necessario aggiungere <style> in modo esplicito. Questa è un'importante differenza tra le importazioni HTML e <iframe>, che indica "carica e visualizza questi contenuti qui".

Conclusione

Le importazioni HTML consentono di raggruppare i file HTML/CSS/JS come singola risorsa. Sebbene sia utile di per sé, questa idea diventa estremamente potente nel mondo dei componenti web. Gli sviluppatori possono creare componenti riutilizzabili che altri possono utilizzare e importare nella propria app, il tutto tramite <link rel="import">.

Le importazioni HTML sono un concetto semplice, ma consentono una serie di casi d'uso interessanti per la piattaforma.

casi d'uso

  • Distribuisci HTML/CSS/JS come singolo bundle. In teoria, potresti importare un'intera app web in un'altra.
  • Organizzazione del codice: suddividi i concetti in modo logico in file diversi, incoraggiando la modularità e la riutilizzabilità**.
  • Pubblica una o più definizioni di elemento personalizzato. È possibile utilizzare un'importazione per register e includerli in un'app. Si tratta di pattern software validi, che mantengono l'interfaccia/definizione dell'elemento separata dal modo in cui viene utilizzato.
  • Gestisci le dipendenze: le risorse vengono deduplicate automaticamente.
  • Script Chunk: prima dell'importazione, una libreria JS di grandi dimensioni doveva analizzare completamente il proprio file per poter essere eseguita, il che era lento. Con le importazioni, la libreria può iniziare a funzionare non appena viene analizzato il blocco A. Meno latenza.
// TODO: DevSite - Code sample removed as it used inline event handlers
  • Parallelizza l'analisi HTML: la prima volta che il browser ha potuto eseguire due (o più) parser HTML in parallelo.

  • Consente di passare dalla modalità di debug a quella non di debug e viceversa in un'app, semplicemente modificando la destinazione dell'importazione stessa. Non è necessario che l'app sia in grado di sapere se la destinazione di importazione è una risorsa in bundle/compilata o una struttura di importazione.