Webpacked-Code von außen aufrufen (HTML-Skript-Tag)


130

Angenommen, ich habe eine Klasse wie diese (in Typoskript geschrieben) und bündle sie mit Webpack in bundle.js.

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

In meine index.html werde ich das Bundle aufnehmen, aber dann möchte ich auch diese statische Methode aufrufen.

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

Das EntryPointist in diesem Fall jedoch undefiniert. Wie würde ich dann das gebündelte Javascript aus einem anderen Skript aufrufen?

Hinzugefügt : Webpack-Konfigurationsdatei .


Bitte fügen Sie Ihre Webpack-Konfiguration hinzu. Ich glaube, dass etwas in der Art von var EntryPoint = require('EntryPoint')in Ihrer onloadMethode fehlt .
Martin Vseticka

2
@MartinVseticka Ich habe meine Konfiguration hinzugefügt. In der Tat requirekönnte so etwas notwendig sein, aber dasselbe wie beim Import unten, heißt es require is not defined. Ich versuche, gebündelte Inhalte aus einfachem Javascript zu verwenden. Würde ich nicht erneut ein Framework benötigen, um es zu verwenden require? Aber ich versuche das zu vermeiden. Hoffe es macht Sinn.
Raven

Antworten:


147

Es scheint, dass Sie das Webpack-Bundle als Bibliothek verfügbar machen möchten . Sie können das Webpack so konfigurieren, dass Ihre Bibliothek im globalen Kontext innerhalb einer eigenen Variablen verfügbar gemacht wird EntryPoint.

Ich kenne TypeScript nicht, daher verwendet das Beispiel stattdessen einfaches JavaScript. Das wichtigste Element hierbei ist jedoch die Webpack-Konfigurationsdatei und insbesondere der outputAbschnitt:

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');
  }
};

Dann können Sie wie erwartet auf Ihre Bibliotheksmethoden zugreifen:

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

Überprüfen Sie das Wesentliche mit dem tatsächlichen Code.


20
Wir haben mehrere Einstiegspunkte, also habe ich es im Ausgabeabschnitt stattdessen gemacht library: ["GlobalAccess", "[name]"],. Das macht die Variable dann zu einem Objekt mit Mitgliedern für jeden Einstiegspunkt: GlobalAccess.EntryPointFoo, GlobalAccess.EntryPointBar usw.
John Hatton

3
Dies funktioniert für nam run builddev env using, funktioniert jedoch nicht webpack-dev-server. Mein exportierter EntryPoint ist ein leeres Objekt. Irgendwelche Ideen?
nkint

1
Was ist mit der Situation, in der der Eintrag: {page1: ['module1.js', 'module2.js'], page2: 'module3.js'} @ JohnHatton-Vorschlag dann nicht zu funktionieren scheint. Ich bekomme Zugriff auf page1.module2, aber nicht auf page1.module1. Es scheint nur den letzten zu dauern.
Sheamus

1
Schritte befolgt, Konfiguration geändert, neu erstellt, aber immer noch nicht erfasst ReferenceError: EntryPoint ist nicht definiert
user889030

2
Ich habe ein ähnliches Beispiel für die Arbeit in Babel + Webpack v3.10.0 erhalten, indem ich index.js in export function run() {}frommodule.exports = ...
dworvos

55

Ich habe es geschafft, dies ohne weitere webpack.config.jsÄnderungen zum importLaufen zu bringen , indem ich einfach die Anweisung verwendet habe, die ich aus meiner Datei main / index.js aufgerufen habe:

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

Geben Sie hier die Bildbeschreibung ein

Als Referenz ist hier meine weback.config.jsDatei.

Anfangs habe ich versucht, dasselbe mit zu erreichen require, aber es hat den Modul-Wrapper window.EntryPointim Gegensatz zur eigentlichen Klasse zugewiesen .


3
Gibt es eine Chance, dies ohne es6 zu tun? Sonst bekomme ich Uncaught SyntaxError: Unexpected token import. Oder ist Ihr index.jsauch gebündelt (ich sehe es als Einstiegspunkt, bin mir aber nicht sicher)?
Raven

Ja, index.js ist auch gebündelt - dort habe ich die Importanweisung eingefügt
Matt

3
Sie sehen, ich versuche, auf etwas zuzugreifen, das über ein Skript gebündelt ist, das nicht zum Bundle gehört. Als wäre das Bundle eine Bibliothek und ich würde versuchen, von außen auf ihre Methoden zuzugreifen. Ist das möglich?
Raven

4
Diese Lösung ist wirklich einfach und ich schäme mich dafür, dass ich nicht darüber nachgedacht habe, sobald das Problem aufgetreten ist.
cav_dan

1
Ich war stundenlang mit diesem Problem beschäftigt. Ich wollte das Skript nur in mein Bundle verschieben, aber das hätte ein paar weitere Probleme verursacht. Danke für die einfache Antwort !!
Stephen Agwu

14

Unter meinen Umständen konnte ich eine Funktion aus dem gebündelten JavaScript aus einem anderen Skript aufrufen, indem ich die Funktion beim Erstellen in das Fenster schrieb.

// 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>

Ich konnte Babel nicht benutzen, also funktionierte das für mich.


Dies ist eine sehr saubere Lösung.
Teoman Shipahi

1

Ich hatte eine ähnliche Herausforderung: Ich wollte ein Bundle für mehrere Seiten innerhalb einer Reise erstellen und wollte, dass jede Seite einen eigenen Einstiegspunkt in den Code hat und kein separates Bundle für jede Seite.

Hier ist mein Ansatz, der Kurt Williams sehr ähnlich ist, aber aus einem etwas anderen Blickwinkel, auch ohne die Webpack-Konfiguration zu ändern:

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

Dann ein Beispiel, wie ich diese Methoden am Ende des aufrufe html Seite aufrufe:

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

0

WEBPACK.CONFIG.JS

1. UMD VERWENDEN

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.VAR VERWENDEN

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. AMD als Bibliothek verwenden, die wir mögen (für diejenigen, die lib machen wollen)

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>
Durch die Nutzung unserer Website bestätigen Sie, dass Sie unsere Cookie-Richtlinie und Datenschutzrichtlinie gelesen und verstanden haben.
Licensed under cc by-sa 3.0 with attribution required.