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

Calling webpacked code from outside (HTML script tag)

假设我有这样的 class(用 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 config file

我设法在没有任何进一步 webpack.config.js 修改的情况下工作,只需使用我从 main/index.js 文件中调用的 import 语句:

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

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

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

您似乎想将 webpack 包公开为 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'
  }
};

index.js

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

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

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

用实际代码检查 gist

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>

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

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

这是我的方法,与 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>

WEBPACK.CONFIG.JS

1.USINGUMD

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.USING 变量

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 作为我们使用的库(对于那些想要制作 lib 的人)

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

到目前为止,许多答案都有效,只需要澄清 Webpack 在声明后构建之前不会识别该库。 您应该在创建库后立即使用 npm run build, 在继续使用 npm start.

之前

至少这对我来说是这样的,只使用 webpack。

也许这是我的冒名顶替综合症,但我认为 'real' 程序员会对我的回答感到畏缩。无论如何,我发现这个解决方案最适合我在业余爱好项目上的时间:

更改您的 JS 函数声明:

function renderValue(value) {

至:

global.renderValue = function(value) {

当然,您会像处理任何文件一样require('path/to/your_custom_js')

我在这里找到了这个答案: https://www.fastruby.io/blog/rails/webpack/from-sprockets-to-webpacker.html

我花了很长时间才弄明白,因为已接受的答案对我不起作用。只需确保函数名称与配置中的库相同,并且它与指定的配置捆绑在一起——npx webpack --config webpack.config.js --mode=development——希望这可以节省人们几个小时。

index.js(要绑定的函数)>>

function EntryPoint() {
    console.log('called from bundle');
}

module.exports = EntryPoint;

webpack.config.js >>

const path = require('path');

module.exports = {
    entry: './src/index.js',
    output: {
        filename: 'main.js',
        path: path.resolve(__dirname, 'dist'),
        libraryTarget: 'var',
        library: 'EntryPoint'
    },
};

start.html(调用绑定函数的地方)>>

<!DOCTYPE html>
<html lang="en">
  <head>
    <meta charset="utf-8">
    <title>Azure SDK Storage Example</title>
    <script type="text/javascript" src="./dist/main.js"></script>
  </head>
  <body>
      <h1>Azure SDK Storage Example</h1>
  </body>
</html>

<script>
 EntryPoint();
</script>