Three.js: 评估 ES6 类

创建于 2017-06-19  ·  92评论  ·  资料来源: mrdoob/three.js

为什么将这种继承的“习惯用法”引入代码中:

PointLight.prototype = Object.assign( Object.create( Light.prototype ), {

严重地? 函数(嵌套函数(ParentPrototype)COMMA SHOTGUN BRACKET?

例如,Materials 类中的忠实两线样式更加清晰明了。 分配原型,然后设置构造函数。 结束。 请不要因感染 JavaScript 疾病而毁了库——奇怪的需要自慰对象和继承的编码方式。 整个图书馆的一种风格。 无需更改它。

Suggestion

最有用的评论

在浏览器可以原生执行 TypeScript 之前,我更喜欢继续使用 JavaScript。

所有92条评论

所以你建议改用这种模式?

PointLight.prototype = Object.create( Light.prototype );
Object.assign( PointLight.prototype, {
class PointLight extends Light

呵呵😄 没问题...

@sasha240100总有一天...

@mrdoob不完全-您提到的两种方式直接等效。 我认为OP正在比较

PointLight.prototype = Object.assign( Object.create( Light.prototype ), { 
    constructor: PointLight,
    prop1: 'something',
    method1: function someFunction() { .. },
    ...
});

function PointLight () { ... };

PointLight.prototype = Object.create( Light.prototype );

PointLight.prototype.constructor = PointLight;

PointLight.prototype.prop1 = 'something';

PointLight.prototype.method1 = function someFunction() { .. };

...

例如,这里就是这样做的。
据我所见,这些样式是等效的-我缺少什么吗?
还是在Object.Assign可用且未在整个代码库中更新时将样式更改为使用?

@looeee @bfred-it @mrdoob为什么不直接使用rollup-babel

比较
当前的。 es5 + es6 和谐模块。

import { LineBasicMaterial } from './LineBasicMaterial';
import { Color } from '../math/Color';

function LineDashedMaterial( parameters ) {

    LineBasicMaterial.call( this );

    this.type = 'LineDashedMaterial';

    this.scale = 1;
    this.dashSize = 3;
    this.gapSize = 1;

    this.setValues( parameters );

}

LineDashedMaterial.prototype = Object.create( LineBasicMaterial.prototype );
LineDashedMaterial.prototype.constructor = LineDashedMaterial;

LineDashedMaterial.prototype.isLineDashedMaterial = true;

LineDashedMaterial.prototype.copy = function ( source ) {

    LineBasicMaterial.prototype.copy.call( this, source );

    this.scale = source.scale;
    this.dashSize = source.dashSize;
    this.gapSize = source.gapSize;

    return this;

};


export { LineDashedMaterial };

ES2015+。 相同的代码,但 es2015+ 带有babel-plugin-transform-class-properties

import { LineBasicMaterial } from './LineBasicMaterial';
import { Color } from '../math/Color';

export class LineDashedMaterial extends LineBasicMaterial {
  type = 'LineDashedMaterial';

  scale = 1;
  dashSize = 3;
  gapSize = 1;
  isLineDashedMaterial = true;

  constructor(parameters) {
    super();
    this.setValues( parameters );
  }

  copy(source) {
    super.copy(source);

    this.scale = source.scale;
    this.dashSize = source.dashSize;
    this.gapSize = source.gapSize;

    return this;
  }
}

ES6 特性可以简化 three.js 代码:

我完全赞成迁移到 ES2015+,我们只需要找到一种方法来输出与我们目前所拥有的代码相似的代码,因此在所有情况下性能都保持不变。

我有一个关于课程的问题。 我们如何将Vector3.unproject之类的方法转移到类语法中? 该方法实际上使用闭包来创建新范围。 这是一个重要的机制,可以将对象创建的数量保持在尽可能低的水平。

在这些情况下我们需要Object.assign吗?

@Mugen87 @mrdoob一些关于 es6 性能的有趣信息。 特别是在Object.assign上:
image
这篇文章

我们如何将 Vector3.unproject 之类的方法转移到类语法中? 该方法实际上使用闭包来创建新范围。

@Mugen87它们不能只是非导出的模块范围对象吗? 像这样的东西;

const tempMatrix = new Matrix();    

export default class Vector3{
    unproject() {
        // uses tempMatrix
    }
}

啊,是的,我认为这应该工作😊

@mrdoob哇! 它似乎已经开始工作了。 我们不能做一个分支,把一些类转换成 es6 看看它是如何编译的吗?


@satori99作为如何将tempMatrix保留在 Vector3 代码中以避免全局变量问题的想法:

export default class Vector3 {
    static tempMatrix = new Matrix();

    unproject() {
        // uses Vector3.tempMatrix
    }
}

@mrdoob哇! 它似乎已经开始工作了。 我们不能做一个分支,把一些类转换成 es6 看看它是如何编译的吗?

对我来说听起来不错! 我目前专注于 WebVR,所以它需要是我以外的其他人。

@sasha240100使用模块作用域变量的好处是它们对常规用户代码保持隐藏,这似乎适用于临时变量。

我不介意关于私有变量的“我们都是成年人”的 Python 方法,但临时变量不应该真正不必要地污染命名空间。

另外,如果我们这些在浏览器中启用了本地模块支持的人可以直接加载 src 文件,那就太好了。 这是一种更愉快的开发方式,无需在每次编辑后进行观察和转译。 使用类属性意味着这是不可能的,因为它们不是当前类规范的一部分。

抱歉,我们应该将问题标题更改为“评估 ES6 类”,因为现在线程已更改为完全不同的内容。

为什么要更改模式@Mugen87 @satori99

method =(()=>{ 
    const vec3forThisScope =...; 
    return (arg)=>{...}
})()

为什么不试试typescript,可以编译成其他版本的js

TypeScript确实是一个很好的选择,因为它是一个转译器 + 类型检查器和 JavaScript 的超集,因此很容易将代码库移至 .ts 文件并通过类型检查逐步重构为 ES6。

如果您从未使用过 TypeScript,这可能听起来很吓人,但这实际上并不是一个很大的学习曲线,而且要为它带来的好处付出很小的代价。 TypeScript 社区将非常乐意帮助完成这一过渡并针对当前库创建性能测试,以确保它不会被降级。

一些有用的文章:

引用核心开发人员 Anders Hejlsberg 的话,TypeScript 的诞生是为了回应客户和内部团队对 JavaScript 不适合大型应用程序的抱怨。

目标是“通过类、模块和静态类型来增强 JavaScript”,同时又不牺牲其开放标准和跨平台的优势; 结果是一种“用于应用程序规模的 javascript 开发的语言”,作为该语言的超集而构建。

在浏览器可以原生执行 TypeScript 之前,我更喜欢继续使用 JavaScript。

@mrdoob

我看不出这是不使用 TypeScript 的正当理由,因为它不能直接在浏览器中运行。 您不希望它在浏览器中运行,因为所有额外的代码行仅用于编译时检查。 它目前不是运行时检查语言。 因此,如果它曾经在浏览器中使用过,它很可能会删除所有类型化的代码,因为它会影响性能,这将是普通的 JavaScript 代码。

我认为您完全忽略了使用类型语言的意义以及它在大型代码库中的开发所带来的好处。 您仍在编写和使用 JavaScript,TypeScript 的全部意义在于它是 JavaScript 的超集。 您编写带有类型的 JavaScript,它被编译成指定 ECMAScript 目标版本中的 JavaScript,可在编译器选项中配置,允许的值为 'es3'、'es5'、'es2015'、'es2016'、'es2017' 或 '下一个'。

因为 Typescript 是 JavaScript,它使得逐步迁移成为可能,而不必为一次重构所有内容而头疼。 它可以由社区逐步完成和改进。 与这里讨论的重构使用 ES6 类相比,它没有更多的工作。 这是我在这里提到它而不是打开一个新问题的唯一原因。

有关很好的示例,请参阅下面的 TypeScript 游乐场链接:

@joejordanbrown

你能想到任何可能不同意你关于打字稿是这个特定问题的最佳解决方案的人吗?

如果您在 google 中输入typescript vs ,会弹出几个术语,其中之一是 Flow。 搜索它,似乎产生了许多文章,人们在争论这两者的利弊。

没有哪种类型比选择其中一种更像是一种妥协。

为比他们创建的结果更复杂的项目保存 Typescript——特别是最初可以在 HTML 中实现的前端框架。 我最初的目的是摆脱 JavaScript 疾病,而不是让它变得更糟。 JavaScript 是一种简单的几乎是玩具语言,有时用于复杂的结果,例如three.js。 打字稿毫无意义。

2017 年 9 月 6 日下午 1:55,Joe [email protected]写道:

@mrdoob

我看不出这是不使用 TypeScript 的正当理由,因为它不能直接在浏览器中运行。 您不希望它在浏览器中运行,因为所有额外的代码行仅用于编译时检查。 它目前不是运行时检查语言。 因此,如果它曾经在浏览器中使用过,它很可能会删除所有类型化的代码,因为它会影响性能,这将是普通的 JavaScript 代码。

我认为您完全忽略了使用类型语言的意义以及它在大型代码库中的开发所带来的好处。 你仍在编写和使用 JavaScript,TypeScript 的全部意义在于它是 JavaScript 的超集。 您编写带有类型的 JavaScript,它被编译成指定 ECMAScript 目标版本中的 JavaScript,可在编译器选项中配置,允许的值为 'es3'、'es5'、'es2015'、'es2016'、'es2017' 或 '下一个'。

因为 Typescript 是 JavaScript,它使得逐步迁移成为可能,而不必为一次重构所有内容而头疼。 它可以由社区逐步完成和改进。 与这里讨论的重构使用 ES6 类相比,它没有更多的工作。 这是我在这里提到它而不是打开一个新问题的唯一原因。

有关示例,请参见 TypeScript 游乐场链接:

经典 JavaScript 示例
添加类型示例
添加有错误的类型示例
使用类示例
使用带有错误的类示例

您收到此消息是因为您编写了该主题。
直接回复此电子邮件,在 GitHub 上查看它,或将线程静音。

^ 即使是可怕的模式,我也可以,只要它是一致的。

@joejordanbrown听起来你爱上了打字稿。 随意分叉项目并将其移植到打字稿。 三.ts! 🙌

@pailhead

这是一个选择的问题,我相信很多人会同意和不同意,这很正常,虽然是对的! 你总是会看到“这个与那个”,“我的比你的好”。 我明白每个人都有自己的好处。 这是关于权衡可用的选项并查看它们是否可以使项目受益。 比较是一件好事,它可以进一步推动项目。

你提到Flow,我看到的问题是:

  • Flow 许可是 BSD 3 条款“ Facebook BSD +专利许可”,Apache Software Foundation 禁止在新项目中使用此许可。 您可以在此处阅读更多详细信息。

  • 与 TypeScript 相比,缺乏 IDE 支持。

  • 与 TypeScript 相比,用户群很小,

  • 公共库的可用类型不完整,TypeScript 有很多维护良好的类型。

  • 与 TypeScript 相比,文档和资源很难找到并且比较模糊,你会发现很棒的文档、书籍、视频和许多其他电子学习资源。

  • Flow 使用带有// @flow标记的 .js 文件,这可能会让人感到困惑,因为您会看到.js扩展名,所以期待 JavaScript,但实际上它是 FlowType。 TypeScript 使用自己的扩展名.ts 。 这还允许您在同一目录中拥有具有相同名称的 TypeScript 和 JavaScript 输出文件,这对于小型项目来说是理想的,显然,在大型项目中情况并非如此,因为您将使用构建系统来管理构建过程。

甚至 google 也在大力支持 TypeScript,这显示了他们对 TypeScript 的信心。 阅读这里这里的帖子。

自 2017 年 3 月起,Typescript 已被允许用于不受限制的客户端开发。TypeScript 和 Angular on TypeScript 用于 Google Analytics、Firebase 和 Google Cloud Platform 以及关键的内部工具,例如错误跟踪、员工评论以及产品批准和发布工具。

我只是想我会打开关于使用类型语言的讨论,看看其他人对这个想法的看法。 不过, @mrdoob似乎完全反对讨论这个想法。


@arctwelve
我看不出这个项目是如何不复杂的,以及使用类型化语言会如何对其产生负面影响。


@mrdoob
一点也不,我可以看到它可能带来的好处,特别是如果正在创建一个新分支来更新到 ES6 类。 我认为用创建自己的名为three.ts 的fork 来回答是愚蠢的。 如果每个人都只是分叉 OSS 项目并修改自己的源代码,而不是专注于 1 个项目并使其成为最好的,那真的违背了良好的 OSS 实践。 无论出于何种原因,您最终都会遇到非常糟糕的软件或社区分裂并专注于他们更喜欢的项目。 为什么你不能就利弊进行公开讨论?

不是扮演魔鬼的拥护者,但似乎他做到了

进行公开讨论

它真的很短:)

我也有类似的观点,它是一个 JS 库,并且 JS 是标准化的。 为 JS 库选择 JS 不会出错,而如果您选择其他东西,则可以。 我只是把 Flow 作为 typescript 的替代品之一,不知道是否还有其他的。

无论如何,看起来我们真的跑题了。

Mugen87 将标题从
移除 JavaScript 疾病评估 ES6 类

原标题(据我了解)指的是缺乏风格一致性。 特别是在某些地方使用Object.assign() ,而在其他地方使用另一种模式。
如果我在这里评估任何东西,那将是问题的当前标题。 为什么一致性问题被提升为关于使用新语言的讨论?

我想使用 typescript 和 es6,代码应该是相当一致的。

我将通过更新此页面来解决此问题:

https://github.com/mrdoob/three.js/wiki/Mr.doob 's-Code-Style%E2%84%A2

并添加:

A)“...使用 Object.assign ...”
B)“...不要使用 Object.assign”

整个图书馆的一种风格。 无需更改它。

例如,Materials 类中的忠实两线样式更加清晰明了。

在第一篇文章中。

我建议:

  1. 编辑标题以反映这句话,讨论在整个库中使用一种风格,编辑风格指南等。
  2. 开始一个名为“评估 es6 类”的新讨论,其中将评估 es6 类
  3. 开始一个新的讨论,标题为“评估用打字语言写的三个”,其中将讨论打字稿等

无论如何,看起来我们真的跑题了。

的确。 @joejordanbrown随意创建一个新主题来讨论 TypeScript。

顺便说一句,忽略以前的对话也是不好的 OSS 做法...... https://github.com/mrdoob/three.js/issues/341#issuecomment -47000692

回到主题。 我以为我们已经解决了这个问题?

https://github.com/mrdoob/three.js/issues/11552#issuecomment -319449068

我们只需要有人试一试。

好的,所以...首先

第一种模式(最好的 IMO):

function MyClass() {...}

MyClass.prototype = Object.assign( Object.create( MyClassToInherit.prototype ), {

    constructor: MyClass,

    prop1: 'something',

    method1: function someFunction() { .. },

    ...

});

第二种模式:

function MyClass() {...}

MyClass.prototype = Object.create( MyClassToInherit.prototype );

MyClass.prototype.constructor = PointLight;

MyClass.prototype.prop1 = 'something';

MyClass.prototype.method1 = function someFunction() { .. };

...

@arctwelve引入这种模式有很多原因。 这不是手淫!

首先,它允许清楚地阅读对象继承。 Object.assign显然是关于对象继承的。 那么你就不能在MyClass.prototype的很多很多行中丢失继承的对象。
其次,在多重继承的情况下,这也更加清晰。
第三,类的构造函数是可读的,不会像第一点那样在多行中丢失。
第四,这允许将属性和方法分组在同一位置(括号内),当您在同一文件中有 3、4、5... 等类时,这会更加清晰。
第五,此模式允许检查某些“继承”属性的正确副本。

最后( @looeee ),这也是为了性能。 第一个版本在文件解析时更加优化,而不是多次调用原型。

反正 !

现在,我们应该传递到 ES6 语法!

@mrdoob

对我来说听起来不错! 我目前专注于 WebVR,所以它需要是我以外的其他人。
我们只需要有人试一试。

你会创建一个 es6 分支吗? 还是靠我们自己?

第一个版本在文件解析时更加优化,而不是多次调用原型。

你确定吗? 我预计Object.Assign会更慢,如果有的话。 但无论哪种情况,我都怀疑这是否足以担心性能开销。

绝对: https ://jsperf.com/inline-prototype-vs-assign-prototype/1

在 chrome 版本 61.0.3163.100 (Build officiel) (64 bits) 下分配的原型大约快 60%

有趣的。 感谢您进行测试。

但是,该结果并不适用于所有浏览器。 在 Firefox 上,它们几乎相同( Object.Assign快了 ~3%),而在 Edge 上Object.Assign了 ~33% 。

但无论如何,我仍然认为这与哪种风格更好的论点无关——即使是最慢的整体(Chrome 中的内联原型)仍然以每秒 180,000 次以上的速度运行,并且可能有几千次这些设置在代码中完成。 所以我们在这里谈论的可能是几毫秒的差异。

对我来说, Object.Assign样式更简洁,更易于阅读,这是支持它的主要论据。

是的,每个文件大约需要几毫秒,并且只有当文件第一次被 javascript 引擎解析时......但是对于像threejs 这样的大型库,页面加载的增益可能合理地约为 200 毫秒。
不要忘记不能等待更多的前用户的 3scd 限制!

我正在尝试使用threejs 制作Angular 项目,但看起来我总是在破解threejs 的每个部分。
首先,必须存在具有三个常量的 es5 语法,例如,如果我需要 OrbitalControls。
我们有三个js类型,但是将它们放在同一个包中会更方便。 打字有 OrbitalControls,但我们不能像import { OrbitalControls } from 'three;那样简单地导入。
Webpack 有 tree-shaking,所以在 es6 的情况下,我们可以将我们需要的所有内容都包含在一个项目中,而不是将它们移动到单独的项目中。
@mrdoob那么为什么 Typescript 如此糟糕? 无论如何,它将被编译为 ES 任何带有类型的版本。
它也用于许多其他框架,如 React。

@FriOne我不确定@mrdoob是否真的认为 Typescript 不好,但我认为他反对在这个问题/线程中讨论 Typescript,因为这不是这个线程的主题。 我认为 ES6 类不适用于 Typescript。 如果将代码库转换为 ES6,则将代码库移植到 Typescript 会更容易,因为它的语法非常相似。 是的,我认为 Typescript 可以启用很多新选项。 例如,它可以帮助“转换”更优化的代码,帮助新开发人员更快地学习库,也许它为未来的实验打开了大门,例如: https://github.com/AssemblyScript/assemblyscript。 我认为 Typescript 有很多优点@joejordanbrown 详细描述了优点。

但回到主题:我认为采用 ES6 类将是向前迈出的一步,之后,我们可以讨论 Typescript 的事情。 所以让我们一个接一个地做

@tschoartschi ,认为 typescript 可以帮助迁移到 es6 类和其他重构。 我没有这样的迁移经验,可能是我错了。

@FriOne这取决于 😉 当然 Typescript 可以提供帮助,因为编译器可以告诉你所有的错误和错误,但你需要先设置整个构建管道才能使用 Typescript。 此外,您需要评估 Typescript 是否合适。 我觉得先转成 ES6 类再考虑 Typescript 就好了。

嘿,我们是一组来自 KTH 的 5 名学生,他们希望为一门课程的开源项目做出贡献,并希望尝试将项目的一部分转换为新的 ES6 语法。

不久前,我将 Three.js 和一些示例移植到 TypeScript(r82),作为概念验证。

https://github.com/flyover/three.ts

这些示例需要一些时间来加载,因为 TypeScript 源是动态转换的。 使用转译的 JavaScript 时,它们的加载速度与原始文件一样快。

我很想看到将three.js 移植到打字稿。 我觉得这个项目非常需要现代化,如果它想要经受住下一代网络的时间考验。 有一天,我们甚至可能会看到它与 AssemblyScript 一起工作并在 WASM 中运行。 如果不是threejs,那么其他东西肯定会。

这是完成@WestLangley@mrdoob

@bhouston这里的结论是什么?

@pkieltyka是的,我也认为 TypeScript 对于像 Three.js 这样的库很有意义。 除了所有技术专家之外,它还可以简化库的使用并帮助新手探索 API。 但我也认为先完成所有 ES6 的东西然后再考虑 TypeScript 很重要。 我认为从最新的 JavaScript 来看,以 TypeScript 的形式添加类型并不太复杂。

@flyover也很高兴看到 Three.js 的 TypeScript 版本的概念验证。 你从 Three.js 的维护者那里得到反馈了吗?

我还支持three.js 的打字稿。 打字机基本上是最好的
实践和原始 JavaScript 不再是。

2019 年 1 月 5 日星期六,凌晨 4:13 tschoartschi < [email protected]写道:

@pkieltyka https://github.com/pkieltyka是的,我也认为 TypeScript
对于像 Three.js 这样的库来说会很有意义。 除了所有
技术专家它还可以简化图书馆的使用并帮助新手
探索 API。 但我也认为完成所有 ES6 很重要
先找东西,然后再考虑 TypeScript。 我认为从最新
JavaScript 以 TypeScript 的形式添加类型并不太复杂。

@flyover https://github.com/flyover也很好看一个概念验证
Three.js 的 TypeScript 版本。 你有没有得到维护者的反馈
Three.js 的?


你收到这个是因为你被提到了。
直接回复此邮件,在 GitHub 上查看
https://github.com/mrdoob/three.js/issues/11552#issuecomment-451639995 ,
或使线程静音
https://github.com/notifications/unsubscribe-auth/AAj6_bkdND7I0_F4AJcBV0DYLpToUIVhks5vAGykgaJpZM4N9vH8
.

@bhouston我同意 TypeScript 是一项很棒的技术,但我不会像您那样说。 我认为我们应该始终尽可能接近原始 JavaScript 并在顶部添加 TypeScript 功能。 由于 TypeScript 非常紧密地遵循 JavaScript 规范,因此 TypeScript 读起来就像带有类型的 ES6。

对于像 three.js 这样的库,TypeScript 可能非常有益,并且可以逐渐被采用。 所以我们不需要“大爆炸”重写,尤其是在所有 ES6 重构完成之后。

如果@mrdoob对 TypeScript 的立场发生变化,将会很有趣。 TypeScript 似乎已成为“类型化 JavaScript”的“事实上”标准(请注意,我将我的声明放在撇号下,因为这不是确凿的事实)

第一步应该是采用 ES6 特性,尤其是类、箭头函数、'let' 和 'const'。

一旦我们完成了这些,我们就可以适当地讨论 typescript 支持,因为正如@roomle-build 指出的那样,如果我们决定在 ES6 代码之上逐步添加 typescript 功能是很容易的。

对我来说,同时做这两件事似乎会让事情变得过于复杂。

很高兴听到 TypeScript 可能在未来的某个时候成为一种选择 :-) 也许我们可以重用@flyover所做的一些工作

但我完全同意@looeee先完成所有 ES6 的东西,然后专注于接下来的步骤

完成所有 ES6 的东西

如果我们至少可以开始,我会很高兴😅

TypeScript 的一个很好的中途步骤是在每个 JavaScript 文件旁边添加类型文件。 因此会有两者:

Vector3.js
Vector3.d.ts

这为我们提供了 TypeScript 作为 sidecar 文件的所有好处。

现在有一个@types/three 文件,但它已经过时并单独维护——因此它总是会出现数据不足的情况。

Three.JS 的主要竞争对手是 Babylong,它完全是 typescript,我相信它会从中受益。

但是杀死 @types/three 并将其作为边车类型定义文件集成到正确的 Three 将是一个很好的第一步。

我们还需要通过某种类型的摇树将所有示例集成到 /src 中。

现在 Three.JS 的代码结构是 2014 年的,使用起来很痛苦。

所有的例子?

示例/js

2019 年 1 月 7 日星期一上午 10:25 Dusan Bosnjak < [email protected]写道:

所有的例子?


你收到这个是因为你被提到了。
直接回复此邮件,在 GitHub 上查看
https://github.com/mrdoob/three.js/issues/11552#issuecomment-451970482
或使线程静音
https://github.com/notifications/unsubscribe-auth/AAj6_Q3Kakb5Qn2DqGbMVvLkW_28cOyaks5vA2b5gaJpZM4N9vH8
.

@bhouston

TypeScript 的一个很好的中途步骤是在每个 JavaScript 文件旁边添加类型文件。 因此会有两者:

Vector3.js
Vector3.d.ts

.d.ts 文件会在 c 中充当 .h 文件吗?

.d.ts 文件会在 c 中充当 .h 文件吗?

这是一个很好的类比。 有趣的人已经在这里完成了大部分工作: https ://github.com/DefinitelyTyped/DefinitelyTyped/tree/master/types/three 因此,实际上它只会获取这些类型文件的所有权并将其集成到 Three.js 中。 如果您愿意,我们可以创建一个 PR,将其集成到 Three.js 中并将其拆分。

要显示 Typescript 的流行程度,请查看每周下载了多少 @Types/three:

https://www.npmjs.com/package/@types/three - 每周 63,000 次下载。

感人的!

如果您愿意,我们可以创建一个 PR,将其集成到 Three.js 中并将其拆分。

我觉得很好听👍

是否可以运行类似于 eslint 的命令行检查,确保类型文件和源.js文件对齐? 如果我们拥有d.ts文件的所有权,最好有某种方法定期验证它们是否匹配。

要显示 Typescript 的流行程度,请查看每周下载了多少 @Types/three:

https://www.npmjs.com/package/@types/three - 每周 63,000 次下载。

我将这更多地归因于 Visual Studio Code 的流行,因为当您使用 Visual Studio Code 时,它​​会通过其自动类型获取功能自动发生。
也就是说,它不能被忽视。

@flyover @bunnybones1 @mrdoob @looeee @donmccurdy @bhouston @roomle-build @pkieltyka @FriOne @joejordanbrown因为你们似乎都对 TypeScript 感兴趣我想指出我创建了一个关于 TypeScript 的新问题。 我认为将所有 TS 讨论移到那里是有意义的。 如果您有兴趣,可以在这里找到它: https ://github.com/mrdoob/three.js/issues/15545

我愿意花时间移植到 ES6 类。 我认为这将是有一天支持 Typescript 的一个很好的桥梁解决方案。

第一步是将一些附加组件转换为 ES6。

https://github.com/mrdoob/three.js/tree/dev/examples/jsm

Controls、Loaders 和 Exporters 是不错的选择。 随时提供帮助!

@mrdoob只是为了确认一下,您的意思是将它们转换为 ES 模块,但还没有使用其他 ES6 功能,对吧?

我假设进行该转换的过程是:

  1. 使用modulesize.js脚本将原始文件转换为 ES 模块。
  2. 如果需要,清理问题。
  3. 在某个时候(这个版本,或在不久的将来),我们将开始使用rollup-examples.config.js将 ES 模块转换为 UMD 模块,此时examples/js中的版本不再由手。
  4. 一旦稳定了,我们可以考虑其他改变,比如引入 ES6 特性。

@mrdoob只是为了确认一下,您的意思是将它们转换为 ES 模块,但还没有使用其他 ES6 功能,对吧?

是的,对不起。 我应该指定的。

我和@bhouston已经创建了承诺的 PR,它为大部分 Three.JS 项目贡献了 *.d.ts 文件。 https://github.com/mrdoob/three.js/pull/15597

我只是等不及 ES6 类和 Typescript 定义。 每次我使用 three.js 时,我都必须复制粘贴数百行代码来重新实现一个位于无法访问范围内的函数。 如果您必须优化场景,这真的不是一种优雅的工作方式。 它将把工作流程提升到一个新的水平,最终能够扩展和覆盖功能。
所以请让类函数至少“受保护”并且可以毫无例外地访问🤗

每次我使用 three.js 时,我都必须复制粘贴数百行代码来重新实现一个位于无法访问范围内的函数。 ...所以请让类函数至少“受保护”并且可以毫无例外地访问。

@dionysiusmarquis我不确定我理解你的意思......现有的TS类型有你想要使用的功能被错误地标记为私有? 或者当前原型风格的类定义很难在 TS 中使用? 你能分享一个例子吗?

每次我使用 three.js 时,我都必须复制粘贴数百行代码来重新实现一个位于无法访问范围内的函数。 ...所以请让类函数至少“受保护”并且可以毫无例外地访问。

@dionysiusmarquis我不确定我理解你的意思......现有的TS类型有你想要使用的功能被错误地标记为私有? 或者当前原型风格的类定义很难在 TS 中使用? 你能分享一个例子吗?

我只是想为特定场景实现特定的阴影贴图。 例如,如果能够覆盖getDepthMaterial将会有所帮助。 目前,我在构建过程中注入了我自己的WebGLShadowMap ,其中包含我想要的更改的复制/粘贴版本。
如果每个three.js类都尽可能多地公开,那就太好了。 使用 typescript,您可以轻松地将函数标记为privateprotected以描述预期目的。 例如,我的 ES6 Class/Typescript ShadowMap 如下所示:

interface MaterialCache {
  [uuid: string]: {[uuid: string]: MeshDepthMaterial}
}

class ShadowMap {
  public enabled: boolean = false
  public autoUpdate: boolean = true
  public needsUpdate: boolean = false
  public type: ShadowMapType

  …

  protected depthMaterials: MeshDepthMaterial[]
  protected materialCache: MaterialCache

  constructor (renderer: WebGLRenderer, objects: WebGLObjects, maxTextureSize: any) {
    …
  }

  protected getDepthMaterial (object: Object3D, material: Material) {
    …
  }
}

export { ShadowMap as WebGLShadowMap }

如果您被允许修改“低级”类,那感觉就像家一样

我有一个关于课程的问题。 我们如何将Vector3.unproject之类的方法转移到类语法中? 该方法实际上使用闭包来创建新范围。 这是一个重要的机制,可以将对象创建的数量保持在尽可能低的水平。

在这些情况下我们需要Object.assign吗?
@穆根87

你现在可以用类做闭包。 如何在该语法糖中导航并不明显。 在 StackOverflow 上查看我的回答: https ://stackoverflow.com/questions/39297258/iife-in-es6-class-literal/56077521#56077521(我必须谦虚并承认我不完全理解它是如何/为什么起作用的.)

抱歉,这段代码看起来像一个反模式,我们不应该在项目中修改它。 在模块范围内管理变量有适当的解决方案。 我建议走这条路。

@Mugen87是的,我也认为我们应该充分利用模块范围。 这也有助于诸如摇树之类的事情。 这已经在许多其他问题中讨论过,例如: https ://github.com/mrdoob/three.js/issues/6241#issuecomment -398703521

抱歉,这段代码看起来像一个反模式,我们不应该在项目中修改它。 在模块范围内管理变量有适当的解决方案。 我建议走这条路。

没问题。 我刚刚提到了这种可能性。 如果你有一个更好/更清洁的解决方案,我很想看到它在行动。 Three.js 项目(用法、源代码、讨论等)一直是我获取 JS 知识的主要来源,因此向 Three.js 引入新的更好的编程模式可能也会使我和我的项目受益。 没什么好遗憾的。 ;-)

