如何使node.js要求绝对?(而不是亲戚)

我想始终通过项目的根目录而不是相对于当前模块来要求文件。

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

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

这真是糟糕的IMO。想象一下,我只想将我所有的例子都更靠近根源。那将是不可能的,因为我将不得不在每个示例中多次更新30多个示例。对此:

express = require('../')

我的解决方案是为基于root的情况提供特殊情况:如果字符串以$开头,则它相对于项目的根文件夹。

任何帮助表示赞赏,谢谢

更新2

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

更新3

现在,我移至webpack + gulp,并使用Enhanced-require处理服务器端的模块。请参阅此处的基本原理:http : //hackhat.com/p/110/module-loader-webpack-vs-requirejs-vs-browserify/

飞云Mandy2020/03/23 10:34:44

我们将尝试一种新方法来解决此问题。

以其他已知项目(例如spring和guice)为例,我们将定义一个“ context”对象,其中将包含所有“ require”语句。

然后,该对象将传递给所有其他模块使用。

例如

var context = {}

context.module1 = require("./module1")( { "context" : context } )
context.module2 = require("./module2")( { "context" : context } )

这就要求我们将每个模块编写为一个接收opts的函数,无论如何,这对我们来说都是一种最佳实践。

module.exports = function(context){ ... }

然后您将引用上下文,而不需要任何内容​​。

var module1Ref = context.moduel1;

如果愿意,您可以轻松编写一个循环来执行require语句

var context = {};
var beans = {"module1" : "./module1","module2" : "./module2" }; 
for ( var i in beans ){
    if ( beans.hasOwnProperty(i)){
         context[i] = require(beans[i])(context);
    }
};

当您要模拟(测试)时,这应该使工作变得更轻松,并且在使代码作为包可重用的同时解决了您的问题。

您还可以通过将bean声明与上下文初始化代码分开来重用上下文初始化代码。例如,您的main.js文件可能看起来像这样

var beans = { ... }; // like before
var context = require("context")(beans); // this example assumes context is a node_module since it is reused.. 

此方法也适用于外部库,不需要在每次需要它们时都对其名称进行硬编码-但是,由于它们的导出不是期望上下文的函数,因此将需要特殊对待。

稍后,我们还可以将bean定义为函数-允许我们require根据环境使用不同的模块-但它超出了该线程的范围。

小胖Gil2020/03/23 10:34:44

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

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

https://npmjs.org/package/rekuire

超级好用

西门Davaid2020/03/23 10:34:43

另一个答案:

想象一下这个文件夹结构:

  • node_modules
    • Lodash
  • src
    • 子目录
      • foo.js
      • bar.js
    • main.js
  • 测试

    • test.js

然后在test.js中,您需要这样的文件:

const foo = require("../src/subdir/foo");
const bar = require("../src/subdir/bar");
const main = require("../src/main");
const _ = require("lodash");

main.js中

const foo = require("./subdir/foo");
const bar = require("./subdir/bar");
const _ = require("lodash");

现在,您可以将babelbabel-plugin-module-resolver与this结合使用。babelrc文件配置2个根文件夹:

{
    "plugins": [
        ["module-resolver", {
            "root": ["./src", "./src/subdir"]
        }]
    ]
}

现在,您可以在测试src中以相同的方式要求文件

const foo = require("foo");
const bar = require("bar");
const main = require("main");
const _ = require("lodash");

并且如果要使用es6模块语法:

{
    "plugins": [
        ["module-resolver", {
            "root": ["./src", "./src/subdir"]
        }],
        "transform-es2015-modules-commonjs"
    ]
}

然后您可以像这样测试src中导入文件

import foo from "foo"
import bar from "bar"
import _ from "lodash"
TomGO2020/03/23 10:34:43

这是我六个月以上的实际工作方式。我在项目中使用名为node_modules的文件夹作为我的根文件夹,通过这种方式,它将始终在我称之为绝对需求的任何地方查找该文件夹:

  • node_modules
    • 我的项目
      • index.js我可以用require(“ myProject / someFolder / hey.js”)代替require(“ ./ someFolder / hey.js”)
      • 包含hey.js的someFolder

当您嵌套在文件夹中时,此功能将更为有用;如果以绝对方式进行设置,则更改文件位置的工作将大大减少。我在整个应用程序中只使用2个相对要求

樱路易2020/03/23 10:34:43

您可以在app.js中定义以下内容:

requireFromRoot = (function(root) {
    return function(resource) {
        return require(root+"/"+resource);
    }
})(__dirname);

and then anytime you want to require something from the root, no matter where you are, you just use requireFromRoot instead of the vanilla require. Works pretty well for me so far.

伽罗2020/03/23 10:34:43

在您自己的项目中,您可以修改根目录中使用的任何.js文件,并将其路径添加到process.env变量的属性中例如:

// in index.js
process.env.root = __dirname;

之后,您可以在任何地方访问该属性:

// in app.js
express = require(process.env.root);
LGil2020/03/23 10:34:43

恕我直言,实现此目的最简单的方法是在应用启动时创建一个指向的符号链接node_modules/app(或您所说的任何名称),该链接指向../app然后,您可以致电require("app/my/module")在所有主要平台上都可以使用符号链接。

但是,您仍然应该将内容拆分成较小的,可维护的模块,这些模块通过npm安装。您还可以通过git-url安装私有模块,因此没有理由拥有一个单一的应用程序目录。

小小伽罗2020/03/23 10:34:43

一些答案是说,最好的方法是将代码作为一个软件包添加到node_module,这可能是丢失../../../in require 的最好方法,但它们中没有一个给出了这样做的方法。

从版本开始,2.0.0您可以从本地文件安装软件包,这意味着您可以在根目录中创建包含所有所需软件包的文件夹,

-modules
 --foo
 --bar 
-app.js
-package.json

因此,在package.json中,您可以将modules(或foobar添加为一个包,而无需发布或使用外部服务器,如下所示:

{
  "name": "baz",
  "dependencies": {
    "bar": "file: ./modules/bar",
    "foo": "file: ./modules/foo"
  }
}

之后,您可以执行npm install,并且可以使用来访问代码var foo = require("foo"),就像处理所有其他软件包一样。

更多信息可以在这里找到:

https://docs.npmjs.com/files/package.json#local-paths

这里是如何创建一个包:

https://docs.npmjs.com/getting-started/creating-node-modules