2017-06-22 40 views
0

我是一種JavaScript編程的新手。目前,我正在嘗試爲包含其他編程語言的現有代碼庫編寫Javascript文件的測試。結構如下所示。如何根據調用者腳本的路徑動態解析nodejs所需的模塊路徑?

src/js/path1/path2/path3/path4/path5/ 
    Rectangle.jsx 
    Circle.jsx 
test/js/path1/path2/path3/path4/path5/ 
    RectangleTest.jsx 
    CircleTest.jsx 

RectangleTest.jsx含量低於

import Rectangle from './../../../../../../../src/js/path1/path2/path3/path4/path5/Rectangle'; 

describe('<Rectangle>',() => { 
    it('Should show content',() => { 
     assert.ok(true); 
    }); 
}); 

正如你所看到的,我需要設置路徑很長的相對路徑./../../../../../../../src/js/path1/path2/path3/path4/path5。這將是非常詳盡的,我喜歡下面的東西。

import Rectangle from './Rectangle'; 

由於測試文件和測試文件的路徑是非常相似的,它應該是可以計算的路徑,通過進口來解決。

有沒有辦法做到這一點?

我正在使用mocha作爲測試框架。我將示例代碼上傳到Github(link),以便您可以看到它。

回答

0

研究有關如何的NodeJS解決模塊後,原來可以通過重寫module模塊來覆蓋require函數行爲。

所以我寫了一個名爲bootstrap.js文件,其中包含以下

let path = require('path'); 
const BASE_DIR = __dirname; 
const SRC_DIR = path.resolve(BASE_DIR + '/../../src/js'); 
var Module = require('module'); 
Module.prototype.require = new Proxy(Module.prototype.require, { 
    apply(target, thisArg, argumentsList){ 
     let name = argumentsList[0]; 
     let isLocal = thisArg.filename.startsWith(BASE_DIR) && 
      name.startsWith('./'); 
     if (isLocal) { 
      let testFileDir = path.dirname(thisArg.filename) 
      let testPath = testFileDir.replace(BASE_DIR, ''); 
      let srcPath = SRC_DIR + testPath; 
      let relativePath = path.relative(testFileDir, srcPath); 
      argumentsList[0] = relativePath + '/' + name; 
     } 
     return Reflect.apply(target, thisArg, argumentsList) 
    } 
}); 

代碼的結構,現在是這樣的

src/js/path1/path2/path3/path4/path5/ 
    Rectangle.jsx 
    Circle.jsx 
test/js/ 
    bootstrap.js 
    path1/path2/path3/path4/path5/ 
     RectangleTest.jsx 
     CircleTest.jsx 

執行測試,我用下面

nyc mocha --recursive \ 
    --require test/js/bootstrap.js \ 
    --compilers js:babel-core/register \ 
    test/js/**/*.{js,jsx}  
聲明

使用上面的代碼,我可以檢查調用者腳本和調用模塊並查看調用者腳本是否駐留在test目錄中。如果確實如此,它將通過使用相對路徑來查看模塊是否被調用。

好處是,我們仍然可以使用import聲明。

import Rectangle from './Rectangle'; 

describe('<Rectangle>',() => { 
    it('Should show content',() => { 
     assert.ok(true); 
    }); 
}); 

缺點是對於現在的測試文件不能調用test目錄的相對路徑。相對路徑現在只能在源路徑中解析。但現在好了。我想知道我們是否可以檢查一個模塊是否可以解析。

更新的源代碼可以讀here

0

您可以使用__dirname全局節點變量,其中包含當前文件的絕對路徑。但是,您必須使用require()而不是import ...,因爲導入不支持動態路徑。

如果你的絕對路徑只包含一個測試名稱,你可以逃脫:

const path = require('path'); 
const retanglePath = path.join(__dirname.replace('/test/', '/src/'), 'Rectangle')); 
const Rectangle = require(rectanglePath).default; 

注:.default是ES6出口已轉換與巴貝爾。

希望這會有所幫助。

編輯:這是一個解決方案,也可以與其他的測試文件夾名稱中的絕對路徑(路徑相對滿足您的需要替換):

const path = require('path'); 
const basePath = path.join(__dirname, '../../../../'); 
const srcPath = __dirname.replace(basePath + 'test', basePath + 'src'); 
const Rectangle = require(path.join(srcPath, 'Rectangle')).default;