javascript - 在浏览器中使用带有导入的 es6 样式类的 TypeScript 转译代码,而无需额外的转译步骤?

标签 javascript reactjs typescript

如果我使用 target:"es5"为了转译使用 es6 风格的类和 React 的 TypeScript 代码,我的预期入口点(这里是一个名为 App.ts 的文件)具有如下所示的转译代码:

Object.defineProperty(exports, "__esModule", { value: true });
var react_1 = require("react");
var react_router_1 = require("react-router");
当这个片段中的第一行被击中时,我得到一个 Uncaught ReferenceError: exports is not defined错误。 TypeScript 的 GitHub 问题页面 here 上描述了类似的问题。 .
quick answerexports将存在于支持类加载的环境中。

commonjs means there's an exports variable available. You can't run commonjs code directly in a browser.


这是我的 html 包装器:
<!DOCTYPE html>
<html>
  <head>
    <meta charset="UTF-8" />
    <title>Hello World</title>
    <script src="https://unpkg.com/react@16/umd/react.development.js"></script>
    <script src="https://unpkg.com/react-dom@16/umd/react-dom.development.js"></script>
    <script src="./components/App.js"></script>
  </head>
  <body>
    <div id="root"></div>

    <script>
      ReactDOM.render(
        React.createElement('App', null),
        document.getElementById('root')
      );
    </script>
  </body>
</html>
看起来( 123 )通常的 react 是在您的 TypeScript 和它在浏览器上发布到客户端之间添加一个额外的转换步骤。等等,什么?我需要转译转译的代码吗?这有点像那些“I thought the dishwasher washed the dishes”广告之一。
另一个建议是使用模块加载库,如 RequireJS 或 SystemJS ( 1 , 2 )。这是有道理的,但我还没有看到将模块加载库添加到 TypeScript 编译代码以传递到浏览器的示例。而且,TypeScript 似乎可以智能地(如“使用最少重复的代码”)在编译时包含这样的库。
(看起来 RequireJS 至少通常与 different syntaxrequire 一起使用,而 require(['lib1', 'lib2', 'lib3'], function (lib1, lib2, lib3) {...}}) 而不是更简单的 var lib1 = require('lib1') TypeScript 正在生成,尽管 perhaps I'm missing something ?)
所以这里至少有两个相关的问题:
  • target="es5" 的预期用例是什么? TypeScript 转译代码?
  • 如何将 es6 TypeScript 代码交付给浏览器,而不需要超出 TypeScript 所能做的转换步骤?
  • 也就是有没有platform:"browser" -我错过了风格的设置?
  • 如果不是,RequireJS 是否应该使用 TS 生成的代码?那应该如何“引导”/开始?


  • 更新: (将我的评论从@felixmosh 的回答移到问题中)
    我已尝试添加 "module":"es2015"到我的 tsconfig.json,但代码开始出现如下错误:import Home from './pages/Home';读到 error TS2307: Cannot find module './pages/Home' .
    我的印象是 module选项定义了在 TypeScript 中定义模块的方式,而不是如何在生成的 JavaScript 代码中转换它们。也就是说,如果此选项仅影响输出,为什么我的未编译代码会在添加/更改模块设置后抛出错误,而不是简单地更改生成的 JavaScript 文件的语法?
    @felixmosh 还 [有用地] 建议使用类似 RollUp.js 的东西,但这确实是通过加载模块来结束的,好吧,它说编译,但它实际上只是将“小 block 代码合并成更大更复杂的东西”。将所有模块放入一个文件是一种作弊。 (尽管为什么 TS 至少不做这个集团?)
    所以 +1 到 felix 并感谢您的帮助,但我仍然不明白为什么 TS 在它停止的地方停止 - 它生成的代码的用例是什么? TypeScript 真的需要在 TS 之外的步骤才能在交付给浏览器的代码中使用 es6 样式的类吗?
    我为什么在乎? 我以前使用过基于 RequireJS 的代码库,很高兴能够以一种比单体代码库更容易调试的方式分解文件。但我也不明白为什么 TS 在这个用例中似乎没有产生可部署的代码。

    最佳答案

    如果您想保留 import/export es6 你应该定义module:"es2015" ,默认情况下,它将这些转换为节点中使用的 cjs 样式。

    Modern browsers不支持节点的cjs风格但 es2015样式,因此您需要指定该模块类型,并在脚本标签上指定 type="module" 的属性,类似的东西:

    <script type="module" src="entry-point.js"></script>
    

    目前有 的原生支持。模块 仅在 chrome 中,因此现在最好的做法是从您使用导入创建的依赖关系树中创建一个包。

    常见的边界是Webpack & RollUp ,您可以阅读他们的配置以生成在浏览器中运行的包。

    typescript 和 webpack 配置的小引用:https://webpack.js.org/guides/typescript/

    关于javascript - 在浏览器中使用带有导入的 es6 样式类的 TypeScript 转译代码,而无需额外的转译步骤?,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/50397184/

    相关文章:

    javascript - 如何链接javascript函数在wordpress主导航菜单中有一个herf

    javascript - React 不将 HTML 字符串从 JSON 转换为文本

    javascript - 使用 react-router-navigation-prompt 时关于弃用 findDOMNode 的警告

    javascript - Angular 8 - 按数字过滤对象数组

    angularjs - 如何摆脱 TypeScript 中的 $injector 类型错误?

    javascript - Fabric.JS 和 AngularJS – 0 和 '0' 之间的区别

    javascript - 需要帮助理解 JQuery 的 noConflict() 函数中发生的情况

    javascript - jQuery scrollTop 不适用于具有高度和滚动条的 HTML 元素

    javascript - 如何删除 appendChild 中的特定 css?

    javascript - 如何按特定键在数组中按字母顺序对对象进行分组?