Three.js: 用于three.js的Google Closure Compiler“externs”文件?

创建于 2011-07-10  ·  61评论  ·  资料来源: mrdoob/three.js

你好

是否有适用于three.js 的外部文件? 我的意思是这样的:

http://code.google.com/closure/compiler/docs/api-tutorial3.html#externs

谢谢
雷莫

Question

最有用的评论

嗯,我仍然对代码中有大量注释不太满意。 有时我想知道将整个东西移植到TypeScript 之类的东西是否会更好(太糟糕了,它归微软所有)。

所有61条评论

不,three.js 没有任何外部依赖项,所以目前还不需要这样的东西。

我知道,但是在可编译环境中集成 THREE.js 对自己的项目也很有用。

这样的文件会是什么样子? 抱歉,如果您共享的链接上已经解释过了,我发现该页面有点冗长(文字太多),我无法阅读/理解。

@mrdoob ,您可以在以下位置找到他们的一些示例:

http://code.google.com/p/closure-compiler/source/browse/#svn %2Ftrunk%2Fexterns

或者

http://code.google.com/p/closure-compiler/source/browse/#svn %2Ftrunk%2Fcontrib%2Fexterns

以下也很重要:

http://code.google.com/closure/compiler/docs/js-for-compiler.html

评论/标题? 我认为这会使代码更难阅读......

是的,但我认为它仅适用于这个 extern 文件,而不适用于整个代码。 一个人可以做到,但没有必要。

我已经尝试过http://www.dotnetwise.com/Code/Externs/index.html 。 但它并不完全适用于 Three.js 。 并非所有定义都被提取出来。

这是博客条目:

http://blog.dotnetwise.com/2009/11/closure-compiler-externs-extractor.html

似乎它支持this.method = function(){}模式,但不支持原型......

@mrdoob ,您建议将 THREE.js 集成到具有闭包编译器高级优化器的应用程序中吗? 目前是不可能的吗?

据我了解高级优化器只包括正在使用的类,对吗? 理论上它应该工作......它不工作吗?

我没有尝试使用three.js 进行高级优化,但我记得它曾经用于破坏代码的其他事情。 一般来说,它不是“安全的”——默认的简单优化总是有效,高级有时则不然。

如果你编译为一个库,它会破坏代码,但作为一个应用程序(调用方法和所有这些)它应该可以工作,对吧?

@mrdoob要使用带有编译(优化)代码的库,您需要一个“externs”文件来声明库的所有类和方法。 没有它就行不通。 但是有没有其他工具可以与 Three.js 一起使用? 我需要它来混淆(丑化)我的 Three.js 应用程序。 一位候选人是: https :

Google 闭包 externs 是一个描述整个对象的文件,我们将在编译后的代码中使用它。
如果没有这个文件,编译器只会从函数名中生成类似 a() 或 b() 的东西。

例如,这是针对 JQuery: http :

如果externs 用于three.js,那就太好了。

我对此很满意,但我无法自己解决。 其他人将需要加强这一点。

@yurikor ,当你使用 node.js 时,你可以一起使用 node-browserify 和 uglify-js。 那么你不需要构建任何东西。

@remoe 非常感谢您的建议。 我会试试看。

这个问题已经有一段时间不活跃了,但如果将来有人想解决这个问题,这里有一些额外的信息:

对于我的项目,我创建了一个简单的文件,其中只有足够的 Threejs 导出才能编译我的项目。 它带有类型注释,这非常有用,因为它使闭包编译器能够检查所有类型并在我的代码中找到一些错误。 我手动创建了这个文件。 我使用闭包编译器主要用于错误检查,对于实际缩小,我使用功能较弱但安全的uglifyjs

此外,为了防止闭包编译器重命名我的公共接口符号,我不得不添加几行代码(这四个函数是我的库中唯一的公共函数)。 请注意,闭包编译器会重命名通过blah.xyz访问的所有属性,但不会触及通过blah["xyz"]访问的任何属性。

最后,需要行window['ColladaLoader2'] = ColladaLoader2 (再次注意字符串的使用)来告诉闭包编译器该类应该导出到全局作用域。

