Chamando código da Web de fora (tag de script HTML)


130

Suponha que eu tenha uma classe como esta (escrita em texto datilografado) e a empacote com o webpack no bundle.js.

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

No meu index.html, incluirei o pacote, mas também gostaria de chamar esse método estático.

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

No entanto, o EntryPointé indefinido neste caso. Como eu chamaria o javascript incluído em outro script?

Adicionado : arquivo de configuração do Webpack .


Por favor, adicione sua configuração do webpack. Acredito que algo do tipo var EntryPoint = require('EntryPoint')está faltando no seu onloadmétodo.
Martin Vseticka

2
@MartinVseticka Adicionei minha configuração. De fato, algo como requirepode ser necessário, mas o mesmo que com a importação abaixo, diz ele require is not defined. O que estou tentando fazer é usar o conteúdo agrupado de javascript comum, não precisaria de alguma estrutura novamente para usar require? Mas estou tentando evitar isso. Espero que faça sentido.
Raven

Respostas:


147

Parece que você deseja expor o pacote configurável do webpack como uma biblioteca . Você pode configurar o webpack para expor sua biblioteca no contexto global em uma variável própria, como EntryPoint.

Eu não sei TypeScript, então o exemplo usa JavaScript simples. Mas a parte importante aqui é o arquivo de configuração do webpack e, especificamente, a outputseção:

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

Então, você poderá acessar os métodos da sua biblioteca como espera:

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

Verifique a essência com o código real.


20
Como temos vários pontos de entrada, na seção de saída, eu o fiz library: ["GlobalAccess", "[name]"],. Que, em seguida, fazer a var ser um objeto com os membros para cada ponto de entrada: GlobalAccess.EntryPointFoo, GlobalAccess.EntryPointBar, etc.
John Hatton

3
Isso funciona, nam run buildmas não funciona no dev env usando webpack-dev-server. Meu EntryPoint exportado é um objeto vazio. Alguma ideia?
Nkint

1
e a situação em que a entrada: {page1: ['module1.js', 'module2.js'], página2: 'module3.js'} A sugestão @JohnHatton parece não funcionar. Eu tenho acesso ao page1.module2, mas não ao page1.module1. Parece apenas levar o último.
Sheamus

1
etapas seguidas, alteração da configuração, reconstrução, mas ainda não foi detectado ReferenceError: EntryPoint não está definido
user889030

2
Eu recebi um exemplo semelhante ao trabalho em babel + Webpack v3.10.0 alterando index.js a export function run() {}partirmodule.exports = ...
dworvos

55

Consegui fazer isso funcionar sem mais webpack.config.jsmodificações, simplesmente usando a importinstrução que chamei do meu arquivo main / index.js:

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

insira a descrição da imagem aqui

Para referência, aqui está o meu weback.config.jsarquivo.

Inicialmente, tentei fazer o mesmo usando require, no entanto, ele atribuiu o invólucro do módulo ao window.EntryPointcontrário da classe real.


3
Alguma chance de fazer isso sem es6? Caso contrário, eu entendo Uncaught SyntaxError: Unexpected token import. Ou você index.jstambém está empacotado (eu o vejo como ponto de entrada, mas não tenho certeza)?
Raven

Sim, index.js é empacotado acima também - que é onde eu incluí a declaração de importação
Matt

3
Bem, veja bem, estou tentando acessar algo que está incluído em um script que não pertence ao pacote. Como se o pacote fosse uma biblioteca e eu tentasse acessar seus métodos de fora. Isso é possível?
Raven

4
Essa solução é realmente simples e tenho vergonha de não pensar nisso assim que o problema surgiu.
cav_dan

1
Eu estava preso nesse problema por horas. Iria apenas mover o script para o meu pacote, mas isso teria causado muito mais problemas. Obrigado pela resposta simples !!
Stephen Agwu

14

Na minha circunstância, consegui chamar uma função de dentro do JavaScript incluído em outro script, escrevendo a função na janela ao criá-la.

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

Eu não era capaz de usar Babel, então isso funcionou para mim.


Esta é uma solução muito elegante.
Teoman shipahi

1

Tive um desafio semelhante, queria criar um pacote para várias páginas em uma jornada e queria que cada página tivesse seu próprio ponto de entrada no código e sem um pacote separado para cada página.

Aqui está minha abordagem, que é muito semelhante a Kurt Williams, mas de um ângulo ligeiramente diferente, também sem alterar a configuração do 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

Em seguida, um exemplo de como eu chamo esses métodos no final da htmlpágina:

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

0

WEBPACK.CONFIG.JS

1. USANDO 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")
}
}

USANDO AMD como biblioteca que usamos como (para aqueles que querem criar 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>
Ao utilizar nosso site, você reconhece que leu e compreendeu nossa Política de Cookies e nossa Política de Privacidade.
Licensed under cc by-sa 3.0 with attribution required.