【问题标题】:including js files with html and node.js包括带有 html 和 node.js 的 js 文件
【发布时间】:2013-01-10 00:32:50
【问题描述】:

我正在通过 websockets 在 HTML5 客户端和在 node.js 上运行的服务器之间执行消息传递。自然地,我选择了 JSON 作为消息格式,因此创建了通用的 javascript 代码,定义了各种消息内容类型和转换操作。 javascript 代码在两个项目之间共享。

我将 Web 客户端创建为一个 git 项目,将我的服务器创建为另一个 git 项目。部分原因是我正在使用 phonegap 为各种基于触摸的环境构建基于 webkit 的客户端。这也是各种逻辑的很好分离。

为了共享通用代码,我为通用逻辑创建了一个单独的项目,并使用 git 的子项目将代码“导入”到其他两个项目中。

现在这适用于基于 html5 的项目,因为我可以执行以下操作来包含代码:

<script src="common/js/comms.js" type="text/javascript"></script>

但是,我在尝试获取代码时遇到了问题。为了获取代码,我最终做了以下事情:

var fs = require('fs');
eval(fs.readFileSync('./common/js/comms.js').toString());

虽然我采用的方法有效,但我注意到当我有依赖项时它开始变得非常混乱(例如,如果我想要 a.js,我需要 x.js、y.js 和 x.js) ,并且我必须为每个希望使用这些实体的单个 node.js js 文件执行此操作。

我也不习惯使用eval 方法。虽然我想使用严格模式,但我没有安全问题,我的理解是 eval 和严格模式像油和水一样结合在一起。

所以我的问题是,在 html 项目和 node.js 项目之间包含共享 js 文件的最佳方法是什么?我更喜欢遵循严格的东西。

我应该指出,虽然围绕这个主题有几个问题,但我找不到任何可以解决我提出的具体问题的问题。我还应该补充一点,我不希望从“服务器”“提供”文件。 HTML5 客户端是“独立的”。


为了澄清,我在“通用 js 文件”中的内容类似于以下内容:

var Comms = function (options) {
   ...
}

在 HTML5 中,我可以通过 new Comms() 引用,这也是我希望在 node.js 中执行的操作。

【问题讨论】:

  • 是的,我会说这些问题非常相似,我认为它肯定回答了他的问题。
  • 如果没有,你总是可以使用 grunt 来连接文件。
  • 如果我在html使用的js文件中使用exports,会不会因为exports没有定义而报错? @mpm 它没有解决我的问题,因为它更改了 js 文件以使用 node.js,这将导致它与 html 代码中断。

标签: javascript html node.js eval


【解决方案1】:

您是否研究过 Node 模块的工作原理?如果您正在使用这种模式进行开发,那么在服务器上使用 require('./common/js/comms') 并同时在您的客户端上也包含它是相当简单的。

这篇文章应该为你指明正确的方向:https://caolan.org/posts/writing_for_node_and_the_browser.html


以下是 Tyler 在下面的 cmets 中链接到的代码。

示例(example.js):

if(typeof exports == "undefined"){
    exports = this;
}

Example = function() {
    this.init();
};

Example.prototype = {
    init: function() {
         console.log('hello world');
    }
};

exports.Example = new Example();

example.js(app.js)的node.js用法:

example = require('./example');

example.js(index.html)的html用法:

<html>
    <head>
        <title></title>
    </head>
    <body>
        <script src="./example.js"></script>
    </body>

OP 的更改是将exports.Example 分配给Example,而不是分配给一个新实例。因此 node.js 逻辑可以使用以下内容:

var Example = require('./example.js').Example;
var foo = new Example();

原来的问题就这样解决了。

【讨论】:

  • 谢谢泰勒,这很有帮助。我更新了我的问题以显示我目前在做什么。使用我给出的示例,然后将我在 html 端的代码更改为类似于 html 端和 node.js 端的 new &lt;modulename&gt;.Comms() 吗?在这种情况下,模块名称几乎总是与实体名称相同(因为我喜欢将所有内容分成单独的 js 文件),所以我最终会得到 new Foo.Foo() 和 new Bar.Bar()?如果是这样,那么这似乎有点奇怪恕我直言。有没有办法解决这个问题?
  • 这是一个带有简单示例的 repo:github.com/TylerLH/shared_module_example -- example.js 是模块,app.js 是需要它的 Node.js 脚本。 index.html 只是使用一个简单的脚本标签来包含可在全局命名空间中访问的模块。如果你想传入一些选项,你也可以等待实例化它。
  • 感谢您的快速示例,但它对我不起作用,因为我希望能够使用var x = new Example()。不过,我认为您为我指明了正确的方向,所以谢谢您。
  • 想通了,感谢您的回复。我的问题是了解节点中的整个导出和导入语句的行为方式。再次感谢泰勒,这非常有帮助。顺便说一句,我正在编辑您的答案以包含您的代码。 :-)
  • 哎呀。来自 Caolan McMahon 的链接失效了。新link here....
【解决方案2】:

看看nodeJS modules。

将在 comm.js 中:

module.exports = function(/* any dependency? */){
   // things
   // you can return some object
}

在你需要的文件中 comm.js

require('./common/js/comm.js')();
// or you can assign it to a variable if it returned something

希望有帮助!

【讨论】:

  • 那么添加module.exports不会导致html中包含的js出现问题?
  • 测试是否先定义模块,然后导出你的模块,这就是要走的路
  • @Metalskin NodeJS 在服务器上运行。 HTML 文件中的脚本在客户端上运行。您没有在客户端上包含服务器代码。相反,您可以从客户端向服务器代码发送消息,并解释结果。
  • @talabes 编程中的一种常见方法是重用代码。当代码在不同项目之间通用时,通常方法是编写库。一个是客户端,一个是服务器都没有关系,公共代码应该被重用,从而在每个项目之间共享。否则,我们会造成不稳定,即有人在 x 中更新代码时忘记更新 y 中的代码。
  • @Metalskin 不用说 DRY,你问 module.exports 是否会导致 html 出现问题,而我只是回答“是”,因为 module.exports 来自节点(服务器代码)。
猜你喜欢
  • 2014-07-17
  • 1970-01-01
  • 2013-07-02
  • 2014-05-05
  • 1970-01-01
  • 1970-01-01
  • 2012-04-21
  • 1970-01-01
  • 2015-01-20
相关资源
最近更新 更多