但是您没有在生产中使用闭包,而只是检查错误? 我是
不确定维护外部文件是否值得。 只需运行关闭
没有积极的优化,然后你就不需要 extern 文件
但你仍然得到了我相信的大部分验证,或者可能是所有的
验证。 也许你能澄清一下?

从我的手机发送,抱歉我的语法和简洁。
2013 年 2 月 12 日凌晨 5:19,“Robert Carnecky”通知@github.com 写道:

这个问题已经有一段时间不活跃了,但如果有人想
将来解决这个问题,这里有一些额外的信息:

对于我的项目,我创建了一个简单的文件https://github.com/crobi/ColladaAnimationCompress/blob/master/threejs-exports.js,其中只有足够的 Threejs 导出才能编译我的项目。 它来了
带有类型注释非常有用,因为它启用了闭包
编译器检查所​​有类型并在我的代码中找到几个错误。 我有
手动创建此文件。 我使用闭包编译器主要是为了 bug
检查,对于实际缩小,我使用功能较弱但安全的
uglifyjs https://github.com/mishoo/UglifyJS。

另外,为了防止闭包编译器重命名我的公共接口
符号,我不得不添加几行代码https://github.com/crobi/ColladaAnimationCompress/blob/366344d3aa5dbbc0a53c47a2c1759b86bb1e0fcd/ColladaLoader2.coffee#L3376 (这四个函数是我库中唯一的公共函数)。 笔记
闭包编译器重命名所有通过 blah.xyz 访问的属性,
但不涉及通过 blah["xyz"] 访问的任何属性。

最后一行https://github.com/crobi/ColladaAnimationCompress/blob/366344d3aa5dbbc0a53c47a2c1759b86bb1e0fcd/ColladaLoader2.coffee#L3383 window['ColladaLoader2']
= ColladaLoader2(再次注意使用字符串)需要告诉
闭包编译器认为这个类应该被导出到全局作用域。


直接回复本邮件或在 Gi tHub上查看

据我所知,简单模式根本不做任何验证。 它重命名局部变量,如果遇到未知符号,则假设它是全局变量,则保持不变。

高级模式的行为类似于强类型语言中的编译器(假设类型信息可用):它警告未知函数或属性,警告您是否使用错误数量的参数调用了一个函数,或者如果您使用了一个字符串参数,其中数在意料之中。

以简单模式为例,转换如下代码

function fn() {
    var foo = {}; // local variable, safe to rename this
    foo.bar();    // undefined property, will crash here
}
fn();

没有任何警告进入

function fn(){({}).bar()}fn();

这显然会在({}).bar()上崩溃。 高级模式输出如下代码

({}).a(); // fn() inlined, private member 'bar' renamed to 'a'

它仍然崩溃,但编译器也给出了警告

Property bar never defined on foo at line 3 character 0.
  • 发现的错误闭包是我在函数名称中输入错误的错误类型,或者我将一个THREE.Vector3传递给Matrix4.makeTranslation而不是 x、y 和 z 组件的三个单独的数字.
  • 如果我有完整的测试覆盖率(我没有),我迟早会发现这些错误。 但是,如果它们不立即显现,有时它们很难调试。
  • 如果threejs 为每个新版本提供了一个最新的导出文件(维护的巨大努力),闭包编译器将捕获来自不断变化的API 的所有问题(就像Matrix4.makeTranslation )。
  • 设置闭包编译器对我来说工作量太大,因为它需要一个 java 运行时。 构建我的库所需的所有其他工具都基于 node/javascript。

我目前正在构建我的闭包库 externs.js 文件,以便将 THREE.js 应用程序与闭包库集成。 基本上,我们试图找出的是:
是否有包含所有 THREE.js 类及其实现的原型方法的列表? 该列表应该是这样的:

三.纹理
三.Texture.constructor
三.Texture.clone
三.Texture.dispose
三.DataTexture.clone

(等等...)

Ps- Three.js 很棒,但是使用适当的 jsDocs,可以轻松提取此列表:)

在这里有一个three.js导出的部分实现(手动编写,所以可能包含一些错误)。

@crobi :你为什么把文档注释放进去? 这似乎相当耗时,我不确定是否有必要......

@taoeffect :评论主要针对闭包编译器高级模式。 我喜欢强类型代码。

@crobi哦,评论导致强制打字? 这有点酷,我不知道它这样做了。

