Gọi mã webpacked từ bên ngoài (thẻ script HTML)


130

Giả sử rằng tôi có lớp như thế này (được viết bằng bản in) và tôi gói nó với webpack vào bundle.js.

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

Trong index.html của tôi, tôi sẽ bao gồm gói, nhưng sau đó tôi cũng muốn gọi phương thức tĩnh đó.

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

Tuy nhiên, EntryPointkhông xác định trong trường hợp này. Làm thế nào tôi có thể gọi javascript được đóng gói từ một tập lệnh khác sau đó?

Đã thêm : Tập tin cấu hình Webpack .


Vui lòng thêm cấu hình webpack của bạn. Tôi tin rằng một cái gì đó dọc theo dòng var EntryPoint = require('EntryPoint')bị thiếu trong onloadphương pháp của bạn .
Martin Vseticka

2
@MartinVseticka Tôi đã thêm cấu hình của mình. Thật vậy, một cái gì đó như requirecó thể là cần thiết nhưng giống như nhập khẩu dưới đây, nó nói require is not defined. Những gì tôi đang cố gắng làm là sử dụng nội dung được đóng gói từ javascript đơn giản, tôi có cần sử dụng lại một số khung công tác requirekhông? Nhưng tôi đang cố tránh điều đó. Hy vọng nó có ý nghĩa.
Quạ

Câu trả lời:


147

Có vẻ như bạn muốn trưng bày gói webpack dưới dạng thư viện . Bạn có thể định cấu hình gói web để hiển thị thư viện của mình trong bối cảnh toàn cầu trong một biến của riêng bạn, như thế EntryPoint.

Tôi không biết TypeScript nên ví dụ này sử dụng JavaScript đơn giản. Nhưng phần quan trọng ở đây là tệp cấu hình webpack, và cụ thể là outputphần:

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

Sau đó, bạn sẽ có thể truy cập các phương thức thư viện của mình như bạn mong đợi:

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

Kiểm tra ý chính với mã thực tế.


20
Chúng tôi có nhiều điểm vào, vì vậy trong phần đầu ra, thay vào đó tôi đã thực hiện nó library: ["GlobalAccess", "[name]"],. Điều đó sau đó làm cho var trở thành một đối tượng với các thành viên cho mỗi điểm vào: GlobalAccess.EntryPointFoo, GlobalAccess.EntryPointBar, v.v.
John Hatton

3
Điều này làm việc cho nam run buildnhưng không hoạt động trong dev env sử dụng webpack-dev-server. Entrypoint đã xuất của tôi là một đối tượng trống. Có ý kiến ​​gì không?
nkint

1
Điều gì về tình huống mà mục nhập: {page1: ['module1.js', 'module2.js'], page2: 'module3.js'} @JohnHatton đề xuất dường như không hoạt động sau đó. Tôi có quyền truy cập vào page1.module2, nhưng không truy cập page1.module1. Nó dường như chỉ mất cái cuối cùng.
sheamus

1
đã làm theo các bước, thay đổi cấu hình, xây dựng lại nó, nhưng vẫn chưa được tham
khảoError: Entrypoint

2
Tôi đã nhận được một ví dụ tương tự để làm việc trong babel + webpack v3.10.0 bằng cách thay đổi index.js thành export function run() {}từmodule.exports = ...
dworvos

55

Tôi đã quản lý để làm việc này mà không cần webpack.config.jssửa đổi gì thêm , chỉ bằng cách sử dụng importcâu lệnh mà tôi đã gọi từ tệp main / index.js của mình:

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

nhập mô tả hình ảnh ở đây

Để tham khảo, đây là weback.config.jstập tin của tôi .

Ban đầu tôi đã thử hoàn thành việc sử dụng tương tự require, tuy nhiên nó đã gán trình bao bọc mô-đun window.EntryPointtrái ngược với lớp thực tế.


3
Bất kỳ cơ hội làm điều này mà không có es6? Nếu không thì tôi nhận được Uncaught SyntaxError: Unexpected token import. Hoặc là bạn index.jscũng bị bó (tôi thấy nó là điểm vào, nhưng không chắc chắn)?
Quạ

Vâng, index.js cũng được gói lại - đó là nơi tôi đã bao gồm câu lệnh nhập khẩu
Matt

3
Bạn thấy đấy, tôi đang cố gắng truy cập một cái gì đó được gói từ một tập lệnh không thuộc về gói. Giống như gói là một thư viện và tôi sẽ cố gắng truy cập các phương thức của nó từ bên ngoài. Điều đó có thể không?
Quạ

4
Giải pháp này thực sự đơn giản và tôi xấu hổ vì đã không nghĩ về nó ngay khi vấn đề phát sinh.
cav_dan

1
Tôi đã bị mắc kẹt trong vấn đề này trong nhiều giờ. Chỉ là sẽ chuyển kịch bản vào gói của tôi nhưng điều đó sẽ gây ra nhiều vấn đề hơn. Cảm ơn câu trả lời đơn giản !!
Stephen Agwu

14

Trong trường hợp của mình, tôi đã có thể gọi một hàm từ bên trong JavaScript được gói từ một tập lệnh khác bằng cách viết hàm vào cửa sổ khi tạo nó.

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

Tôi đã không thể sử dụng Babel vì vậy điều này làm việc cho tôi.


Đây là giải pháp rất gọn gàng.
Teoman shipahi

1

Tôi đã có một thử thách tương tự, tôi muốn tạo một gói cho nhiều trang trong một hành trình và muốn mỗi trang có điểm nhập riêng vào mã và không có gói riêng cho mỗi trang.

Đây là cách tiếp cận của tôi, rất giống với Kurt Williams nhưng từ một góc độ hơi khác, cũng không thay đổi cấu hình 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

Sau đó, một ví dụ về cách tôi gọi các phương thức này ở cuối htmltrang:

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

0

WEBPACK.CONFIG.JS

1. KIẾM 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")
}

VÒI

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.USING AMD là thư viện chúng tôi sử dụng như thế (đối với những người muốn tạo lib)

define(['jquery', './aux-lib.js'], function ($) { ..(1).. });

-4

Ứng dụng:

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>
Khi sử dụng trang web của chúng tôi, bạn xác nhận rằng bạn đã đọc và hiểu Chính sách cookieChính sách bảo mật của chúng tôi.
Licensed under cc by-sa 3.0 with attribution required.