Виклик веб-упакованого коду ззовні (тег 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? Але я намагаюся цього уникати. Сподіваюся, це має сенс.
Ворон

Відповіді:


147

Здається, ви хочете виставити пакет веб-пакунків як бібліотеку . Ви можете налаштувати веб-пакет для викриття вашої бібліотеки в глобальному контексті в межах власної змінної, наприклад 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]"],. Тоді перетворення вару буде об’єктом з членами для кожної точки входу: GlobalAccess.EntryPointFoo, GlobalAccess.EntryPointBar тощо
Джон Хаттон,

3
Це працює, nam run buildале не працює у програмах dev env webpack-dev-server. Мій експортований EntryPoint - це порожній об’єкт. Будь-які ідеї?
nkint

1
як щодо ситуації, коли запис: {page1: ['module1.js', 'module2.js'], page2: 'module3.js'} @ пропозиція Джона Хеттона, здається, не працює. Я отримую доступ до page1.module2, але не до page1.module1. Здається, просто взяти останній.
sheamus

1
виконували кроки, змінювали конфігурацію, відновлювали її, але все-таки отримували незрозумілий ReferenceError: EntryPoint не визначено
user889030

2
Я отримав подібний приклад для роботи в babel + webpack v3.10.0, змінивши index.js на export function run() {}зmodule.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також в комплекті (я бачу це як пункт входу, але не впевнений)?
Ворон

Так, index.js також в комплекті - саме там я включив заяву про імпорт
Matt

3
Ну ви бачите, я намагаюся отримати доступ до чогось, що входить в комплект із сценарію, який не належить до групи. Як би в комплекті була бібліотека, і я б спробував отримати доступ до її методів ззовні. Це можливо?
Ворон

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.