博客
关于我
强烈建议你试试无所不能的chatGPT,快点击我
nodejs路径引用问题
阅读量:6351 次
发布时间:2019-06-22

本文共 2894 字,大约阅读时间需要 9 分钟。

nodejs路径引用问题

  1. gulp-babel的引用路径问题

  2. gulp src 文件流路径

  3. require('xx') 路径问题

本文主要讲述了编写外部构建工具中gulp-babel中依赖es2015插件失败问题、gulp.src路径问题以及require('xx')的路径问题。

gulp的src作用是引入所需要的流,且其使用了node-glob模块实现了文件匹配,

gulp.src(globs[, options])

其中options对象中的属性除了node-glob可以使用的除外,还额外增加了options.buffer ,options.read, options.base,关于这三个额外的属性作用可以查看 。

这里主要介绍node-glob中的cwd属性

options.cwdDefault is process.cwd()

不知道大家之前有无疑惑,我们把gulpfile文件放在独立于项目文件的目录中,类似

~/Desktop/GIT/dada/lib/dada-task/gulpfile.js

在这个文件中分别定义了项目构建相关的task

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()的,

这就导致了会在项目目录中寻找es2015babel插件,肯定的是是找不到的。

经过google发现了解决办法,

.pipe(babel({      presets: ['babel-preset-es2015'].map(require.resolve)    }))    .pipe(gulp.dest('./src/js'))

对presets数组进行遍历并执行require.resolve方法

至于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.jsbar/index.jsonbar/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进行路径的查找匹配,最后得出正确的绝对路径。

原创文章!欢迎转载

你可能感兴趣的文章
vue中的input使用e.target.value赋值的问题
查看>>
数据库跨库访问问题
查看>>
关于FindComponent的使用,简化一些过程
查看>>
jq动态生成数据后绑定事件
查看>>
||和 && 符号的赋值运用(转)
查看>>
post提交返回json格式
查看>>
Java.lang 包中的Void类型
查看>>
正确理解linux grep 的姿势
查看>>
网络通信协议和 tcp udp在 socket 中的区别
查看>>
大道至简阅读笔记02
查看>>
分享几款Flash和Javascript网页视频播放器,不过我钟爱JCPlayer
查看>>
Windows 7 SP1与部分程序不兼容
查看>>
黑客竞赛:甲骨文等大企业员工安全意识差
查看>>
黑客称Flash插件才是浏览器漏洞祸首
查看>>
(十五)Java B2B2C o2o多用户商城 springcloud架构 - commonservice-sso服务搭建(一)
查看>>
Stega_听会歌吧
查看>>
Console命令详解,让调试js代码变得更简单
查看>>
PHP中的闭包和匿名函数(转载)
查看>>
Angularjs基础(十)
查看>>
crontab文件的真实位置
查看>>