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

Tho*_*ber 9 html javascript commonjs typescript systemjs

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

这是一个例子:

example.ts:

export class Example {
    myFunction() {
        alert('Test');
    }
}
Run Code Online (Sandbox Code Playgroud)

example2.ts:

export function doSomething() {
    alert('Test2');
}
Run Code Online (Sandbox Code Playgroud)

example.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>
Run Code Online (Sandbox Code Playgroud)

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

目前我通过将整个$(document).ready...部分移动到TypeScript文件中来使用解决方法.但是对于这个<a href...例子我没有任何解决方法.

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

ale*_*ill 10

是.webpack支持这两种方式

1)使用选项输出.这会将条目文件的导出写入您选择的全局范围内的命名空间变量

myEntryFile.ts

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

export {
  Example,
  doSomething
}
Run Code Online (Sandbox Code Playgroud)

webpack.config.js

output: {
  //... your normal output config her
  library: 'MyExposedNamespace'
}
Run Code Online (Sandbox Code Playgroud)

现在可以在 window.MyExposedNamespace

window.MyExposedNamespace.doSomething()
const myExample = new window.MyExposedNamespace.Example()
Run Code Online (Sandbox Code Playgroud)

对于更高级的用法,您还可以通过libraryTarget更改应用命名空间的范围,这样就不会污染全局范围

2)使用expose-loader

webpack.config.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'
      ]
    }
  ]
}
Run Code Online (Sandbox Code Playgroud)

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

myEntryFile.ts

import './example'
import './example2'
Run Code Online (Sandbox Code Playgroud)

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

window.doSomeThing()
const myExample = new window.Example()
Run Code Online (Sandbox Code Playgroud)

这个可能会变得更加棘手,因为打字机也需要在暴露之前发生,这取决于你的其他配置,可能比上面的简单版本更复杂

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