Wywołanie spakowanego kodu internetowego z zewnątrz (tag HTML script)

130

Załóżmy, że mam taką klasę (napisaną na maszynie) i dołączam ją do pakietu internetowego do bundle.js.

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

W moim index.html umieszczę pakiet, ale potem chciałbym również wywołać tę statyczną metodę.

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

Jednak EntryPointw tym przypadku jest niezdefiniowany. Jak mógłbym wtedy wywołać dołączony javascript z innego skryptu?

Dodano : plik konfiguracyjny Webpack .

Kruk
źródło
Dodaj konfigurację pakietu internetowego. Uważam, że var EntryPoint = require('EntryPoint')w twojej onloadmetodzie brakuje czegoś podobnego .
Martin Vseticka,
2
@MartinVseticka Dodałem konfigurację. Rzeczywiście, coś takiego requiremoże być konieczne, ale tak samo jak w przypadku importu poniżej, mówi require is not defined. To, co próbuję zrobić, to użyć dołączonej zawartości ze zwykłego javascript, czy nie potrzebowałbym ponownie jakiejś struktury require? Ale staram się tego uniknąć. Mam nadzieję, że to ma sens.
Raven

Odpowiedzi:

147

Wygląda na to, że chcesz udostępnić pakiet webpack jako bibliotekę . Możesz skonfigurować pakiet webpack, aby udostępnić swoją bibliotekę w kontekście globalnym w ramach własnej zmiennej, takiej jak EntryPoint.

Nie znam języka TypeScript, więc w przykładzie zastosowano zwykły JavaScript. Ale ważnym elementem jest tutaj plik konfiguracyjny pakietu internetowego, a konkretnie outputsekcja:

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

Wtedy będziesz mógł uzyskać dostęp do swoich metod bibliotecznych zgodnie z oczekiwaniami:

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

Sprawdź sedno faktycznego kodu.

dreyescat
źródło
20
Mamy wiele punktów wejścia, więc w sekcji wyjściowej zrobiłem to library: ["GlobalAccess", "[name]"],. To sprawia, że ​​zmienna staje się obiektem z elementami składowymi dla każdego punktu wejścia: GlobalAccess.EntryPointFoo, GlobalAccess.EntryPointBar itp.
John Hatton
3
Działa to, nam run buildale nie działa w przypadku używania środowiska deweloperskiego webpack-dev-server. Mój wyeksportowany EntryPoint jest pustym obiektem. Jakieś pomysły?
nkint
1
a co z sytuacją, w której wpis: {page1: ['module1.js', 'module2.js'], page2: 'module3.js'} @JohnHatton wydaje się wtedy nie działać. Mam dostęp do page1.module2, ale nie do page1.module1. Wydaje się, że zajmuje to ostatnie.
sheamus
1
wykonano kroki, zmieniono konfigurację, odbudowano, ale nadal nie można go złapać. Błąd referencyjny: EntryPoint nie jest zdefiniowany
user889030
2
Otrzymałem podobny przykład do pracy w babel + webpack v3.10.0, zmieniając index.js na export function run() {}frommodule.exports = ...
dworvos
55

Udało mi się to uruchomić bez żadnych dalszych webpack.config.jsmodyfikacji, po prostu używając importinstrukcji, którą wywołałem z mojego pliku main / index.js:

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

wprowadź opis obrazu tutaj

Dla odniesienia, oto mój weback.config.jsplik.

Początkowo próbowałem wykonać to samo użycie require, jednak przypisało to opakowanie modułu window.EntryPointw przeciwieństwie do rzeczywistej klasy.

Matt
źródło
3
Jest jakaś szansa na zrobienie tego bez es6? W przeciwnym razie otrzymam Uncaught SyntaxError: Unexpected token import. Czy też jest w index.jspakiecie (widzę to jako punkt wejścia, ale nie jestem pewien)?
Raven
Tak, plik index.js też jest spakowany - tam dołączyłem oświadczenie importu
Matt
3
Widzisz, próbuję uzyskać dostęp do czegoś, co jest w pakiecie ze skryptu, który nie należy do pakietu. Jakby pakiet był biblioteką i próbowałbym uzyskać dostęp do jej metod z zewnątrz. Czy to jest możliwe?
Raven
4
To rozwiązanie jest naprawdę proste i wstydzę się, że nie pomyślałem o tym, gdy tylko pojawił się problem.
cav_dan
1
Utknąłem na tym problemie godzinami. Chciałem tylko przenieść skrypt do mojego pakietu, ale spowodowałoby to o wiele więcej problemów. Dzięki za prostą odpowiedź !!
Stephen Agwu
14

W moich okolicznościach mogłem wywołać funkcję z pakietu JavaScript z innego skryptu, zapisując funkcję w oknie podczas jej tworzenia.

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

Nie mogłem używać Babel, więc to zadziałało.

Kurt William
źródło
To bardzo zgrabne rozwiązanie.
Teoman shipahi
1

Miałem podobne wyzwanie, chciałem stworzyć pakiet dla wielu stron w ramach podróży i chciałem, aby każda strona miała swój własny punkt wejścia do kodu i bez osobnego pakietu dla każdej strony.

Oto moje podejście, które jest bardzo podobne do Kurta Williamsa, ale z nieco innego punktu widzenia, również bez zmiany konfiguracji webpacka:

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

Następnie przykład, jak nazywam te metody na końcu htmlstrony:

<script src="/js/JourneyMaster.js"></script>
<script>window.landingPageInit();</script>
Darren Sweeney
źródło
0

WEBPACK.CONFIG.JS

1. KORZYSTANIE Z 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. UŻYWANIE 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. UŻYWANIE AMD jako biblioteki, której używamy (dla tych, którzy chcą zrobić lib)

define(['jquery', './aux-lib.js'], function ($) { ..(1).. });
ßãlãjî
źródło
-4

Załączniki:

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>
Veera Induvasi
źródło