使用Node.js爲require設置別名(alias)

使用Node.js爲require設置別名(alias)

前言

因爲本包包是個很懶惰的人,而後咱們有些個項目設計的不是很好,因此致使寫代碼的時候有不少這樣的代碼:javascript

require('../../../../../../foo.js');

寫的時候數那個小點點感受人都要死了?

這種時候若是寫node能像用了webpack(and so on)那樣可以require別名就行了。
好比這樣:java

require('modules/foo.js');

因而我搜尋了幾種方法。node

來自branneman總結的方法

如下內容來自於github上一名叫作branneman的同志的總結,我爲他的內容進行了隨性的翻譯webpack

原文可查看這裏git

1. Symlink

"偷"自focusaurus / express_code_structure # the-app-symlink-trickgithub

  1. 在應用的node_modules文件夾下面建立一個symlink
  • Linux: ln -nsf node_modules app
  • Windows: mklink /D app node_modules
    (叉燒包註釋:若是你在應用的目錄下,應該使用,以bash爲例cd node_modules && ln -nsf [模塊路徑],耍的時候請把app換成你要複製的模塊的路徑)

而後你就能夠web

var Article = require('app/article');

小貼士:因爲git不能處理跨平臺的symlinks,因此你不能再git repo裏面用這樣的文件。不過若是你是在克隆後、git-hook或者是由開發人員手動建立一個symlink,那就沒啥問題shell

另外,你能夠在npm裏面裏面增長一條postinstall鉤子,這個方法由scharf提出。能夠把命令加進package.json裏面express

"scripts": {
    "postinstall" : "node -e \"var s='../src',d='node_modules/src',fs=require('fs');fs.exists(d,function(e){e||fs.symlinkSync(s,d,'dir')});\""
  }

(叉燒包註釋:postinstall會在npm run install前先自動執行)npm

2. 全局變量

在你的app裏面增長

global.__base = __dirname + '/';

這樣你就能夠這樣用了

var Article = require(__base + 'app/models/article');

3. 使用別人開發的庫

這裏下面再作推薦

4. 環境變量

設置環境變量NODE_PATH成一個指向你app想用的模塊的路徑(做者的狀況下是.)。
(叉燒包註釋:最好是使用絕對路徑,這樣比較穩妥)

而後就能夠

var Article = require('app/models/article');

4.1 提早設置

在啓動app前線確保已經設置好了環境變量

  • Linux: export NODE_PATH=.
  • Windows: set NODE_PATH=.

使用exportset是僅對當前shell有效的,若是你須要讓他全局、永久的改變,須要修改你的配置文件

4.2 只在執行node時設置

這個方法不會影響你的環境,除非node運行。他須要你改變應用啓用命令。

像這樣啓動你的app

  • Linux: NODE_PATH=. node app.js
  • Windows: cmd.exe /C "set NODE_PATH=.&& node app.js"

(在win下面若是你在path和&&之間加空格的話就啓動不了)
(叉燒包註釋:這裏推薦一下cross-env插件,能夠跨平臺使用命令,這樣的話就能夠用這樣使用命令啦~ cross-env NODE_PATH=. node app.js

5. 啓用腳本

其實和4.2差很少

其實就是寫成一個腳原本運行,不過這樣比較方便加各類參數

例:

  • Linux: ./app (Windows PowerShell可)
  • Windows: app

5.1 Node.js

這裏
代碼具體是這樣

#!/usr/bin/env node

'use strict';

var spawn = require('child_process').spawn;

var args = [
  '--harmony',
  'app/bootstrap.js'
];

var opt = {
  cwd: __dirname,
  env: (function() {
    process.env.NODE_PATH = '.'; // Enables require() calls relative to the cwd :)  
    //叉燒包註釋: 若是須要多個路徑能夠這樣(須要額外 require path 模塊)
    //process.env.NODE_PATH = ['.', './lib'].join(path. delimiter)
    return process.env;
  }()),
  stdio: [process.stdin, process.stdout, process.stderr]
};

var app = spawn(process.execPath, args, opt);

5.2 操做系統特定的啓動腳本

  • Linux
    能夠建立一個app.sh
#!/bin/sh
NODE_PATH=. node app.js
  • Windows
    能夠建立一個app.bat
@echo off
cmd.exe /C "set NODE_PATH=.&& node app.js"

6. Hack

謝謝@joelabair和4.2差很少,但不須要在app以外指定NODE_PATH。可是,因爲這依賴於一個專用的Node.js核心方法。
你須要在require以前運行這個方法。

process.env.NODE_PATH = __dirname;
require('module').Module._initPaths();

7. 包裹

感謝@a-ignatov-parc
簡單來講你能夠在你的app最開始運行這樣的代碼。

global.rootRequire = function(name) {
    return require(__dirname + '/' + name);
}

而後就能夠這樣

var Article = rootRequire('app/models/article');

叉燒包總結

基於個人原則一貫來就是越快越好,打字越少越好,因此我的認爲

  • symlink的方式因爲各類限制並且你增長一點你的包就得新生產一個,感受比較的不爽 => pass
  • 增長全局變量,可是還須要本身拼接一下,難受 => pass
  • 環境變量,我比較能接受寫一份腳本的方法 0-0
  • Hack方法,這個我比較的喜歡, 使用時也和原生同樣
  • 包裹方法在require時比較難受,我喜歡能直接require…so => pass

包子的方法

1. 修改啓用命令

這個上面也提到過4和5中也提到過。

在啓用時這樣操做NODE_PATH=. node app.js

不過得考慮到不一樣操做系統下面path分割符的問題,因此我的推薦是採用5.1中的方法,寫一份node腳本

2. HACK

我hack了_findPath()方法,這個就是想設成啥別名就啥別名w,只不過只能兼容到node6

已經封裝成插件node-require-alias,在這裏自薦一下。
使用方法:

const path = require("path")
require('node-require-alias').setAlias({
    "@": path.join(__dirname, "this/is/a/path")
})
// or require('node-require-alias').setAlias("@", path.join(__dirname, "this/is/a/path"))

require模塊時候↓

require('@/abc.js')

歡迎來PR(づ ̄3 ̄)づ╭❤~

其餘人的方法

  • hack了require方法,這個和我想的hack差很少,可是這樣兼容性比較好。code看這裏。這個做者也封裝成了一個插件,你們能夠去支持一下sexy-require。這邊的別名是配置在package.json下面的
  • 還有hack了export方法的,經過Object.defineProperty,在get方法時給模塊的添加必要的屬性
  • babel-plugin-resolver。這個本包卻是沒有細去了解,因此使用的小夥伴能夠本身看一下

插件推薦

各位有用過別的歡迎在評論裏面告訴我喲~(@^_^@)~

使用起來和原生沒有差異的

  • 先羞羞的安利一下本身的插件node-require-alias, node6.0環境以上的考慮一下
  • 還有是經過讀package.json配置的sexy-require
  • module-alias這個讀package.json和經過方法均可以設置別名

使用起來和原生有差異的

由於我我的比較嫌棄這種寫法,這裏就不作介紹了,只作推薦

最後的總結

我我的比較的做,喜歡本身寫仍是比較喜歡HACK!不過我以爲加環境變量也很快,也不用管兼容b( ̄▽ ̄)d。

另外對於HACK方法我還作了十分隨性的原理解析,你們想看的能夠戳這裏

相關文章
相關標籤/搜索