Вызов веб-кода извне (тег HTML-скрипта)


130

Предположим, у меня есть такой класс (написанный на машинописном тексте), и я связываю его с webpack в bundle.js.

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

В свой index.html я включу пакет, но затем я также хотел бы вызвать этот статический метод.

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

Однако EntryPointв этом случае не определено. Как тогда мне вызвать связанный javascript из другого скрипта?

Добавлено : конфигурационный файл Webpack .


Пожалуйста, добавьте конфигурацию вашего веб-пакета. Я считаю, что var EntryPoint = require('EntryPoint')в вашем onloadметоде чего-то не хватает .
Мартин Всетицка

2
@MartinVseticka Я добавил свой конфиг. Действительно, requireможет потребоваться что-то вроде , но такое же, как с импортом ниже, говорится в нем require is not defined. Я пытаюсь использовать объединенный контент из простого javascript, не понадобится ли мне снова использовать какой-то фреймворк require? Но я пытаюсь этого избежать. Надеюсь, это имеет смысл.
Raven

Ответы:


147

Похоже, вы хотите выставить пакет webpack как библиотеку . Вы можете настроить webpack для отображения вашей библиотеки в глобальном контексте внутри вашей собственной переменной, например EntryPoint.

Я не знаю TypeScript, поэтому вместо этого в примере используется простой JavaScript. Но важной частью здесь является файл конфигурации веб-пакета, и в частности outputраздел:

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

Тогда вы сможете получить доступ к методам своей библиотеки, как вы ожидаете:

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

Проверьте суть с реальным кодом.


20
У нас есть несколько точек входа, поэтому я сделал это в разделе вывода library: ["GlobalAccess", "[name]"],. Затем это делает var объектом с членами для каждой точки входа: GlobalAccess.EntryPointFoo, GlobalAccess.EntryPointBar и т. Д.
Джон Хаттон,

3
Это работает, nam run buildно не работает в dev env using webpack-dev-server. Моя экспортированная EntryPoint - пустой объект. Любые идеи?
nkint

1
как насчет ситуации, когда запись: {page1: ['module1.js', 'module2.js'], page2: 'module3.js'}, предложение @JohnHatton, похоже, не работает. Я получаю доступ к page1.module2, но не к page1.module1. Вроде как раз взял последний.
sheamus

1
выполнил шаги, изменил конфигурацию, перестроил ее, но все еще не
перехватывал

2
Я получил аналогичный пример для работы в babel + webpack v3.10.0, изменив index.js на export function run() {}frommodule.exports = ...
dworvos

55

Мне удалось заставить это работать без каких-либо дальнейших webpack.config.jsизменений, просто используя importоператор, который я вызвал из моего файла main / index.js:

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

введите описание изображения здесь

Для справки вот мой weback.config.jsфайл.

Первоначально я пытался сделать то же самое с помощью require, однако он назначил оболочку модуля, window.EntryPointа не фактический класс.


3
Есть ли шанс сделать это без es6? В противном случае я получу Uncaught SyntaxError: Unexpected token import. Или у вас index.jsтоже есть пакет (я вижу это как точку входа, но не уверен)?
Raven

Да, index.js тоже входит в комплект - туда я включил оператор импорта
Мэтт

3
Видите ли, я пытаюсь получить доступ к чему-то, что связано с пакетом, который не принадлежит этому пакету. Как будто пакет был библиотекой, и я бы попытался получить доступ к ее методам извне. Это возможно?
Raven

4
Это решение действительно простое, и мне стыдно за то, что я не подумал об этом, как только возникла проблема.
cav_dan

1
Я зацикливался на этой проблеме несколько часов. Я просто собирался переместить скрипт в свой пакет, но это вызвало бы кучу дополнительных проблем. Спасибо за простой ответ !!
Стивен Агву

14

В моих обстоятельствах я смог вызвать функцию из связанного JavaScript из другого скрипта, записав функцию в окно при его создании.

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

Я не мог использовать Babel, поэтому у меня это сработало.


Это очень изящное решение.
Теоман Шипахи

1

У меня была аналогичная задача: я хотел создать пакет для нескольких страниц в рамках путешествия и хотел, чтобы каждая страница имела собственную точку входа в код и без отдельного пакета для каждой страницы.

Вот мой подход, который очень похож на Курта Уильямса, но под немного другим углом, также без изменения конфигурации веб-пакета:

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

Затем пример того, как я вызываю эти методы в конце htmlстраницы:

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

0

WEBPACK.CONFIG.JS

1. ИСПОЛЬЗОВАНИЕ 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. ИСПОЛЬЗОВАНИЕ 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. ИСПОЛЬЗОВАНИЕ AMD в качестве библиотеки, которую мы используем как (для тех, кто хочет сделать 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>
Используя наш сайт, вы подтверждаете, что прочитали и поняли нашу Политику в отношении файлов cookie и Политику конфиденциальности.
Licensed under cc by-sa 3.0 with attribution required.