仅当您使用闭包编译器来检查类型错误时。 类似于打字稿。 两者都将带注释的 javascript 预处理为纯 javascript。 所以它只是一个编译时检查。

这里大部分关于闭包高级优化模式的评论都是不准确的。

为了解决主要问题,您可以使用以下工具为任何库http://www.dotnetwise.com/Code/Externs/自动生成闭包 externs

此外,如果您决定使用three.js 作为代码的输入而不是简单地将其用作外部库,则需要添加标志

--language_in=ECMASCRIPT5

你应该写一篇关于这个的博客文章,也许是表演
关键示例并查看是否通过 Google Closure 运行它
具有良好优化的编译器会有所作为。
-本

2014 年 1 月 13 日星期一下午 12:31,Rodrigo Formigone <
[email protected]> 写道:

此外,如果您决定使用three.js 作为代码的输入而不是
只需将其用作外部库,您就需要添加标志

--language_in=ECMASCRIPT5


直接回复本邮件或在Gi tHub上查看
.

此致,
本·休斯顿
语音:613-762-4113 Skype:ben.exocortex 推特:@exocortexcom
http://Clara.io - 基于 WebGL 的专业级 3D 内容创建

我想我可能会写这样的帖子。 不过,为了澄清,人们希望通过闭包(有或没有 externs 文件)运行 Three.js 的原因不一定只是为了性能优化。 Closure 的主要目的是帮助您用 JavaScript 编写可维护的代码(特别是非常大的代码库)。 目标是帮助开发人员“驯服” JavaScript(编写原生 JS),而不是“避免”它(使用 GWT 或其他类似工具)。 如果您只是尝试将 Three.js 编译为 Closure 项目的一部分,编译器可能会对您大喊大叫,因为 Three.js 可能不符合其某些标准(JSDoc 不够,也许?)。 使用 --language_in 编译器标志现在可以解决这个问题,尽管您会收到一些警告。 如果您只是想编译自己的 JS 代码,但将 Three.js 引用为外部库(从而使 Three.js 的所有代码库保持不变和未优化),您将需要上述 externs 文件。 如果没有 externs 文件,Closure 会抛出编译错误,说 THREE.* 没有在任何地方声明,等等。

虽然我不会写我的博客文章来解释人们可能想要在 Closure 项目中使用 Three.js 的方式和原因,但这是我见过的关于 Google Closure 工具的最佳介绍:(来自 Google I/O 2011) https://www.youtube.com/watch?v=M3uWx-fhjUc (我知道这是一个很长的视频,但确实清楚地说明了编译器的目的是什么,以及不同的编译模式实际上做了什么。它还描述了为什么你需要一个外部文件)。

嗨,我期待使用three.js 开发应用程序,因此需要ADVANCED_OPTIMIZATIONS 选项支持。

当嵌入应用程序仅使用 Three.js 函数的一部分时,死代码移除非常有效。

目前,three.js 需要开发每个函数,因为预期用途仅限于“只需要三个.min.js!”。这种经典方法很容易理解,但是对于这种方法编写的代码,JavaScript 最小化器可以减少代码仅通过缩小变量名(对短变量名无效)、删除空格(仅对缩进空格、制表符和换行符有效)和其他廉价技巧来调整大小。

通过对“闭包编译器样式”代码使用 ADVANCED_OPTIMIZATIONS 选项,它可以删除整个“不需要的代码”,这些代码主要对大型库进行加权。 像Closure 库这样的

由于three.js 已经以面向对象的风格编写,我认为将整个代码更新为“闭包编译器风格”代码并不(技术上)困难。 我担心的事情...

  • Closure 编译器风格需要对每个函数进行注释。 目前,他们都没有。 为曾经开发的所有函数添加注释需要多长时间?
  • 闭包编译器需要严格的类型定义。 即使对于 null 和 undefined,您也应该正确地为它们工作。 对于具有“允许为空”参数、“未定义允许”参数等的函数来说,这可能是一项艰巨的工作……
  • 如果您希望准备由 ADVANCED_OPTIMIZATIONS 编译的“完整版本库”,您应该准备一个适当的 externs 文件。

海调度Xor,

这是一个不错的主意。 你能分享一个小片段,关于如何
这必须添加到three.js?