@Mugen87您能否详细说明一下为什么您认为 IIFE 类是一种反模式,如果这样我可以学习和理解更多一点? 我理解模块范围变量固有地但这与以前构建核心的方式没有什么不同。 由于使用缓存变量的函数如此之多,因此确保没有函数冲突或同时使用变量非常重要——函数作用域使这更容易管理和维护,这就是为什么我没有看到它作为一种反模式(至少与在模块范围内抛出所有缓存变量相比)。

您能否详细说明为什么您认为 IIFE 类是一种反模式

我不会使用像这里提到的那样可能阻碍摇树的方法: https://github.com/mrdoob/three.js/pull/14695。 此外,我认为整个模式看起来像一个黑客。 使用较少“花哨”的方法通常效果更好。 避免不必要的闭包也应该总体上提高代码执行性能(不能用参考证明这一点,但我前段时间在一次谈话中听说过)。

由于使用缓存变量的函数如此之多,因此确保没有函数冲突或同时使用变量非常重要。

IIFE主要用于数学课。 由于我们在那里有大量的测试覆盖率( @gero3最近通过添加更多的单元测试做得很好),应该更容易删除它们。

可以删除 IIFE。 我想我在 2013 年就对它负责。这是为了摆脱难以维护的静态变量模式。 这是在这个 PR 中完成的:

