.9-浅析webpack源码之NodeEnvironmentPlugin模块总览
介绍Compiler的构造比较无趣,不如先过后面的,在用到compiler的时候再做讲解。
这一节主要讲这行代码:
// 不管这里
compiler = new Compiler();
compiler.context = options.context;
compiler.options = options;
// 看这里
new NodeEnvironmentPlugin().apply(compiler);
这个构造了一个NodeEnvironmentPlugin对象并调用apply对compiler进行操作。
流程图:

模块源码如下:
"use strict";
const NodeWatchFileSystem = require("./NodeWatchFileSystem");
const NodeOutputFileSystem = require("./NodeOutputFileSystem");
const NodeJsInputFileSystem = require("enhanced-resolve/lib/NodeJsInputFileSystem");
const CachedInputFileSystem = require("enhanced-resolve/lib/CachedInputFileSystem");
class NodeEnvironmentPlugin {
apply(compiler) {
// 可以缓存输入的文件系统
compiler.inputFileSystem = new CachedInputFileSystem(new NodeJsInputFileSystem(), 60000);
const inputFileSystem = compiler.inputFileSystem;
// 输出文件系统
compiler.outputFileSystem = new NodeOutputFileSystem();
// 监视文件系统
compiler.watchFileSystem = new NodeWatchFileSystem(compiler.inputFileSystem);
// 添加事件流before-run
compiler.plugin("before-run", (compiler, callback) => {
if (compiler.inputFileSystem === inputFileSystem)
inputFileSystem.purge();
callback();
});
}
}
module.exports = NodeEnvironmentPlugin;
除去添加事件流,其余几步都是在compiler对象上挂载node的fs文件系统,详细的API用法可以去nodejs官网看文档:https://nodejs.org/dist/latest-v8.x/docs/api/
这里只做简介:
NodeJsInputFileSystem
var fs = require("graceful-fs");
module.exports = NodeJsInputFileSystem;
// 获取文件信息
NodeJsInputFileSystem.prototype.stat = fs.stat.bind(fs);
// 读取目录内容
NodeJsInputFileSystem.prototype.readdir = function readdir(path, callback) {
// files 是目录中不包括 '.' 和 '..' 的文件名的数组
fs.readdir(path, function(err, files) {
callback(err, files && files.map(function(file) {
// 对文件名进行NFC格式化
return file.normalize ? file.normalize("NFC") : file;
}));
});
};
// 读取文件
NodeJsInputFileSystem.prototype.readFile = fs.readFile.bind(fs);
// 读取链接
NodeJsInputFileSystem.prototype.readlink = fs.readlink.bind(fs);
// 同步方法
NodeJsInputFileSystem.prototype.statSync = fs.statSync.bind(fs);
NodeJsInputFileSystem.prototype.readdirSync = function readdirSync(path) {/**/};
NodeJsInputFileSystem.prototype.readFileSync = fs.readFileSync.bind(fs);
NodeJsInputFileSystem.prototype.readlinkSync = fs.readlinkSync.bind(fs);
可以看到,这里只是对引入的graceful-js的部分方法进行bind绑定,大概看一下graceful-fs的内容:
var fs = require('fs')
// ...工具方法
module.exports = patch(require('./fs.js'))
if (process.env.TEST_GRACEFUL_FS_GLOBAL_PATCH) {
module.exports = patch(fs)
}
module.exports.close = fs.close = (function(fs$close) { /*...*/ })(fs.close)
module.exports.closeSync = fs.closeSync = (function(fs$closeSync) { /*...*/ })(fs.closeSync)
function patch(fs) {
// fs方法二次封装
return fs
}
跟名字一样,内部调用了一个patch对fs模块进行二次封装,变得更加'优雅'。
NodeOutputFileSystem
"use strict";
const fs = require("fs");
const path = require("path");
const mkdirp = require("mkdirp");
class NodeOutputFileSystem {
constructor() {
// 新建多层级文件夹
this.mkdirp = mkdirp;
// 新建单个文件夹
this.mkdir = fs.mkdir.bind(fs);
// 删除文件夹
this.rmdir = fs.rmdir.bind(fs);
// 删除文件
this.unlink = fs.unlink.bind(fs);
// 将内容写进某个文件
this.writeFile = fs.writeFile.bind(fs);
// 略
this.join = path.join.bind(path);
}
}
module.exports = NodeOutputFileSystem;
这个模块就十分亲民,都是原生的nodeAPI,并没有进行包装。
"use strict";
const Watchpack = require("watchpack");
class NodeWatchFileSystem {
constructor(inputFileSystem) {
this.inputFileSystem = inputFileSystem;
this.watcherOptions = {
aggregateTimeout: 0
};
this.watcher = new Watchpack(this.watcherOptions);
}
// 对文件进行监视
watch(files, dirs, missing, startTime, options, callback, callbackUndelayed) { /*...*/ }
}
module.exports = NodeWatchFileSystem;
模块内容比较简单,引入一个inputFileSystem进行初始化监视对象,原型上只有一个watch方法。(实际内容非常深入和繁杂,后面再讲)
这个模块主要是为了接下来输出打包文件做准备,主要内容大部分是nodejs相关。
不过没关系,都是用JS写的。
.9-浅析webpack源码之NodeEnvironmentPlugin模块总览的更多相关文章
- .12-浅析webpack源码之NodeWatchFileSystem模块总览
剩下一个watch模块,这个模块比较深,先大概过一下整体涉及内容再分部讲解. 流程图如下: NodeWatchFileSystem const Watchpack = require("wa ...
- .3-浅析webpack源码之预编译总览
写在前面: 本来一开始想沿用之前vue源码的标题:webpack源码之***,但是这个工具比较巨大,所以为防止有人觉得我装逼跑来喷我(或者随时鸽),加上浅析二字,以示怂. 既然是浅析,那么案例就不必太 ...
- .6-浅析webpack源码之validateSchema模块
validateSchema模块 首先来看错误检测: const webpackOptionsValidationErrors = validateSchema(webpackOptionsSchem ...
- .4-浅析webpack源码之convert-argv模块
上一节看了一眼预编译的总体代码,这一节分析convert-argv模块. 这个模块主要是对命令参数的解析,也是yargs框架的核心用处. 生成默认配置文件名数组 module.exports = fu ...
- .15-浅析webpack源码之WebpackOptionsApply模块-plugin事件流总览
总体过了一下后面的流程,发现Compiler模块确实不适合单独讲解,这里继续讲解后面的代码: compiler.options = new WebpackOptionsApply().process( ...
- .14-浅析webpack源码之Watchpack模块
解决掉了最头疼的DirectoryWatcher内部实现,这一节可以结束NodeWatchFileSystem模块. 关于watch的应用场景,仔细思考了下,这不就是热重载的核心嘛. 首先是监视文件, ...
- .13-浅析webpack源码之WatcherManager模块
从模块流可以看出,这个NodeWatchFileSystem模块非常深,这里暂时不会深入到chokidar模块,有点太偏离本系列文章了,从WatcherManager开始讲解. 流程如图: 源码非常简 ...
- .11-浅析webpack源码之Storage模块
至此已完成NodeJsInputFileSysten模块的讲解,下一步就是实际实用的模块: compiler.inputFileSystem = new CachedInputFileSystem(n ...
- .10-浅析webpack源码之graceful-fs模块
在cachedInput.output.watch三大文件系统中,output非常简单,没有必要讲,其余两个模块依赖于input模块,而input主要是引用了graceful-fs的部分API,所以这 ...
随机推荐
- angular指令的4种设计模式
指令的功能集非常丰富,不过我们已经发现了指令的帕累托分布:使用angular编写的大量指令只会用到可用性和设计模式中很小的比例,这些指令大概可以分为4类: 只渲染指令--这些指令将渲染作用域中的数据, ...
- idea tomee required to support ear ejb deployment问题
先删掉原来的uname,然后添加项目即可
- SQLAlchemy复杂查询
最近个人用python + flask搞了一个小项目,ORM用到的是SQLAlchemy. SQLAlchemy的查询方式非常灵活,你所能想像到的复杂SQL 语句,基本上都可以实现.这里简单的总结 ...
- Unity 游戏框架搭建 (七) 减少加班利器-QApp类
本来这周想介绍一些框架中自认为比较好用的小工具的,但是发现很多小工具都依赖一个类----App. App类的职责: 1.接收Unity的生命周期事件. 2.做为游戏的入口. 3.一些框架级别的组件初始 ...
- geolocation h5
navigator. geolocation.getCurrentPosition() 触发浏览器弹窗询问用户同意访问地址.接收三个参数:成功回调函数,可选的失败回调,可选选项对象 成功回调函数接 ...
- Number 类型
Javascript使用IEEE -754格式存储整型和浮点型(有些语言称为双精度) 因为这种存储格式,所以javascript中有正的0和负的0 整型也可以存储八进制和十六制 八进制第一个数 ...
- 2000W条数据,加入全文检索的总结
一) 前期准备测试: 旧版的MySQL的全文索引只能用在MyISAM表格的char.varchar和text的字段上. 不过新版的MySQL5.6.24上InnoDB引擎也加入了全文索引,所以具体信息 ...
- C#继承中的override(重写)与new(覆盖)用法
刚接触C#编程,我也是被override与new搞得晕头转向.于是花了点时间翻资料,看博客,终于算小有领悟,把学习笔记记录于此. 首先声明一个父类Animal类,与继承Animal的两个子类Dog类与 ...
- 轻松驾驭Tomcat
Tomcat 服务器是一个免费的开放源代码的Web 应用服务器,属于轻量级应用服务器,在中小型系统和并发访问用户不是很多的场合下被普遍使用,是开发和调试JSP 程序的首选.对于一个初学者来说,可以这样 ...
- 团队工作准则&贡献分配规则
团队工作准则&贡献分配规则 NewTeam 2017/10/24 v1.0 工作准则及内容 全体成员 所有成员在接受任务时应结合自身情况考虑,如果认为任务内容或时间有不合理之处应当立即提出修改 ...