.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-runcompiler.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,并没有进行包装。

 

NodeWatchFileSystem
"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写的。

转载于:https://www.cnblogs.com/QH-Jimmy/p/8041875.html

本文来自互联网用户投稿,该文观点仅代表作者本人,不代表本站立场。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如若转载,请注明出处:http://www.mzph.cn/news/399133.shtml

如若内容造成侵权/违法违规/事实不符,请联系多彩编程网进行投诉反馈email:809451989@qq.com,一经查实,立即删除!

相关文章

运行QQ出现initialization failure 0x0000000c错误和浏览器上不了网

出现QQ出现initialization failure 0x0000000c错误和浏览器上不了网的问题,原因是关机的时候没有正常关闭导致的。 解决方法: 1、我们在开始菜单栏中的附件中找到“命令提示符”,然后点击右键选择“以管理员身份运行”。 或者windowx&#xf…

Unity3D 动态加载 图片序列正反播放

参考来源 跟来源的电子图书翻页多了点细节上的变化。 using UnityEngine; using System.Collections; using System.Resources;public class MovePic : MonoBehaviour {public Texture2D[] texAll; //图片序列储存的图片组,注意需要定义这个组的size大小为图片序列…

【IT笔试面试题整理】寻找二叉树两节点的最近的公共祖先

【试题描述】 求二叉树中任意两个节点的最近公共祖先也称为LCA问题(Lowest Common Ancestor)。 二叉查找树 如果该二叉树是二叉查找树,那么求解LCA十分简单。 基本思想为:从树根开始,该节点的值为t,如果t大…

解释spring,struts,hibernate优缺点

解释spring,struts,hibernate优缺点 Struts优点:对视图层进行封装 更好的分离视图层和控制层 对数据进行封装 缺点: 1 、转到展示层时,需要配置forward,每一次转到展示层,相信大多数都是直接转到jsp,而涉及到转向&…

java单例模式的七种写法_Java设计模式之单例模式的七种写法

什么是单例模式?单例模式是一种常见的设计模式,单例模式的写法有很多种,这里主要介绍三种: 懒汉式单例模式、饿汉式单例模式、登记式单例 。单例模式有以下特点:1、单例类只能有一个实例。2、单例类必须自己创建自己唯…

在Hadoop集群上,搭建HBase集群

(1)下载Hbase包,并解压:这里下载的是0.98.4版本,对应的hadoop-1.2.1集群 (2)覆盖相关的包:在这个版本里,Hbase刚好和Hadoop集群完美配合,不需要进行覆盖. 不过这里写了个覆盖的脚本,可以留着备用. find -name hadoop*jar | sed s/2.2.0/2.3.0/g | sed s/.\///g > f.log rm .…

java js跳出循环_[Java教程]js循环的总结

[Java教程]js循环的总结02016-10-07 15:00:14js原生的循环有两种&#xff0c;一般的for循环和for...in循环。还有一种常用jQuery.each()循环。一. js原生循环a. for循环&#xff0c;代码如下&#xff1a;var myArray [1,2,3];for (var i 0; i < myArray.length; i) {conso…

Beta版本冲刺

1.凡事预则立&#xff0c;在Beta开始前&#xff0c;以小组为单位&#xff0c;在敏捷冲刺前发布一篇博客&#xff0c;描述&#xff1a; a. 下一阶段需要改进完善的功能&#xff1a; 无 b. 下一阶段新增的功能 修改密码功能 管理员功能 生成表格的优化 c. 需要改进的团队分工&…

Struts2国际化

一&#xff1a;简单理解 国际化简称i18n&#xff0c;其来源是英文单词 internationalization的首末字符i 和n。18为中间的字符数。 随着全球经济的一体化&#xff0c;软件开发者应该开发出支持多国语言、国际化的Web应用。对于Web应用来说&#xff0c;同样的页面在不同的语言环…

NOI经验谈

对于NOI来说&#xff0c;甚至比硬实力更加重要。我觉得一场考试这么几件事要做&#xff1a;看题&#xff0c;选题&#xff0c;分析&#xff0c;编码&#xff0c;调试&#xff0c;测试&#xff0c;骗分。 1、看题 拿到试卷以后的第一件事就是看题。看题不是看小说&#xff0c;要…

ReactiveCocoa源码拆分解析(四)

&#xff08;整个关于ReactiveCocoa的代码工程可以在https://github.com/qianhongqiang/QHQReactive下载&#xff09; 上一章节简要的说明了如何实现的热信号。但是像那么写&#xff0c;貌似不是非常优雅。这一章节我们会把冷热信号转换写的跟ReactiveCocoa一样优雅。 Reactive…

用Emacs编写mybatis

<?xml version"1.0" encoding"utf-8"?> 用Emacs编写mybatis用Emacs编写mybatis Table of Contents 1. 效果图2. 配置1 效果图 2 配置 现在web开发&#xff0c;最流行的orm框架非mybatis莫属了&#xff0c;它功能强大&#xff0c;编写简单灵活&…

lambda显式声明返回值

10.21 编写一个lambda&#xff0c;捕获一个局部int变量&#xff0c;并递减变量值&#xff0c;直至它变为0.一旦变量变为0&#xff0c;再调用lambda应该不再递减变量。lambda应该返回一个bool值&#xff0c;指出捕获的变量是否为0. #include<iostream> #include<algori…

【Codeforces Round #452 (Div. 2) C】 Dividing the numbers

【链接】 我是链接,点我呀:) 【题意】 在这里输入题意 【题解】 n为偶数。 l 1, r n (l,r)放在一组 l,r-- 新的l,r放在另外一组 直到l1r 这个时候,判断两组的和,如果一样的话,分散在两组 差为1否则差为0n为奇数 l 2,r n (l,r)放在一组 l,r-- 新的l,r放在另外一组 直到l1r…