带着敬意,

拉姆松达尔·马达万

2014 年 6 月 24 日,星期二,下午 4:23,Schedul Xor [email protected]
写道:

嗨,我期待着使用three.js 开发应用程序,并且
所以需要 ADVANCED_OPTIMIZATIONS 选项支持。

当嵌入应用程序仅使用
Three.js 函数的一部分。

目前,three.js 需要开发每一个函数,因为
预期用途仅限于“只需要三个.min.js!”。这个经典
方法很容易理解,但是对于这种方法编写的代码,
JavaScript 最小化器只能通过缩小变量名称来减少代码大小
(对短变量名无效),删除空格(仅对
用于缩进空格、制表符和换行符)和其他廉价技巧。

通过对“Closure compiler styled”使用 ADVANCED_OPTIMIZATIONS 选项
代码,它可以删除整个“不需要的代码”,主要是权重
大型图书馆。 类似 Closure 库的库
https://developers.google.com/closure/library/变大了,但是
图书馆用户和开发人员不关心它,因为他们知道
大多数代码将在编译阶段被删除。

由于three.js已经是用面向对象的风格编写的,我认为它是
不(技术上)很难将整个代码更新为“Closure compiler
样式”代码。我担心的事情......

  • Closure 编译器风格需要对每个函数进行注释。
    目前,他们都没有。 添加注解需要多长时间
    开发过的所有功能?
  • 闭包编译器需要严格的类型定义。 即使对于 null 和
    未定义,您应该正确地为他们工作。 这可能是一项艰苦的工作
    具有“允许为空”参数的函数,“允许未定义”
    参数, ...
  • 如果你期待的话,你应该准备一个合适的 externs 文件
    准备由编译的“完整版本库”
    ADVANCED_OPTIMIZATIONS。


直接回复此邮件或在 GitHub 上查看
https://github.com/mrdoob/three.js/issues/341#issuecomment -46957189。

@schedul-xor 我们肯定需要这方面的帮助...代码注释是否真的需要,或者使用 externs 就足够了?

你好,

我是这个社区的新手,我有兴趣贡献这些
变化。

带着敬意,

拉姆松达尔·马达万

2014 年 6 月 24 日星期二晚上 7:23,Mr.doob [email protected]写道:

@schedul-xor https://github.com/schedul-xor我们肯定需要帮助
有了那个......代码注释真的需要还是足够了
外援?


直接回复此邮件或在 GitHub 上查看
https://github.com/mrdoob/three.js/issues/341#issuecomment -46973166。

请记住,高级优化需要特定的编码风格,否则会破坏您的代码。 例如,three.js 混合了uniforms["diffuse"]uniforms.diffuse ,这在闭包高级优化下是不允许的。 另见#3222。

在任何地方添加严格类型注释是一项巨大的工作,并添加了大量注释行(在我的项目中,它使行数增加了 2 倍)。

拥有其他 Web 框架/语言的 externs 文件很好。

根据教程, externs 用于保护您不想重命名的变量。 当您想要保护(非闭包编译器风格的)第三方库(在您的闭包编译器风格的项目中使用)免受激进的变量重命名时,这就是您使用的方法。

我不确定即使 externs 文件是唯一提供的内容,编译器是否仍会尝试剪切死代码。 如果您应该只编写 externs 文件,而不是为所有函数编写注释,那会容易得多...

尽管如此,在我看来,为每个函数编写注释比编写 externs 更好,因为如果类型定义文件和源代码不同,之后将很难同步 externs 文件。 您可以想象如果每个功能修复都需要更新 externs 文件,那该有多烦人。 任何一种选择(externs 或 /** */ 函数注释)都需要注释,在大多数情况下,更简单的方法获胜。

由于three.js 是一个大项目,我想知道我应该首先在哪里工作。 最好从容易完成的事情开始。

如何放置文件头,为每个函数更改函数定义样式?

THREE.Material = function(){
  :
};
THREE.Material.prototype = {
    constructor: THREE.Material,
    setValues: function ( values1, value2 ) {}
    getValues: function () { return this.a; }
    :
};

goog.provide('THREE.Material'); ← Write goog.provide('package.classname') at the first line

← three empty lines before <strong i="10">@constructor</strong>