https://github.com/mrdoob/three.js/pull/2941

https://github.com/mrdoob/three.js/issues/2936

并在这里更早地讨论过:

https://github.com/mrdoob/three.js/pull/2920#issuecomment -12217793

有趣的事实是,当我们将这些放入时,代码性能并没有差异。

我假设进行该转换的过程是:

  1. 使用modulesize.js脚本将原始文件转换为 ES 模块。
  2. 如果需要,清理问题。
  3. 在某个时候(这个版本,或在不久的将来),我们将开始使用rollup-examples.config.js将 ES 模块转换为 UMD 模块,此时examples/js中的版本不再由手。
  4. 一旦稳定了,我们可以考虑其他改变,比如引入 ES6 特性。

嘿。 可能已经错过了,但是我们对课程的增量步骤是什么?

  1. [x] 使用 modulesize.js 脚本将原始文件转换为 ES 模块。
  2. [x] 如果需要,清理问题。
  3. [ ] 在某个时候(此版本或不久的将来),我们将开始使用 rollup-examples.config.js 将 ES 模块转换为 UMD 模块,此时示例/js 中的版本不再由手。
  4. [ ] 一旦稳定了,我们可以考虑其他改变,比如引入 ES6 特性。

在上面的步骤中,我们基本上完成了步骤(1)和(2)。

