gulp-babel的引用路徑問題node
gulp src 文件流路徑es6
require('xx') 路徑問題shell
本文主要講述了編寫外部構建工具中gulp-babel中依賴es2015插件失敗問題、gulp.src路徑問題以及require('xx')的路徑問題。npm
gulp的src做用是引入所須要的流,且其使用了node-glob模塊實現了文件匹配,json
gulp.src(globs[, options])
其中options對象中的屬性除了node-glob可使用的除外,還額外增長了options.buffer
,options.read
, options.base
,關於這三個額外的屬性做用能夠查看 gulp api。gulp
這裏主要介紹node-glob
中的cwd
屬性api
options.cwd Default is process.cwd()
不知道你們以前有無疑惑,咱們把gulpfile文件放在獨立於項目文件的目錄中,相似數組
~/Desktop/GIT/dada/lib/dada-task/gulpfile.js
babel
在這個文件中分別定義了項目構建相關的taskless
gulp.task("less", function() { gulp.src('./src/less/*.less', { cwd: __dirname }) .pipe(less()) .pipe(gulp.dest(srcPath.CSS)) //無視路徑 .pipe(browserSync.stream()); //無視路徑 })
接着咱們在項目目錄中調用構建命令
//項目目錄cwd /Users/lvdada/Desktop/WorkGit/05-marketing //調用 node ~/Desktop/GIT/dada/lib/dada-task/gulpfile.js
結果成功了,gulp.src('./src/less/*.less')
取的是相對路徑,照理說應該是相對於gulpfile.js
文件纔對,結果取到的文件流是項目文件中的,這就要歸功於node-glob
中的cwd
屬性了,默認狀況下,gulp.src
取到的文件都是相對process.cwd()的,也就是在命令工具中調用shell命令時的路徑。在項目目錄中調用命令的時候就至關於項目目錄。
可是這樣有個問題
.pipe(babel({ presets: ['es2015'] })) .pipe(gulp.dest('./src/js'))
此段task片斷是對gulp-babel
對es6的編譯,須要es2015
這個babel插件,此時babel的默認取文件流路徑是相對於process.cwd()的,
這就致使了會在項目目錄中尋找es2015
babel插件,確定的是是找不到的。
通過google發現瞭解決辦法,
.pipe(babel({ presets: ['babel-preset-es2015'].map(require.resolve) })) .pipe(gulp.dest('./src/js'))
對presets數組進行遍歷並執行require.resolve方法
hack來源
至於require.resolve的做用,須要瞭解一下node模塊require()
工做原理。參考阮一峯
代碼中執行require(X)時,會按照下面的順序處理引用,分紅兩種類型:
(一)第一種是帶相對路徑的引用,好比./bar.js ../bar
其中又分兩種狀況,
當作具體文件進行引用
有具體文件後綴的直接引用(相似bar.js),沒有後綴標識的會一次查找下面文件後綴類型,只要存在就返回。
- bar - bar.js - bar.json - bar.node
當作具體目錄進行引用
此時加載器會將bar當作一個目錄,並依次查找bar目錄下的文件,只要找到其中之一就返回該文件。
bar/package.json(main字段)(main字段中有引用的文件地址) bar/index.js bar/index.json bar/index.node
(二)第二種是不帶相對路徑的引用,好比require('fs') require('gulp-if')
引用是內置模塊時,好比fs,直接加載fs模塊。
引用不是內置模塊,好比gulp-if
,
則在當前路徑的父目錄逐級向上尋找node_modules文件夾,而後把gulp-if先當作具體文件按照上面的方法查找文件,若找不到,再將gulp-if當作具體目錄進行查找。具體的向上查找路徑集合能夠經過module.path
查詢。
假設一個文件test.js
console.log('module.paths: ', module.paths);
在當前目錄執行node test.js
,會輸出:
module.paths: [ '/Users/lvdada/Desktop/GIT/test/dada-test/src/js/node_modules', '/Users/lvdada/Desktop/GIT/test/dada-test/src/node_modules', '/Users/lvdada/Desktop/GIT/test/dada-test/node_modules', '/Users/lvdada/Desktop/GIT/test/node_modules', '/Users/lvdada/Desktop/GIT/node_modules', '/Users/lvdada/Desktop/node_modules', '/Users/lvdada/node_modules', '/Users/node_modules', '/node_modules' ]
若在文件系統中查詢不到require的模塊,則會在全局模塊路徑中查找。
// npm root -g /usr/local/lib/node_modules
上面介紹的文件查詢方法是基於相對路勁的,當模塊加載器要加載模塊須要肯定模塊的絕對地址。
Module._resolveFilename() // 獲得模塊的絕對地址,並由此地址加載模塊
最後node暴露出來的一個屬性和一個方法能夠獲得模塊的絕對地址:
module.filename ; var filename = request.resolve('./bar.js');
回到以前的問題,在gulp-babel中指定的babel插件沒法有效加載。
.pipe(babel({ presets: ['babel-preset-es2015'].map(require.resolve) })) .pipe(gulp.dest('./src/js'))
使用require.resolve進行路徑的查找匹配,最後得出正確的絕對路徑。
原創文章!歡迎轉載