从外部调用 webpacked 代码(HTML 脚本标签)

IT技术 javascript html typescript webpack
2021-01-16 05:17:28

假设我有这样的类(用typescript编写)并将它与 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 配置文件

6个回答

似乎您想将 webpack bundle 作为library公开您可以配置 webpack 以在您自己的变量中的全局上下文中公开您的库,例如EntryPoint.

我不知道 TypeScript,所以这个例子使用了普通的 JavaScript。但这里重要的部分是 webpack 配置文件,特别是以下output部分:

webpack.config.js

module.exports = {
  entry: './index.js',
  output: {
    path: './lib',
    filename: 'yourlib.js',
    libraryTarget: 'var',
    library: 'EntryPoint'
  }
};

索引.js

module.exports = {
  run: function () {
    console.log('run from library');
  }
};

然后您将能够像您期望的那样访问您的库方法:

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

使用实际代码检查要点

通过将 index.js 更改为export function run() {}from,我得到了一个类似的示例,可以在 babel + webpack v3.10.0module.exports = ...
2021-03-22 05:17:28
那么 entry: { page1: [ 'module1.js', 'module2.js' ], page2: 'module3.js' } @JohnHatton 建议似乎不起作用的情况呢?我可以访问 page1.module2,但不能访问 page1.module1。似乎只需要最后一个。
2021-03-25 05:17:28
按照步骤,更改配置,重建它,但仍然未捕获 ReferenceError: EntryPoint is not defined
2021-03-27 05:17:28
这适用于nam run build但不适用于使用webpack-dev-server. 我导出的 EntryPoint 是一个空对象。有任何想法吗?
2021-03-29 05:17:28
我们有多个入口点,所以在输出部分,我改为创建它library: ["GlobalAccess", "[name]"],然后使 var 成为具有每个入口点成员的对象:GlobalAccess.EntryPointFoo、GlobalAccess.EntryPointBar 等。
2021-04-04 05:17:28

webpack.config.js通过简单地使用import我从 main/index.js 文件调用语句,我设法在没有任何进一步修改的情况下使其工作

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

在此处输入图片说明

作为参考,这是我的weback.config.js文件。

最初我尝试使用 完成相同的操作require,但是它分配了module包装器而window.EntryPoint不是实际的类。

这个解决方案真的很简单,我为自己没有在问题出现时立即考虑它而感到羞耻。
2021-03-14 05:17:28
是的,index.js 也被捆绑了 - 这就是我包含 import 语句的地方
2021-03-22 05:17:28
我已经被这个问题困住了几个小时。只是打算将脚本移到我的包中,但这会导致更多问题。谢谢你的简单回答!!
2021-03-24 05:17:28
没有 es6 有机会这样做吗?否则我得到Uncaught SyntaxError: Unexpected token import. 或者你的index.js也被捆绑了(我确实认为它是入口点,但不确定)?
2021-04-09 05:17:28
好吧,您看,我正在尝试访问从不属于该捆绑包的脚本中捆绑的内容。就像 bundle 是一个库,我会尝试从外部访问它的方法。那可能吗?
2021-04-11 05:17:28

在我的情况下,通过在创建窗口时将函数写入窗口,我能够从另一个脚本中的捆绑 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,所以这对我有用。

这是一个非常巧妙的解决方案。
2021-03-25 05:17:28

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

索引.html

<script src="dist/main.js"></script>
<script>
  window.onload = function () {
  rstate()=>{}
</script>

主文件

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

索引.html

<script>
  window.onload = function () {
  EntryPoint.rstate()=>{}
</script>

主文件

module.exports={
    rstate=function(){
        console.log("hi module")
    }
}

3.USING AMD as library we used like (for those who want to make lib)

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

我遇到了类似的挑战,我想为一个旅程中的多个页面创建一个包,并希望每个页面都有自己的代码入口点,并且每个页面没有单独的包。

这是我的方法,它与 Kurt Williams 非常相似,但角度略有不同,而且没有更改 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

然后是我如何在html页面末尾调用这些方法的示例

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