/**
 * <strong i="11">@constructor</strong> ← Add <strong i="12">@constructor</strong> annotation to constructor
 */
THREE.Material = function(){
  :
};

← two empty lines before function definition
/**
 * <strong i="13">@param</strong> {!Array.<!string>} values1 Values1 explanation ← values1 is an array of strings. values1 can't be null, and elements inside values1 can't be null.
 * <strong i="14">@param</strong> {!number} value2 Value2 explanation ← value2 is a number.
 */
THREE.Material.prototype.setValue = function(values1, value2){
  goog.asserts.assertArray(values1);
  goog.asserts.assertNumber(value2);
  :
};


/**
 * <strong i="15">@return</strong> {!number} ← This function returns a non-null number.
 */
THREE.Material.prototype.getValue = function(){
  return this.a;
};

将所有参数类型和返回值类型限制为非空会更容易。 这将使传递 ADVANCED_OPTIMIZATIONS 编译错误变得更加容易。

嗯,我仍然对代码中有大量注释不太满意。 有时我想知道将整个东西移植到TypeScript 之类的东西是否会更好(太糟糕了,它归微软所有)。

对于强类型的 javascript,Typescript 感觉比闭包要好得多。 这是我在将一个中等大小的 collada 加载器首先重写为符合闭包的 javascript 然后再重写为打字稿后的经验。 这两种方法都有助于在编译时发现错误。 Closure 对我的代码执行了一些非常好的优化(内联、死代码删除),并且支持可空类型。 另一方面,大量的注释让人分心,IDE 支持(用于代码完成)不如打字稿好。 另外,由于类似于 ECMAScript6 的class关键字,在 typescript 中编写类要容易得多。

但这只是个人意见。 更重要的是,我想再次强调一个事实,在正式支持高级编译模式下的闭包之前,您必须确保所有属性访问都是一致的。 拥有 externs 文件无济于事,对于未导出的内部对象,属性访问必须保持一致,因为您_希望_积极地重命名/内联/删除这些对象。 如果您对每个类和每个变量进行注释,您将发现不一致的属性访问,但对整个 Three.js 代码库执行此操作需要几周时间(如果我推断注释我的项目需要多长时间)。

最后,将three.js 之类的大项目移植到任何其他语言/框架/编码风格是应该详细讨论的事情。

好的,我同意three.js 非常庞大,因此为每个函数添加注释可能需要数周时间。 可能存在比闭包更好的 AltJS。 必须更深入地讨论(如果您希望将其移植到其他地方)。

对不起,我等不及了。 我将 fork 当前提交并开始移植。

你好,

是否可以自动添加这个注解? 如果可以,我们可以添加它
到 build.py 并在我们启用闭包的高级优化之前添加。

带着敬意,

拉姆松达尔·马达万

2014 年 6 月 25 日星期三上午 6:05,Schedul Xor [email protected]
写道:

好的,我同意three.js 是巨大的,因此为每个添加注释
功能可能需要数周时间。 可能存在比它更好的 AltJS
关闭。 必须对此进行讨论(如果您希望将其移植到
别的东西)更深入。

对不起,我等不及了。 我将 fork 当前提交并开始移植。


直接回复此邮件或在 GitHub 上查看
https://github.com/mrdoob/three.js/issues/341#issuecomment -47047966。

@ramsundhar20 ,在我看来,首先添加注释(不准确?总比没有好。不是大问题。它可以更新)将使自动化更容易。

Three.js 目前包含 163 个 javascript 文件,其中定义了 1354 个函数。 是的,这是巨大的,但这并不是一个太远的目标。

// 如果这个话题不合适,我很害怕...

再次@schedul-xor,我真的不喜欢对每个函数发表评论:/

@mrdoob好的,我明白了。

尊重您的政策,我只想在我的 fork 中为每个功能添加评论。 此外,我永远不会提出任何拉取请求。 相反,我会将原始的three.js 修改移植到我的闭包样式的fork 中。 您的有利考虑将不胜感激。

听起来不错 :)

谢谢! 我会开始处理它。

是否至少有一个基本的three.js externs 文件与闭包编译器一起使用? 这不需要 Three.js 源代码有任何额外的 google 样式注释,这只是为了使来自使用 Three.js 的外部 app.js 的链接足够可编译/混淆?

