我想要求我的文件总是通过我的项目的根,而不是相对于当前模块。
例如,如果查看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/
我们准备尝试一种新的方法来解决这个问题。
以其他已知项目(如spring和guice)为例,我们将定义一个“context”对象,它将包含所有的“require”语句。
该对象将被传递给所有其他模块使用。
例如
var context = {}
context.module1 = require("./module1")( { "context" : context } )
context.module2 = require("./module2")( { "context" : context } )
这要求我们将每个模块编写为一个接收选项的函数,这对我们来说是一个最佳实践。
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定义为函数——这将允许我们根据环境需要不同的模块——但这超出了这个线程的范围。
在Browserify手册中有一个非常有趣的章节:
avoiding ../../../../../../..
Not everything in an application properly belongs on the public npm
and the overhead of setting up a private npm or git repo is still
rather large in many cases. Here are some approaches for avoiding the
../../../../../../../ relative paths problem.
node_modules
People sometimes object to putting application-specific modules into
node_modules because it is not obvious how to check in your internal
modules without also checking in third-party modules from npm.
The answer is quite simple! If you have a .gitignore file that
ignores node_modules:
node_modules
You can just add an exception with ! for each of your internal
application modules:
node_modules/*
!node_modules/foo
!node_modules/bar
Please note that you can't unignore a subdirectory, if the parent is
already ignored. So instead of ignoring node_modules, you have to
ignore every directory inside node_modules with the
node_modules/* trick, and then you can add your exceptions.
Now anywhere in your application you will be able to require('foo')
or require('bar') without having a very large and fragile relative
path.
If you have a lot of modules and want to keep them more separate from
the third-party modules installed by npm, you can just put them all
under a directory in node_modules such as node_modules/app:
node_modules/app/foo
node_modules/app/bar
Now you will be able to require('app/foo') or require('app/bar')
from anywhere in your application.
In your .gitignore, just add an exception for node_modules/app:
node_modules/*
!node_modules/app
If your application had transforms configured in package.json, you'll
need to create a separate package.json with its own transform field in
your node_modules/foo or node_modules/app/foo component directory
because transforms don't apply across module boundaries. This will
make your modules more robust against configuration changes in your
application and it will be easier to independently reuse the packages
outside of your application.
symlink
Another handy trick if you are working on an application where you can
make symlinks and don't need to support windows is to symlink a lib/
or app/ folder into node_modules. From the project root, do:
ln -s ../lib node_modules/app
and now from anywhere in your project you'll be able to require files
in lib/ by doing require('app/foo.js') to get lib/foo.js.
custom paths
You might see some places talk about using the $NODE_PATH
environment variable or opts.paths to add directories for node and
browserify to look in to find modules.
Unlike most other platforms, using a shell-style array of path
directories with $NODE_PATH is not as favorable in node compared to
making effective use of the node_modules directory.
This is because your application is more tightly coupled to a runtime
environment configuration so there are more moving parts and your
application will only work when your environment is setup correctly.
node and browserify both support but discourage the use of
$NODE_PATH.
如果你使用yarn而不是npm,你可以使用工作区。
假设我有一个文件夹服务,我希望更容易地需要:
.
├── app.js
├── node_modules
├── test
├── services
│ ├── foo
│ └── bar
└── package.json
要创建Yarn工作空间,需要创建一个包。services文件夹中的Json文件:
{
"name": "myservices",
"version": "1.0.0"
}
在你的主包里。json添加:
"private": true,
"workspaces": ["myservices"]
从项目的根目录运行yarn install。
然后,在代码的任何地方,你可以这样做:
const { myFunc } = require('myservices/foo')
而不是像这样:
const { myFunc } = require('../../../../../../services/foo')