我想要求我的文件总是通过我的项目的根,而不是相对于当前模块。

例如,如果查看https://github.com/visionmedia/express/blob/2820f2227de0229c5d7f28009aa432f9f3a7b5f9/examples/downloads/app.js第6行,您将看到

express = require('../../')

在我看来,这真的很糟糕。假设我想让我所有的例子都只靠近根结点一层。这是不可能的,因为我必须更新超过30个例子,并且在每个例子中更新很多次。:

express = require('../')

我的解决方案是有一个基于根的特殊情况:如果字符串以$开头,那么它相对于项目的根文件夹。

任何帮助都是感激的,谢谢

更新2

现在我使用require.js,它允许你以一种方式编写,在客户端和服务器上都可以工作。Require.js还允许你创建自定义路径。

更新3

现在我转移到webpack + gulp,我使用enhanced-require来处理服务器端模块。看这里的基本原理:http://hackhat.com/p/110/module-loader-webpack-vs-requirejs-vs-browserify/


当前回答

这里有关于这个问题的很好的讨论。

我遇到了同样的架构问题:想要给我的应用程序更多的组织和内部名称空间,但没有:

将应用程序模块与外部依赖项混合,或者为特定于应用程序的代码使用私有NPM回购 使用相对要求,使得重构和理解更加困难 使用符号链接或更改节点路径,这可能会模糊源代码位置,并且不能很好地进行源代码控制

最后,我决定使用文件命名约定而不是目录来组织我的代码。结构应该是这样的:

npm-shrinkwrap.json package.json node_modules ... src app.js app.config.js app.models.bar.js app.models.foo.js app.web.js app.web.routes.js ...

然后在代码中:

var app_config = require('./app.config');
var app_models_foo = require('./app.models.foo');

或者只是

var config = require('./app.config');
var foo = require('./app.models.foo');

和往常一样,外部依赖项可以从node_modules中获得:

var express = require('express');

通过这种方式,所有应用程序代码都按层次结构组织成模块,相对于应用程序根,所有其他代码都可以使用。

当然,主要的缺点是在文件浏览器中,您不能展开/折叠树,就好像它实际上被组织成目录一样。但我喜欢它非常明确所有代码的来源,而且它没有使用任何“魔法”。

其他回答

只是想继续Paolo Moretti和Browserify的精彩回答。如果你正在使用一个编译器(例如babel, typescript),并且你有单独的文件夹存放源代码和编译过的代码,比如src/和dist/,你可以使用不同的解决方案

node_modules

目录结构如下:

app
  node_modules
    ... // normal npm dependencies for app
  src
    node_modules
      app
        ... // source code
  dist
    node_modules
      app
        ... // transpiled code

然后你可以让Babel等编译SRC目录到dist目录。

符号链接

使用符号链接,我们可以摆脱一些嵌套级别:

app
  node_modules
    ... // normal npm dependencies for app
  src
    node_modules
      app // symlinks to '..'
    ... // source code
  dist
    node_modules
      app // symlinks to '..'
    ... // transpiled code

关于babel——copy-files的警告:babel的——copy-files标志不能很好地处理符号链接。它可能会一直导航到…符号链接和隐性看到无尽的文件。一种变通方法是使用以下目录结构:

app
  node_modules
    app // symlink to '../src'
    ... // normal npm dependencies for app
  src
    ... // source code
  dist
    node_modules
      app // symlinks to '..'
    ... // transpiled code

通过这种方式,src下的代码仍然会有app解析到src,而babel将不再看到符号链接。

我创建了一个名为rekiure的节点模块

它允许您在不使用相对路径的情况下进行要求

https://npmjs.org/package/rekuire

它非常容易使用

我喜欢做的是利用node从node_module目录加载的方式。

如果有人试图加载“thing”模块,他会做如下的事情

require('thing');

Node将在'node_module'目录中查找'thing'目录。

由于node_module通常位于项目的根,所以我们可以利用这种一致性。(如果node_module不在根节点上,那么您就会遇到其他令人头痛的问题。)

如果我们进入目录,然后从目录中返回,我们可以获得到节点项目根的一致路径。

require('thing/../../');

如果我们想访问/happy目录,我们会这样做。

require('thing/../../happy');

虽然这有点粗糙,但是我觉得如果node_modules加载的功能发生了变化,将会有更大的问题需要处理。这种行为应该保持一致。

为了使事情更清楚,我这样做,因为模块的名称并不重要。

require('root/../../happy');

我最近在angular2中使用了它。我想从根目录加载服务。

import {MyService} from 'root/../../app/services/http/my.service';

我正在寻找完全相同的简单性,要求文件从任何级别,我发现模块-别名。

安装:

npm i --save module-alias

打开你的包裹。Json文件,在这里你可以为你的路径添加别名,例如。

"_moduleAliases": {
 "@root"      : ".", // Application's root
 "@deep"      : "src/some/very/deep/directory/or/file",
 "@my_module" : "lib/some-file.js",
 "something"  : "src/foo", // Or without @. Actually, it could be any string
}

使用你的别名只需:

require('module-alias/register')
const deep = require('@deep')
const module = require('something')

我实现这一点的方法是创建“本地链接模块”。

的文件夹结构为例

db ¬ 
    models ¬
        index.js
    migrations
    seed
    config.json

routes ¬
    index.js
    user ¬
        index.js

如果从。/routes/user/index.js我想访问/db/models/index.js我会写

require('../../db/models/index.js')

为了使/db/models/index.js可以从任何地方访问,我在db文件夹中创建了一个名为_module_的文件夹,其中包含一个包。Json和一个main.js文件。

# package.json
{
    "name": "db", <-- change this to what you want your require name to be
    "version": "1.0.0",
    "description": "",
    "author": "",
    "repository": {},
    "main": "main.js"
}
// main.js
module.exports = require('../../db/models/index');

main.js中的路径必须是相对的,就像文件在node_modules中一样

node_modules ¬
    db ¬
        main.js

然后你可以运行npm install ./db/_module_,这将把。/db/_module_中的文件复制到。/node_modules/db中,在应用程序包的依赖项下创建一个条目。json之类的

"db": "file:db/_module_"

您现在可以在任何地方使用此包

const db = require('db');

当你运行npm install时,它会自动安装你的其他模块,工作跨平台(没有符号链接),并且不需要第三方包。