代码之家  ›  专栏  ›  技术社区  ›  Thomas Sparber

使用模块系统从HTML调用typescript函数

  •  10
  • Thomas Sparber  · 技术社区  · 8 年前

    我想从HTML调用TypeScript(最终JavaScript)函数。问题是,我还想使用模块系统(systemjs、commonjs等)和webpack。

    以下是一个示例:

    实例ts:

    export class Example {
        myFunction() {
            alert('Test');
        }
    }
    

    示例2.ts:

    export function doSomething() {
        alert('Test2');
    }
    

    实例html:

    <html>
        <head>
            <script src="path/to/the/compiled/js/file.js"></script>
            <script>
                $(document).ready(function() {
                    $('#test-btn').click(function(){
                        var example = new Example(); //error1
                        example.myFunction();
                    });
                });
            </script>
        </head>
        <body>
            <button id="test-btn">Click me</button>
            <a href="javascript:doSomething()">Click me too</a> <!-- error2 -->
        </body>
    </html>
    

    错误注释指示错误发生的位置:由于使用了模块系统,因此找不到导出的类/函数。如果查看已编译的js文件,我可以看到类和函数声明放在一些模块函数中,因此它们无法从HTML访问。

    目前,我正在通过移动整个 $(document).ready... 节转换为TypeScript文件。但对于 <a href... 例如,我没有任何变通方法。

    所以我的最后一个问题是:是否真的可以从HTML调用TypeScript函数/类并使用模块系统?

    1 回复  |  直到 8 年前
        1
  •  11
  •   alechill    8 年前

    对webpack有两种支持此功能的方法

    1) 输出使用 library 选项这将把入口文件的导出写入所选全局范围内的命名空间变量

    myEntryFile。ts

    import {Example} from './example'
    import {doSomething} from './example2'
    
    export {
      Example,
      doSomething
    }
    

    网页包。配置。js公司

    output: {
      //... your normal output config her
      library: 'MyExposedNamespace'
    }
    

    现在可以在 window.MyExposedNamespace

    window.MyExposedNamespace.doSomething()
    const myExample = new window.MyExposedNamespace.Example()
    

    要获得更高级的使用,还可以通过以下方式更改命名空间应用于的范围 libraryTarget 所以不会污染全球范围

    2) 使用 expose-loader

    网页包。配置。js公司

    module: {
      rules: [
        { test: /example\.ts$/, 
          use: [
           { loader: 'expose-loader', options: 'Example'},
           'awesome-typescript-loader' // must transpile as file is typescript
          ]
        },
        { test: /example2\.ts$/, 
          use: [
            { loader: 'expose-loader', options: 'doSomeThing'},
            'awesome-typescript-loader'
          ]
        }
      ]
    }
    

    您还必须记住将这些文件导入项目中的某个位置,否则webpack将忽略它们。您不必实际使用它们,它只是用于webpack跟踪依赖项。最符合逻辑的地方是您的条目文件

    myEntryFile。ts

    import './example'
    import './example2'
    

    然后可以通过全局作用域调用它们(在浏览器中,这当然是 window )

    window.doSomeThing()
    const myExample = new window.Example()
    

    这一步可能会变得更加棘手,因为typescript转换步骤也需要在公开之前进行,这取决于您的其他配置,可能会比上面的简单版本更加复杂

    因此,我建议第一种解决方案是最简单的