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.