.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,所以这 ...
随机推荐
- 使用bower init创建bower.json文件
使用bower init 可以快速创建bower.json文件 bower init 回答一系列问题后就可以了,其中大部分问题可以按enter跳过.
- 分布式数据库TiDB的部署
转自:https://my.oschina.net/Kenyon/blog/908370 一.环境 CentOS Linux release 7.3.1611 (Core)172.26.11.91 ...
- Brave Game(裸的巴什博弈)
Brave Game Time Limit: 1000/1000 MS (Java/Others) Memory Limit: 32768/32768 K (Java/Others) Total Su ...
- scanf和cin性能的比较
我的实验机器配置是: 处理器:Intel(R) Core(TM) i3-7100U CPU @ 2.40GHz 2.40GHz 随机访问存储器:4.00GB 操作系统:Windows10 集成开发环境 ...
- Maven合并多个war包的工程需要用到的插件
<build> <finalName>WebSite</finalName> <plugins> <!-- 配置war包合并的插件 --> ...
- Vue.js优雅的实现列表清单
一.Vue.js简要说明 Vue.js (读音 /vjuː/) 是一套构建用户界面的渐进式框架.与前端框架Angular一样, Vue.js在设计上采用MVVM模式,当View视图层发生变化时 ...
- SQL server中事务的四个属性特征(ACID)
事务的概念.类型和四个特征(ACID). 1.事务(Transaction)是并发控制的单位,是用户定义的一个操作序列.这些操作要么都做,要么都不做,是一个不可分割的工作单位. 通过事务,SQL Se ...
- JS中!=、==、!==、===的用法和区别
1.对于string,number等基础类型,==和===是有区别的 1)不同类型间比较,==之比较"转化成同一类型后的值"看"值"是否相等,===如果类型不同 ...
- JS小游戏:贪吃蛇(附源码)
javascript小游戏:贪吃蛇 此小游戏采用的是面向对象的思想,将蛇,食物,和游戏引擎分为3个对象来写的. 为方便下载,我把js写在了html中, 源码中暂时没有注释,等有空我在添加点注释吧. 游 ...
- Java中static关键字的详解
static关键字可以修饰方法和成员变量(不可以修饰局部变量,但是可以修饰内部类). static关键字方便在没有创建对象的情况下来进行调用(方法/变量). 很显然,被static关键字修饰的方法或者 ...