Richiamo del codice Webpacked dall'esterno (tag script HTML)


130

Supponiamo di avere una classe come questa (scritta in dattiloscritto) e di raggrupparla con webpack in bundle.js.

export class EntryPoint {
    static run() {
        ...
    }
}

Nel mio index.html includerò il bundle, ma poi vorrei anche chiamare quel metodo statico.

<script src="build/bundle.js"></script>
<script>
    window.onload = function() {
        EntryPoint.run();
    }
</script>

Tuttavia, EntryPointin questo caso non è definito. Come chiamerei il javascript in bundle da un altro script allora?

Aggiunto : file di configurazione Webpack .


Aggiungi la tua configurazione webpack. Credo che var EntryPoint = require('EntryPoint')manchi qualcosa del genere nel tuo onloadmetodo.
Martin Vseticka,

2
@MartinVseticka Ho aggiunto la mia configurazione. In effetti qualcosa di simile requirepotrebbe essere necessario ma uguale a quello con l'importazione di seguito, dice require is not defined. Quello che sto cercando di fare è utilizzare il contenuto in bundle da javascript semplice, non avrei bisogno di utilizzare nuovamente un framework require? Ma sto cercando di evitarlo. Spero abbia senso.
Raven,

Risposte:


147

Sembra che tu voglia esporre il bundle webpack come libreria . Puoi configurare il webpack per esporre la tua libreria nel contesto globale all'interno di una tua variabile, ad esempio EntryPoint.

Non conosco TypeScript, quindi l'esempio usa JavaScript semplice. Ma il pezzo importante qui è il file di configurazione del webpack, e in particolare la outputsezione:

webpack.config.js

module.exports = {
  entry: './index.js',
  output: {
    path: './lib',
    filename: 'yourlib.js',
    libraryTarget: 'var',
    library: 'EntryPoint'
  }
};

index.js

module.exports = {
  run: function () {
    console.log('run from library');
  }
};

Quindi sarai in grado di accedere ai tuoi metodi di libreria come ti aspetti:

<script src="lib/yourlib.js"></script>
<script>
  window.onload = function () {
    EntryPoint.run();
  };
</script>

Controlla l' essenza con il codice attuale.


20
Abbiamo più punti di ingresso, quindi nella sezione di output l'ho invece creato library: ["GlobalAccess", "[name]"],. Ciò rende quindi il var un oggetto con membri per ogni punto di entrata: GlobalAccess.EntryPointFoo, GlobalAccess.EntryPointBar, ecc.
John Hatton,

3
Questo funziona per nam run buildma non funziona con dev env utilizzando webpack-dev-server. Il mio EntryPoint esportato è un oggetto vuoto. Qualche idea?
nkint,

1
per quanto riguarda la situazione in cui la voce: {page1: ['module1.js', 'module2.js'], page2: 'module3.js'} Il suggerimento @JohnHatton non sembra funzionare allora. Ottengo l'accesso a page1.module2, ma non a page1.module1. Sembra prendere solo l'ultimo.
sheamus,

1
ha seguito i passaggi, modificato la configurazione, ricostruita, ma ancora non rilevata ReferenceError: EntryPoint non definito
user889030

2
Ho ottenuto un esempio simile per lavorare in babel + webpack v3.10.0 cambiando index.js a export function run() {}damodule.exports = ...
dworvos

55

Sono riuscito a farlo funzionare senza ulteriori webpack.config.jsmodifiche, semplicemente usando la importdichiarazione che ho chiamato dal mio file principale / index.js:

import EntryPoint from './EntryPoint.js';
window.EntryPoint = EntryPoint;

inserisci qui la descrizione dell'immagine

Per riferimento, ecco il mio weback.config.jsfile.

Inizialmente ho provato a ottenere lo stesso risultato require, tuttavia ha assegnato il wrapper del modulo window.EntryPointrispetto alla classe effettiva.


3
Qualche possibilità di farlo senza es6? Altrimenti lo capisco Uncaught SyntaxError: Unexpected token import. O è index.jsanche il tuo bundle (lo vedo come punto di ingresso, ma non sono sicuro)?
Raven,

