Warning: file_get_contents(/data/phpspider/zhask/data//catemap/9/javascript/478.json): failed to open stream: No such file or directory in /data/phpspider/zhask/libs/function.php on line 167

Warning: Invalid argument supplied for foreach() in /data/phpspider/zhask/libs/tag.function.php on line 1116

Notice: Undefined index: in /data/phpspider/zhask/libs/function.php on line 180

Warning: array_chunk() expects parameter 1 to be array, null given in /data/phpspider/zhask/libs/function.php on line 181

Warning: file_get_contents(/data/phpspider/zhask/data//catemap/0/mercurial/2.json): failed to open stream: No such file or directory in /data/phpspider/zhask/libs/function.php on line 167

Warning: Invalid argument supplied for foreach() in /data/phpspider/zhask/libs/tag.function.php on line 1116

Notice: Undefined index: in /data/phpspider/zhask/libs/function.php on line 180

Warning: array_chunk() expects parameter 1 to be array, null given in /data/phpspider/zhask/libs/function.php on line 181
Javascript 使用Google Closure编译器时在浏览器和node.JS之间共享JS的最佳方式_Javascript_Node.js_Google Closure Compiler - Fatal编程技术网

Javascript 使用Google Closure编译器时在浏览器和node.JS之间共享JS的最佳方式

Javascript 使用Google Closure编译器时在浏览器和node.JS之间共享JS的最佳方式,javascript,node.js,google-closure-compiler,Javascript,Node.js,Google Closure Compiler,我正在浏览器和运行node.js的服务器之间开发一个网络应用程序。我现在共享了很多代码,但是当我实际部署它时,我希望客户端只获取特定于客户端的代码。我现在的选择是: 1.)使用继承实现任何浏览器/node.js差异。我在一些地方尝试过这个方法,最终得到了很多类,它们是父类的非常基本的定制,通常只是部分地专门化了一个函数。这不是一种我非常喜欢的风格,因为当你试图了解到底发生了什么时,它意味着很多间接的东西 2.)在全局范围内定义一个常量,比如IS_BROWSER,然后在需要更改浏览器vs node

我正在浏览器和运行node.js的服务器之间开发一个网络应用程序。我现在共享了很多代码,但是当我实际部署它时,我希望客户端只获取特定于客户端的代码。我现在的选择是:

1.)使用继承实现任何浏览器/node.js差异。我在一些地方尝试过这个方法,最终得到了很多类,它们是父类的非常基本的定制,通常只是部分地专门化了一个函数。这不是一种我非常喜欢的风格,因为当你试图了解到底发生了什么时,它意味着很多间接的东西

2.)在全局范围内定义一个常量,比如IS_BROWSER,然后在需要更改浏览器vs node.js上的代码路径时检查它。然后使用高级优化编译所有js,以删除浏览器上的死代码(设置为_browser=true)。假设我做了所有我需要做的事情来在闭包编译器中进行高级优化,那么这种方法有什么问题吗


3。)??我愿意接受建议。

如果您使用高级编译,任何未使用的代码都应该删除;如果正确使用编译器的导出系统,则客户端代码未调用的任何服务器端代码将不在客户端代码的编译版本中

您可以在一个大blob中编写所有代码,然后为您的客户机添加一个包含以下内容的文件

goog.require('my.client.app');
goog.exportSymbol('my.app.entryPoint', my.client.app.entryPoint);
编译后的代码将不包括
my.client.app.entryPoint
的调用树之外的任何内容。同样,如果编译只导出服务器入口点,则客户端代码将被排除

上面的样式用于编写脚本以提供一些函数,这些函数随后将被内联脚本调用;要将整个过程变成一个脚本,您可以执行更简单的操作:

goog.require('my.client.app');
my.client.app.entryPoint();

为了验证编译输出中没有太多死代码,您可以这样做:

您使用的是什么JavaScript库?相当多的JavaScript库将为您消除浏览器和node/rhino之间的差异。按照你的#2使用一个全局常量也很好,但我认为最好是使用一个对所有这些内容进行抽象的库。许多差异实际上是应用程序逻辑的差异,所以它们不会被库抽象掉。我很好奇,浏览器环境和无头服务器环境有什么逻辑差异?好吧,它们都支持环境中的大部分相同功能。如果有人担心CPU使用率、线程等问题,那么我认为使用“has.js”库进行环境功能检测可能是未来最灵活的方式。@StephenChung:你能举一个“库将为你抽象出浏览器和node/rhino之间的差异”的例子吗?@bukzor,例如,Dojo支持大多数浏览器、rhino和node(尽管我不确定node支持是否已经正式取消)。我没有看到任何关于闭包库(closure library,cl)的提及,如果没有第三方(第四方?)库的帮助,cl将无法在node.js下工作,这些库目前都不具备生产质量。这一点很好。我用闭包库风格编写了示例代码,但这完全没有必要。当你说“这是不必要的”时,这意味着还有另一种方法。有吗?编译器以特殊方式处理
goog.require
goog.exportSymbol
,但是通过
require
添加的任何代码都可以预先添加到您想要编译的代码中,并且
exportSymbol
可以替换为
this[“varName”]=varValue
this
希望默认为全局或模块范围)或
window[“varName”]=varValue
浏览器中的。如果您通过名称字符串访问属性,编译器将不会重命名该访问。为了保证以.fieldName样式访问的字段可以使用该名称访问,您必须使用
exportSymbol
,也就是说,如果base.js(定义了
require
exportSymbol
)无法与node.js一起使用;它们至少定义并使用了“我在浏览器中吗?”功能,并且不接触,例如DOM功能。