java中reject方法作用_Java BindingResult.rejectValue方法代碼示例

本文整理匯總了Java中org.springframework.validation.BindingResult.rejectValue方法的典型用法代碼示例。如果您正苦於以下問題&#xff1a;Java BindingResult.rejectValue方法的具體用法&#xff1f;Java BindingResult.rejectValue怎麽用&#xff1f;Java BindingResult.r…

java方法参数

Java程序设计语言总是采用值调用。也就是说&#xff0c;方法得到的是所有参数的一个拷贝&#xff0c;特别是方法不能修改传递给它的任何参数变量的内容。 基本类型参数 1&#xff09;X被初始化为percent值的一个拷贝&#xff1b; 2&#xff09;X被乘以3等于30。但是percent仍然…

SaltStack源码分析之:master端执行salt模块大致流程

2019独角兽企业重金招聘Python工程师标准>>> ##JOB执行流程 先看下官网对于master端的工作流程的介绍&#xff1a; The Salt master works by always publishing commands to all connected minions and the minions decide if the command is meant for them by ch…

myecplise新建Maven项目Filter选什么,使用myeclipse建立maven项目

myecplise新建Maven项目Filter选什么 使用myeclipse建立maven项目 1234567分步阅读maven是管理项目的&#xff0c;myeclipse是编写代码的。第一次写项目都要配置好多东西&#xff0c;很麻烦&#xff0c;now 来看看怎样新建一个maven项目。 工具/原料 myeclipsemaven方法/步骤 1…

python参数传递时不构造新数据对象_关于函数的参数传递(parameter passing),以下选项中描述错误的是_学小易找答案...

【单选题】下面代码的输出结果是: a [] for i in range(2,10): count 0 for x in range(2,i-1): if i % x 0: count 1 if count 0: a.append(i) print(a)【单选题】Python3.0正式发布的年份是【单选题】以下选项中,对于函数的定义错误的是【单选题】关于函数的参数传递(pa…