Memanggil kode webpacked dari luar (tag skrip HTML)


130

Misalkan saya memiliki kelas seperti ini (ditulis dalam naskah) dan saya bundel dengan webpack bundle.js.

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

Dalam index.html saya, saya akan menyertakan bundel, tetapi kemudian saya juga ingin memanggil metode statis itu.

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

Namun, hal EntryPointini tidak terdefinisi dalam kasus ini. Bagaimana saya memanggil javascript yang dibundel dari skrip lain?

Ditambahkan : file konfigurasi Webpack .


Silakan tambahkan konfigurasi webpack Anda. Saya percaya bahwa ada sesuatu yang var EntryPoint = require('EntryPoint')hilang dalam onloadmetode Anda .
Martin Vseticka

2
@ Martin Vseticka saya telah menambahkan konfigurasi saya. Memang sesuatu seperti requiremungkin diperlukan tetapi sama dengan impor di bawah ini, katanya require is not defined. Apa yang saya coba lakukan adalah menggunakan konten yang dibundel dari javascript biasa, bukankah saya perlu kerangka kerja lagi untuk digunakan require? Tetapi saya berusaha menghindarinya. Semoga itu masuk akal.
Raven

Jawaban:


147

Tampaknya Anda ingin mengekspos bundel webpack sebagai pustaka . Anda dapat mengonfigurasi webpack untuk mengekspos pustaka Anda dalam konteks global di dalam variabel Anda sendiri, seperti EntryPoint.

Saya tidak tahu TypeScript jadi contohnya menggunakan JavaScript biasa. Tetapi yang penting di sini adalah file konfigurasi webpack, dan khususnya outputbagian:

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

Maka Anda akan dapat mengakses metode perpustakaan Anda seperti yang Anda harapkan:

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

Periksa intinya dengan kode aktual.


20
Kami memiliki beberapa titik masuk, jadi di bagian keluaran, saya malah membuatnya library: ["GlobalAccess", "[name]"],. Itu kemudian membuat var menjadi objek dengan anggota untuk setiap entri: GlobalAccess.EntryPointFoo, GlobalAccess.EntryPointBar, dll.
John Hatton

3
Ini berfungsi untuk nam run buildtetapi tidak bekerja di dev env menggunakan webpack-dev-server. EntryPoint saya yang diekspor adalah objek kosong. Ada ide?
nkint

1
bagaimana dengan situasi di mana entri: {page1: ['module1.js', 'module2.js'], page2: 'module3.js'} Saran @JohnHatton tampaknya tidak berfungsi saat itu. Saya mendapatkan akses ke page1.module2, tetapi tidak ke page1.module1. Sepertinya hanya mengambil yang terakhir.
sheamus

1
mengikuti langkah-langkah, mengubah konfigurasi, membangun kembali, tetapi masih mendapatkan ReferenceError:
EntryPoint

2
Saya mendapatkan contoh serupa untuk bekerja di babel + webpack v3.10.0 dengan mengubah index.js export function run() {}darimodule.exports = ...
dworvos

55

Saya berhasil menjalankan ini tanpa webpack.config.jsmodifikasi lebih lanjut , hanya dengan menggunakan importpernyataan yang saya panggil dari file utama / index.js saya:

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

masukkan deskripsi gambar di sini

Untuk referensi, ini weback.config.jsfile saya .

Awalnya saya mencoba menyelesaikan menggunakan yang sama require, namun ia ditugaskan pembungkus modul window.EntryPointsebagai lawan dari kelas yang sebenarnya.


3
Adakah yang bisa melakukan ini tanpa es6? Kalau tidak saya dapatkan Uncaught SyntaxError: Unexpected token import. Atau apakah Anda index.jsjuga dibundel (saya memang melihatnya sebagai titik masuk, tetapi tidak yakin)?
Raven

Ya, index.js dibundel juga - di situlah saya memasukkan pernyataan impor
Matt

3
Nah, Anda tahu, saya mencoba mengakses sesuatu yang dibundel dari skrip yang bukan milik bundel. Seperti bundel itu adalah perpustakaan dan saya akan mencoba mengakses metodenya dari luar. Apakah itu mungkin?
Raven

4
Solusi ini sangat sederhana dan saya malu pada diri saya sendiri karena tidak memikirkannya segera setelah masalah muncul.
cav_dan

1
Saya telah terjebak pada masalah ini selama berjam-jam. Hanya akan memindahkan script ke bundel saya tapi itu akan menyebabkan banyak masalah. Terima kasih atas jawaban yang sederhana !!
Stephen Agwu

14

Dalam keadaan saya, saya bisa memanggil fungsi dari dalam JavaScript yang dibundel dari skrip lain dengan menulis fungsi ke jendela saat membuatnya.

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

Saya tidak dapat menggunakan Babel jadi ini bekerja untuk saya.


Ini solusi yang sangat rapi.
Teoman shipahi

1

Saya memiliki tantangan serupa, saya ingin membuat bundel untuk beberapa halaman dalam perjalanan dan ingin setiap halaman memiliki titik masuknya sendiri ke dalam kode, dan tanpa bundel terpisah untuk setiap halaman.

Inilah pendekatan saya, yang sangat mirip dengan Kurt Williams tetapi dari sudut yang sedikit berbeda, juga tanpa mengubah konfigurasi 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

Lalu contoh bagaimana saya memanggil metode ini di akhir htmlhalaman:

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

0

WEBPACK.CONFIG.JS

1.MENGGUNAKAN 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. MENGGUNAKAN 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.Menggunakan AMD sebagai pustaka yang kami gunakan seperti (untuk mereka yang ingin membuat 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>
Dengan menggunakan situs kami, Anda mengakui telah membaca dan memahami Kebijakan Cookie dan Kebijakan Privasi kami.
Licensed under cc by-sa 3.0 with attribution required.