Llamar a código webpacked desde afuera (etiqueta de script HTML)

130

Supongamos que tengo una clase como esta (escrita en mecanografiado) y la empaqueto con el paquete web bundle.js.

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

En mi index.html incluiré el paquete, pero también me gustaría llamar a ese método estático.

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

Sin embargo, el EntryPointno está definido en este caso. ¿Cómo llamaría al javascript incluido desde otro script entonces?

Agregado : archivo de configuración de Webpack .

Cuervo
fuente
Agregue la configuración de su paquete web. Creo que var EntryPoint = require('EntryPoint')falta algo en la línea de su onloadmétodo.
Martin Vseticka
2
@ MartinVseticka He agregado mi configuración. De hecho, algo así requirepodría ser necesario pero igual que con la importación a continuación, dice require is not defined. Lo que estoy tratando de hacer es usar contenido empaquetado de JavaScript simple, ¿no necesitaría algún marco nuevamente para usar require? Pero estoy tratando de evitar eso. Espero que tenga sentido.
Raven

Respuestas:

147

Parece que desea exponer el paquete webpack como una biblioteca . Puede configurar webpack para exponer su biblioteca en el contexto global dentro de una variable propia, como EntryPoint.

No conozco TypeScript, por lo que el ejemplo utiliza JavaScript simple. Pero la pieza importante aquí es el archivo de configuración del paquete web, y específicamente la outputsección:

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

Entonces podrá acceder a los métodos de su biblioteca como espera:

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

Verifique la esencia con el código real.

dreyescat
fuente
20
Tenemos múltiples puntos de entrada, así que en la sección de salida, en su lugar, lo hice library: ["GlobalAccess", "[name]"],. Eso hace que var sea un objeto con miembros para cada punto de entrada: GlobalAccess.EntryPointFoo, GlobalAccess.EntryPointBar, etc.
John Hatton
3
Esto funciona nam run buildpero no funciona en dev env usando webpack-dev-server. Mi EntryPoint exportado es un objeto vacío. ¿Algunas ideas?
nkint
1
¿qué pasa con la situación donde la entrada: {página1: ['module1.js', 'module2.js'], página2: 'module3.js'} @JohnHatton sugerencia no parece funcionar entonces. Tengo acceso a page1.module2, pero no a page1.module1. Parece que solo toma el último.
sheamus
1
seguí los pasos, cambié la configuración, la reconstruí, pero aún no he detectado ReferenceError: EntryPoint no está definido
user889030
2
Obtuve un ejemplo similar para trabajar en babel + webpack v3.10.0 al cambiar index.js export function run() {}demodule.exports = ...
dworvos el
55

Logré que esto funcionara sin más webpack.config.jsmodificaciones, simplemente usando la importdeclaración que llamé desde mi archivo main / index.js:

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

ingrese la descripción de la imagen aquí

Como referencia, aquí está mi weback.config.jsarchivo.

Inicialmente intenté lograr lo mismo usando require, sin embargo, asignó el contenedor del módulo window.EntryPointa la clase real.

Mate
fuente
3
¿Hay alguna posibilidad de hacer esto sin es6? De lo contrario lo entiendo Uncaught SyntaxError: Unexpected token import. ¿O index.jstambién está incluido (lo veo como punto de entrada, pero no estoy seguro)?
Cuervo
Sí, index.js también está incluido, ahí es donde he incluido la declaración de importación
Matt
3
Bueno, ya ves, estoy tratando de acceder a algo que está incluido en un script que no pertenece al paquete. Al igual que el paquete era una biblioteca y trataría de acceder a sus métodos desde el exterior. ¿Es eso posible?
Cuervo
44
Esta solución es realmente simple y me avergüenzo de mí mismo por no pensar en ello tan pronto como surgió el problema.
cav_dan
1
Había estado atrapado en este problema durante horas. Solo iba a mover el script a mi paquete, pero eso habría causado muchos más problemas. Gracias por la respuesta simple !!
Stephen Agwu
14

En mi caso, pude llamar a una función desde el JavaScript incluido desde otro script al escribir la función en la ventana al crearla.

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

No podía usar Babel, así que esto funcionó para mí.

Kurt William
fuente
Esta es una solución muy ordenada.
Teoman shipahi
1

Tuve un desafío similar, quería crear un paquete para varias páginas dentro de un viaje y quería que cada página tuviera su propio punto de entrada en el código, y sin un paquete separado para cada página.

Aquí está mi enfoque, que es muy similar a Kurt Williams pero desde un ángulo ligeramente diferente, también sin cambiar la configuración del paquete web:

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

Luego, un ejemplo de cómo llamo a estos métodos al final de la htmlpágina:

<script src="/js/JourneyMaster.js"></script>
<script>window.landingPageInit();</script>
Darren Sweeney
fuente
0

WEBPACK.CONFIG.JS

1.USO 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.USAR 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.USO DE AMD como biblioteca que usamos como (para aquellos que quieren hacer lib)

define(['jquery', './aux-lib.js'], function ($) { ..(1).. });
ßãlãjî
fuente
-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>
Veera Induvasi
fuente