Appel de code Webpack de l'extérieur (balise de script HTML)


130

Supposons que j'ai une classe comme celle-ci (écrite en manuscrit) et que je la intègre avec webpack dans bundle.js.

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

Dans mon index.html, j'inclurai le bundle, mais j'aimerais également appeler cette méthode statique.

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

Cependant, le EntryPointn'est pas défini dans ce cas. Comment puis-je appeler le javascript fourni à partir d'un autre script?

Ajouté : fichier de configuration Webpack .


Veuillez ajouter votre configuration Webpack. Je crois qu'il var EntryPoint = require('EntryPoint')manque quelque chose du genre dans votre onloadméthode.
Martin Vseticka

2
@MartinVseticka J'ai ajouté ma configuration. En effet, quelque chose comme requirepeut être nécessaire mais comme pour l'importation ci-dessous, dit-il require is not defined. Ce que j'essaie de faire, c'est d'utiliser du contenu groupé à partir de javascript simple, est-ce que je n'aurais pas besoin à nouveau d'un cadre pour l'utiliser require? Mais j'essaye d'éviter ça. J'espère que cela a du sens.
Raven

Réponses:


147

Il semble que vous souhaitiez exposer le bundle webpack en tant que bibliothèque . Vous pouvez configurer webpack pour exposer votre bibliothèque dans le contexte global dans une variable de votre choix, comme EntryPoint.

Je ne connais pas TypeScript, donc l'exemple utilise plutôt du JavaScript brut. Mais la pièce importante ici est le fichier de configuration du webpack, et plus précisément la outputsection:

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

Ensuite, vous pourrez accéder aux méthodes de votre bibliothèque comme vous le souhaitez:

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

Vérifiez l' essentiel avec le code réel.


20
Nous avons plusieurs points d'entrée, donc dans la section de sortie, je l'ai fait à la place library: ["GlobalAccess", "[name]"],. Cela fait ensuite de la var un objet avec des membres pour chaque point d'entrée: GlobalAccess.EntryPointFoo, GlobalAccess.EntryPointBar, etc.
John Hatton

3
Cela fonctionne nam run buildmais ne fonctionne pas dans dev env en utilisant webpack-dev-server. Mon EntryPoint exporté est un objet vide. Des idées?
nkint

1
qu'en est-il de la situation où l'entrée: {page1: ['module1.js', 'module2.js'], page2: 'module3.js'} @JohnHatton suggestion ne semble pas fonctionner alors. J'ai accès à page1.module2, mais pas à page1.module1. Il semble que ce soit juste le dernier.
sheamus

1
suivi des étapes, modification de la configuration, reconstruction, mais toujours non intercepté ReferenceError: EntryPoint is not defined
user889030

2
J'ai eu un exemple similaire pour travailler dans babel + webpack v3.10.0 en changeant index.js en export function run() {}demodule.exports = ...
dworvos

55

J'ai réussi à faire fonctionner cela sans aucune autre webpack.config.jsmodification, en utilisant simplement l' importinstruction que j'ai appelée à partir de mon fichier main / index.js:

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

entrez la description de l'image ici

Pour référence, voici mon weback.config.jsdossier.

Au départ, j'ai essayé d'accomplir la même chose en utilisant require, mais il a attribué le wrapper de module window.EntryPointpar opposition à la classe réelle.


3
Une chance de faire ça sans es6? Sinon, je reçois Uncaught SyntaxError: Unexpected token import. Ou est-ce que votre est index.jségalement fourni (je le vois comme un point d'entrée, mais pas sûr)?
Raven

Oui, index.js est également fourni - c'est là que j'ai inclus la déclaration d'importation
Matt

3
Eh bien, vous voyez, j'essaie d'accéder à quelque chose qui est groupé à partir d'un script qui n'appartient pas au bundle. Comme le bundle était une bibliothèque et j'essaierais d'accéder à ses méthodes de l'extérieur. Est-ce possible?
Raven

4
Cette solution est vraiment simple et j'ai honte de ne pas y penser dès que le problème est survenu.
cav_dan

1
J'étais coincé sur ce problème depuis des heures. J'allais juste déplacer le script dans mon bundle mais cela aurait causé beaucoup plus de problèmes. Merci pour la réponse simple !!
Stephen Agwu

14

Dans ma situation, j'ai pu appeler une fonction à partir du JavaScript fourni à partir d'un autre script en écrivant la fonction dans la fenêtre lors de sa création.

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

Je n'ai pas pu utiliser Babel donc cela a fonctionné pour moi.


C'est une solution très soignée.
Teoman shipahi

1

J'ai eu un défi similaire, je voulais créer un bundle pour plusieurs pages dans un voyage et je voulais que chaque page ait son propre point d'entrée dans le code, et sans bundle séparé pour chaque page.

Voici mon approche, qui est très similaire à Kurt Williams mais sous un angle légèrement différent, également sans changer la configuration du 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

Ensuite, un exemple de la façon dont j'appelle ces méthodes à la fin de la htmlpage:

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

0

WEBPACK.CONFIG.JS

1.UTILISER 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. UTILISATION DE 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.UTILISER AMD comme bibliothèque que nous utilisons comme (pour ceux qui veulent faire 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>
En utilisant notre site, vous reconnaissez avoir lu et compris notre politique liée aux cookies et notre politique de confidentialité.
Licensed under cc by-sa 3.0 with attribution required.