我想要求我的文件总是通过我的项目的根,而不是相对于当前模块。
例如,如果查看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/
我喜欢为共享代码创建一个新的node_modules文件夹,然后让node和require做它最擅长的事情。
例如:
- node_modules // => these are loaded from your package.json
- app
- node_modules // => add node-style modules
- helper.js
- models
- user
- car
- package.json
- .gitignore
例如,如果你在car/index.js中,你可以require('helper'), node会找到它!
node_modules如何工作
Node有一个在竞争对手中独一无二的解决模块的聪明算法
平台。
如果你从/beep/boop/bar.js中require('./foo.js'), node会在/beep/boop/foo.js中寻找。/foo.js。以./或..开头的路径/对于调用require()的文件总是本地的。
然而,如果你需要一个非相对名称,例如require('xyz')来自/beep/boop/foo.js, node会按顺序搜索这些路径,在第一次匹配时停止,如果没有找到就会引发错误:
/beep/boop/node_modules/xyz
/beep/node_modules/xyz
/node_modules/xyz
对于每个存在的xyz目录,node将首先查找一个xyz/包。查看是否存在一个“main”字段。“main”字段定义了如果你需要()目录路径,哪个文件应该负责。
例如,如果/beep/node_modules/xyz是第一个匹配,那么/beep/node_modules/xyz/package。json有:
{
"name": "xyz",
"version": "1.2.3",
"main": "lib/abc.js"
}
然后从/beep/node_modules/xyz/lib/abc.js中导出的文件将被返回
要求(“xyz”)。
如果没有包裹。Json或没有“main”字段,index.js是假设的:
/beep/node_modules/xyz/index.js
我喜欢为共享代码创建一个新的node_modules文件夹,然后让node和require做它最擅长的事情。
例如:
- node_modules // => these are loaded from your package.json
- app
- node_modules // => add node-style modules
- helper.js
- models
- user
- car
- package.json
- .gitignore
例如,如果你在car/index.js中,你可以require('helper'), node会找到它!
node_modules如何工作
Node有一个在竞争对手中独一无二的解决模块的聪明算法
平台。
如果你从/beep/boop/bar.js中require('./foo.js'), node会在/beep/boop/foo.js中寻找。/foo.js。以./或..开头的路径/对于调用require()的文件总是本地的。
然而,如果你需要一个非相对名称,例如require('xyz')来自/beep/boop/foo.js, node会按顺序搜索这些路径,在第一次匹配时停止,如果没有找到就会引发错误:
/beep/boop/node_modules/xyz
/beep/node_modules/xyz
/node_modules/xyz
对于每个存在的xyz目录,node将首先查找一个xyz/包。查看是否存在一个“main”字段。“main”字段定义了如果你需要()目录路径,哪个文件应该负责。
例如,如果/beep/node_modules/xyz是第一个匹配,那么/beep/node_modules/xyz/package。json有:
{
"name": "xyz",
"version": "1.2.3",
"main": "lib/abc.js"
}
然后从/beep/node_modules/xyz/lib/abc.js中导出的文件将被返回
要求(“xyz”)。
如果没有包裹。Json或没有“main”字段,index.js是假设的:
/beep/node_modules/xyz/index.js
我认为你不需要用你描述的方式来解决这个问题。如果您想在大量文件中更改相同的字符串,请使用sed。在你的例子中,
find . -name "*.js" -exec sed -i 's/\.\.\/\.\.\//\.\.\//g' {} +
/../变成了../
或者,您可以要求配置文件存储包含库路径的变量。如果您将以下文件存储为config.js在示例目录中
var config = {};
config.path = '../../';
在你的例子文件中
myConfiguration = require('./config');
express = require(config.path);
您将能够从一个文件控制每个示例的配置。
这只是个人喜好。
大局
这看起来“真的很糟糕”,但要给它时间。事实上,它真的很好。显式的require()提供了完全的透明性和易于理解,就像项目生命周期中的一股新鲜空气。
可以这样想:你正在阅读一个例子,尝试Node.js,你认为它“在我看来真的很糟糕”。你在质疑Node.js社区的领导者,他们比任何人都花了更多的时间来编写和维护Node.js应用程序。作者犯这样一个新手错误的可能性有多大?(我同意,从我的Ruby和Python背景来看,乍一看这像是一场灾难。)
围绕Node.js有很多炒作和反炒作。但是当尘埃落定后,我们将承认显式模块和“本地优先”包是采用的主要驱动力。
一般情况
当然,首先搜索当前目录中的node_modules,然后是父目录、祖父目录、曾祖父目录等等。所以您已经安装的包已经以这种方式工作了。通常你可以从项目中的任何地方要求(“express”),它工作得很好。
如果您发现自己正在从项目的根目录加载公共文件(可能是因为它们是公共实用程序函数),那么这就是一个很大的线索,说明是时候创建包了。包非常简单:将文件移动到node_modules/,并放入package.json
在那里。瞧!整个项目都可以访问该名称空间中的所有内容。包是将代码放入全局名称空间的正确方法。
其他解决方法
我个人不使用这些技巧,但它们确实回答了你的问题,当然你比我更了解自己的情况。
您可以将$NODE_PATH设置为项目根目录。当您需要()时,将搜索该目录。
接下来,您可以折衷一下,从所有示例中要求一个通用的本地文件。该通用文件只是重新导出祖父目录中的真实文件。
Examples /downloads/app.js(以及其他类似的文件)
var express = require('./express')
/下载/ express.js例子
module.exports = require('../../')
现在当你重新定位这些文件时,最坏的情况是修复一个垫片模块。
只是想继续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将不再看到符号链接。
如果你使用ES5语法,你可以使用asapp。对于ES6,你可以使用babel-plugin-module-resolver,使用如下配置文件:
.babelrc
{
"plugins": [
["module-resolver", {
"root": ["./"],
"alias": {
"app": "./app",
"config": "./app/config",
"schema": "./app/db/schemas",
"model": "./app/db/models",
"controller": "./app/http/controllers",
"middleware": "./app/http/middleware",
"route": "./app/http/routes",
"locale": "./app/locales",
"log": "./app/logs",
"library": "./app/utilities/libraries",
"helper": "./app/utilities/helpers",
"view": "./app/views"
}
}]
]
}