我也对three.js 的高质量、完整的externs 文件非常感兴趣。 这是一个,但不完整:

https://github.com/cljsjs/packages/blob/master/three/resources/cljsjs/three/common/three.ext.js

我想一种方法是从这个开始,然后手动添加您使用的东西。

是的,算我的票。 非常适合可编译的高级模式,100% 类型的 Threejs - 或者至少是 externs 文件。

类型推断变得更好,所需的混乱也减少了。 有了作用域和别名,代码就不必像闭包库一样冗长了。 在干净的代码的情况下,它几乎可以归结为编写类型化的内联文档。 那些真的坏到足以超过所有的好处吗?

超级激进的设置,即高级模式 + JS 压缩 + 基于类型的优化,不仅可以删除死代码,而且可以做优化编译器可以做的所有很酷的事情:

命名常量/枚举将替换为数字。 此外,编译器可以跟踪常量,使用其他常量执行计算,最后在需要的地方插入一个普通数字。 当然,依赖流控制会受到死代码消除的影响。 在生成的应用程序中只有一个活动调用点的函数以及其压缩形式最终会小于其定义的函数将被内联。 命名空间被删除。 所有未受保护的名称都缩小到最低限度。

在 JavaScript 中查找相对昂贵。 重命名、常量折叠和内联的组合将消除大量查找和大量函数调用。 最重要的是,给定一个合适的头文件(闭包库中有一个),所有标准化的 WebGL 常量都可以被烘焙到渲染器中。

结果是一个更小、更快、自我记录和自动定制的库。 编译器还会在更激进的设置下捕获更多错误 - 它可能会简化代码审查。 最后但并非最不重要的是,存在混淆效应:将客户端代码与定制库集中在一起,比带有通过 externs 文件保存的暴露符号的代码提供更好的知识产权保护。

我找不到上面提到的分支。 有人还在开发打字版吗?

@mrdoob 是否希望对主线改变

我很乐意帮忙。

@mrdoob 是否希望对主线改变

目前我专注于重构WebGLRenderer 😇

可以将常量更改为const而不是var对所有 WebGL 浏览器 https://kangax.github.io/compat-table/es6/ (const->basic) 和 js 都有很好的支持引擎开始优化const使用固定字段优化加速全局常量

不过,有趣的是,因为它只能代替var ,所以只适用于我所谈论的情况中的一小部分——即使它只是关于常量。 此外,根据定义,JIT 编译器很匆忙,因此它们自然无法与离线工具执行的整个程序优化竞争。 每个JS引擎都必须尊重代码的结构,不能随意重构,因为我们期望能够例如打开控制台并找到我们放入其中的程序,替换特定功能等。

回到闭包编译器支持:我做了一些阅读和实验。 这是我发现的:

  • 运行高级模式不需要注释,
  • 可以逐渐添加注释以提高优化级别,并且
  • 装载机需要一些小心才能保持工作,但这相当容易。

基本上有三种不同的用例:

  1. 模型可以与应用程序和库一起压缩。
  2. 应用程序和库被压缩。 模型在运行时加载。
  3. 该库以基本模式编译,高级模式应用程序想要使用它。

第三个需要所有 Three.js 的 externs 文件,而且 IMO 的好处太少了很多工作。 所以我只会讨论前两个 - 无论如何,这些是首选:

当编译器看到

anObject['aProperty']

它不会触及属性名称(不会更改任何字符串)。

anObject.aProperty

另一方面,允许编译器一致地重命名属性,除非它知道anObject是正在编译的应用程序的外部。 编译器通过内置或显式提供的 _externs_ 知道这一点。