步骤 (3) 我们不再这样做,而是在某个时候弃用并删除examples/js文件夹(请参阅 https://github.com/mrdoob/three.js/pull/18749) .

认为这意味着步骤 (4),将 ES6 类引入examples/jsm只能(目前)在极少数不是从examples/js源版本生成的示例上完成。 一旦examples/js被删除,我们就可以做剩下的事情了。

^但我可能在这里的字里行间读得太多了,也许@Mugen87@mrdoob可以确认?

IMO,该项目应专注于examples/js的弃用和删除,以实现仅模块代码库。 在下一步中,我建议继续进行类迁移。 从示例开始,然后迁移核心。

完美的。 谢谢。 将仔细研究这些方式

从已关闭的问题重新发布。
你好呀,

我想创建这个问题来尝试梳理每个人对我们希望如何推进班级迁移的想法。

我对到目前为止所遇到的事情的快速总结:

  • 我们应该在做任何其他事情之前弃用示例文件夹
  • src/ 的某些部分没有被任何可以转换的示例扩展
  • 通过对 modulesize.js 脚本进行一些更改,我们可以开始使用 examples/js/ 生成相应的示例/jsm 脚本。

我错过了什么吗?

我们应该在做任何其他事情之前弃用示例文件夹

我不确定谁负责examples/js文件夹上的任何特定下一步。 除非我们可以清楚地表达该计划,否则我希望这不会阻止将事物转换为 ES 类。 出于这个原因,我有点不同意https://github.com/mrdoob/three.js/issues/11552#issuecomment -592768708。 🙂

除此之外,我们似乎只是在等待确定的日期

此外,作为我所做的一些修改的一部分,我发现了关于如何通过当前汇总构建过程引入其他 ES2015 功能的评论甚至给出了一个例子

编辑:这是另一个快速示例的要点

@DefinitelyMaybe我有一些时间,我很乐意提供帮助。 我可以拿一些dependencies.json清单上的物品吗?

@DefinitelyMaybe处理从像Object3D这样的深层祖先继承的最佳方法是什么? 例如,我在转换src/audio/AudioListener.js时遇到了破损:

[ROLLUP] bundles src/Three.js → build/three.js...
[ROLLUP] (!) Error when using sourcemap for reporting an error: Can't resolve original location of error.
[ROLLUP] src/audio/AudioListener.js: (137:1)
[ROLLUP] [!] Error: 'return' outside of function
[ROLLUP] src/audio/AudioListener.js (137:1)
[ROLLUP] 135:   };
[ROLLUP] 136: 
[ROLLUP] 137:   return AudioListener;
[ROLLUP]        ^
[ROLLUP] 138: }(Object3D));
[ROLLUP] Error: 'return' outside of function

如果我没记错的话,我们将在文件顶部记录我们遇到的任何问题。

我误解了 AudioListener 发生了什么......经过一些调试后,我认为bubleCleanup转换中存在匹配问题。 有关更多信息,请参阅https://github.com/mrdoob/three.js/pull/19934#issuecomment -667411997。 我在几个不同的课程中遇到了这个问题,所以我们可能必须在更进一步之前对其进行排序。

这将是一些文件的情况,但不是全部。 我们预料到了这样的问题。

对于那些跟随的人,请快速阅读这里的讨论。

与此同时,在src/loaders上的 dibs !

此页面是否有帮助?
0 / 5 - 0 等级