Sì, anche index.js è raggruppato - è lì che ho incluso la dichiarazione di importazione
Matt

3
Bene, vedi, sto provando ad accedere a qualcosa che è raggruppato da uno script che non appartiene al pacchetto. Come se il bundle fosse una libreria e proverei ad accedere ai suoi metodi dall'esterno. È possibile?
Raven,

4
Questa soluzione è davvero semplice e mi vergogno di me stesso per non pensarci non appena si è presentato il problema.
cav_dan,

1
Ero stato bloccato su questo problema per ore. Stavo per spostare la sceneggiatura nel mio pacchetto, ma ciò avrebbe causato molti più problemi. Grazie per la semplice risposta !!
Stephen Agwu,

14

Nella mia circostanza sono stato in grado di chiamare una funzione dall'interno del JavaScript in bundle da un altro script scrivendo la funzione nella finestra durante la creazione.

// In the bundled script:
function foo() {
    var modal = document.createElement('div');
}
// Bind to the window
window.foo = foo;
// Then, in the other script where I want to reference the bundled function I just call it as a normal function
<button onClick="window.foo()">Click Me</button>

Non sono stato in grado di usare Babel, quindi questo ha funzionato per me.


Questa è una soluzione molto accurata.
Teoman Shipahi,

1

Ho avuto una sfida simile, volevo creare un pacchetto per più pagine all'interno di un viaggio e volevo che ogni pagina avesse il proprio punto di ingresso nel codice e senza un pacchetto separato per ogni pagina.

Ecco il mio approccio, che è molto simile a Kurt Williams ma da un'angolazione leggermente diversa, anche senza cambiare la configurazione del webpack:

JourneyMaster.js

import { getViewData } from './modules/common';
import { VIEW_DATA_API_URL } from './modules/constants';
import { createLandingPage, createAnotherPage } from './modules/components/pageBuilder';

window.landingPageInit = () => {
    getViewData(VIEW_DATA_API_URL).then(viewData => {
        createLandingPage(viewData);
    });
};

window.anotherPageInit = () => {
    getViewData(VIEW_DATA_API_URL).then(viewData => {
        createAnotherPage(viewData);
    });
};

// I appreciate the above could be one liners,
// but readable at a glance is important to me

Quindi un esempio di come chiamo questi metodi alla fine della htmlpagina:

<script src="/js/JourneyMaster.js"></script>
<script>window.landingPageInit();</script>

0

WEBPACK.CONFIG.JS

1.USD UMD

module.exports={
            mode:'development',
            entry:'./yourentry.js',
            output:{
            path:path.resolve(__dirname,"dist"),
            filename:'main.js',
            publicPath:'/dist/',
            libraryTarget:'umd', 
            library:'rstate',
            umdNamedDefine: true,
            libraryExport: 'default' 
        }
    }

index.html

<script src="dist/main.js"></script>
<script>
  window.onload = function () {
  rstate()=>{}
</script>

main.js

export default function rstate(){
console.log("i called from html")
}

2. USARE VAR

module.exports={
            mode:'development',
            entry:'./yourentry.js',
            output:{
            path:path.resolve(__dirname,"dist"),
            filename:'main.js',
            publicPath:'/dist/',
            libraryTarget:'var', 
            library: 'EntryPoint'
        }
    }

index.html

<script>
  window.onload = function () {
  EntryPoint.rstate()=>{}
</script>

main.js

module.exports={
rstate=function(){
console.log("hi module")
}
}

3. USANDO AMD come libreria che usiamo come (per coloro che vogliono creare lib)

define(['jquery', './aux-lib.js'], function ($) { ..(1).. });

-4

App.ts:

namespace mytypescript.Pages {

        export class Manage {

     public Initialise() {
     $("#btnNewActivity").click(() => {
                    alert("sdc'");
                });
        }
    }
}

mypage.html:

 <input class="button" type="button" id="btnNewActivity" value="Register New Activity" />

 <script type="text/javascript">
    var page = new mytypescript.Pages.Manage();
    page.Initialise();
</script>
Utilizzando il nostro sito, riconosci di aver letto e compreso le nostre Informativa sui cookie e Informativa sulla privacy.
Licensed under cc by-sa 3.0 with attribution required.