食谱来了:

  • 我们使加载器始终使用点符号访问属性。
  • 我们键入输入并仅为 JSON编写一个 externs 文件。
  • 使用该 externs 文件进行编译应该是使用例 2 工作所需的全部内容。
  • 对于用例 1,我们不使用 externs 文件,而是从 JSON 中的对象键中去除引号:
{
    "camera": {
        "object": {
    // ...

只会变成

{
    camera: {
        object: {
    // ...

很简单,不是吗?

当 JSON 格式允许外部二进制数据(原始或通过 webgl-loader 或 o3dgc 压缩)时,用例 1 变得更加有吸引力——当然,从技术上讲,另一个与闭包支持完全正交的特性。

externs 文件还可以替换记录文件格式的过时的 Wiki 页面:-)。

我知道这个问题已经关闭了一段时间。 然而,我最近在一个闭包编译器项目中使用three.js 遇到了同样的问题,并登陆了这个页面。 我编写了一个将 .d.ts(打字稿声明文件)转换为闭包编译器文件的工具。 使用该工具和描述的很好的绝对类型/threejs 描述符文件,它可以完美运行。
工具: https :

希望这可以帮助...

@eredo完全帮助了我。 我尝试过的所有其他生成器都缺少对three.js 库的大量方法定义。 谢谢!

@eredo @Corkle或其他任何人,你能告诉我们如何使用tsd2cce吗? 第一个 arg 显然是 .d.ts 定义文件,但第二个 arg 是什么? 我得到这个问题。 https://github.com/eredo/tsd2cce/issues/6

实际上,我发现使用 2 月份的 r73 d.ts 与 tsd2cce 配合得很好,不过 r73 对我来说太旧了。

现在执行此操作的正确方法是使用 tsickle 从 d.ts 文件生成。

大家好,

为了后代和每个人的利益,我决定在这里报告我自己尝试使用 Google Closure Compiler 的 ADVANCED_OPTIMIZATIONS 和其他一些调整进一步缩小库的尝试。

我创建了一个 extern.js,它允许 Three.min.js 开启高级优化。 这远非完美。

为了创建它,我从基于此线程中早期示例的 extern.js 开始。 由于该 extern 文件中未包含损坏的属性,因此以这种方式编译时该库已损坏。 使用闭包编译器上的--property_renaming_report选项,我得到了完整的损坏属性列表。 将所有这些属性添加到 extern.js 后,属性不再被破坏,输出与 SIMPLE_OPTIMIZATIONS 相同。 从那里我有选择地/手动开始注释 extern.js 的部分并确认该库仍然以缩小的形式工作。

我希望自动进行这种猜测和检查,并获得一个完美的 extern.js,它可以安全地处理尽可能多的属性名称。 我有使用 THREE.JS 的单元测试并以编程方式确定哪些损坏的 propnames 导致测试失败的想法,但目前似乎不可能从命令行运行单元测试,例如使用 phantomjs。 (可能是由于 WebGL)?

无论哪种方式,这都是朝着更小的缩小库的“进步”,帮助我保持我的整体 SPA javascript 大小。

外部文件

更新 package.json build-closure 命令

我还使用字符串替换命令从库中删除所有 console.warn 和 console.error 消息,正如您在 build-closure 命令中看到的那样。 有了这个,并注释掉了某些代码部分,到目前为止,我已经将缩小的 lib 缩小了大约 20%,并且还有改进的空间。

@mrdoob在这里执行类似于我的方法的操作,您最终可以提供一个允许 ADVANCED_OPTIMIZATIONS 的 extern.js,而不会使用特定于该编译器的注释使代码混乱,这似乎是您的主要关注点。

@medmr1 太棒了! 您是否尝试过将three.js 库合二为一地编译您的应用程序? 理想情况下,这将防止需要 externs 文件。

我还没有尝试在闭包内构建整个事物,不。 这可能没问题,但我怀疑在修改以编程方式引用的某些属性方面仍然存在问题? IE 之类的东西var thing = ShaderLib[ shaderType + "BumpMapFrag"]但也许我可以省去很多麻烦?

是的,像var thing = ShaderLib[ shaderType + "BumpMapFrag"]这样的东西会因高级优化而中断。 属性引用需要是静态可分析的。 你可以这样做:

function(shaderType) {
  if (shaderType == "a") {
    return ShaderLib.aBumpMapFrag;
  }
  if (shaderType == "b") {
    return ShaderLib.bBumpMapFrag;
  }
...

构建一个正确的 externs 文件对整个项目肯定更有益,因为大多数人不会使用 Closure Compiler 编译他们的应用程序,只使用已发布的缩小版本。

除了 externs,您还可以尝试使用@export注释。
https://github.com/google/closure-compiler/wiki/Annotating-JavaScript-for-the-Closure-Compiler#export -export-sometype

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