.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,一经查实,立即删除!

相关文章

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

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

Struts2国际化

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

用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;编写简单灵活&…

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…

关于TCP/IP与数据传输

一、TCP/IP的具体含义&#xff1a; 从字面意思来讲&#xff0c;很多人会认为TCP/IP是指TCP与IP这两种协议。有时确实也可以说是这两种协议&#xff0c;但是大部分情况下所说的是利用IP进行通信时所必须用到的协议群的统称。具体来说IP,ICMP,TCP,UDP,FTP以及HTTP等都属于TCP/IP协…

geohash php_空间索引-geohash算法实现

算法简介geohash是实现空间索引的一种算法,其他实现空间索引的算法有:R树和其变种GIST树、四叉树、网格索引等算法基本原理geohash算法将地球理解为一个二维平面&#xff0c;将平面递归分解成更小的子块&#xff0c;每个子块在一定经纬度范围内拥有相同的编码&#xff0c;这种方…

ActiveReports 报表控件V12新特性 -- 新增JSON和CSV导出

ActiveReports 报表控件V12新特性 -- 新增JSON和CSV导出 ActiveReports 是一款专注于 .NET 平台的报表控件&#xff0c;全面满足 HTML5 / WinForms / ASP.NET / ASP.NET MVC / WPF 等平台下报表设计和开发工作需求&#xff0c;作为专业的报表工具为全球超过 300,000 开发人员提…

php imap配置,怎么为PHP编译imap扩展?

为PHP编译imap扩展的方法&#xff1a;首先安装“imap-open2007e”&#xff1b;然后下载源代码&#xff1b;接着准备好系统的“imap-open”环境&#xff1b;最后进入“./ext/extension/imap/”文件夹下执行“make”命令即可。怎么为PHP编译imap扩展&#xff1f;最近为项目增加了…

vmware安装minimal centos报错/etc/rc5.d/s99local : line

2019独角兽企业重金招聘Python工程师标准>>> 有人用vmware安装minimal centos报错/etc/rc5.d/s99local : line:25 : eject : command not found 。我们看下完整报错内容&#xff1a; Installing VMware Tools, please wait...mount: special device /dev/hda does n…

后缀树(Suffix Trie)子串匹配结构

Suffix Trie 又称后缀Trie或后缀树。它与Trie树的最大不同在于&#xff0c;后缀Trie的字符串集合是由指定字符串的后缀子串构成的。比如、完整字符串"minimize"的后缀子串组成的集合S分…

java中的线程和进程,Java | 线程和进程,创建线程

一、线程与进程线程定义进程中执行的一个代码段&#xff0c;来完成不同的任务组成&#xff1a;线程ID&#xff0c;当前指令指针(PC)&#xff0c;寄存器集合(存储一部分正在执行线程的处理器状态的值)和堆栈进程定义执行的一段程序&#xff0c;一旦程序被载入到内存中准备执行就…

Maven的pom报错的解决方法

如果在MyEclipse里面导入项目,导入不了,如下图 接下来可以点击Import Maven Projects里的Action那一行Resolve Later. 点击Do Not Execute(add to pom)就可以正常导入了转载于:https://www.cnblogs.com/JimmySeraph/p/8068299.html

django零开始

2019独角兽企业重金招聘Python工程师标准>>> 安装。。。后查看 import django django.VERSION #输出版本号&#xff0c;目前自己是py2.7.9和django1.8 1&#xff0c;新建一个django-project django-admin.py startproject project-name 一个project一般为一个项目 …

关于Python3.6下登陆接口的尝试

编者按&#xff1a;README:此代码为用户登陆界面&#xff0c;添加了寻求帮助选项。1.学习了基本数据类型&#xff0c;string, int&#xff0c;以及while循环&#xff0c;continue, break, if, elif, else条件语句&#xff0c;“x".format&#xff08;x&#xff09;变量替代…

php 命令安装tp5,tp5.1框架的下载与安装方法步骤(图文)

大家可以都知道啊&#xff0c;tp框架5.1之前的版本都是可以在thinkphp的官网进行下载压缩包来安装框架的&#xff0c;那么在从tp5.1开始啊&#xff0c;就取消了下载压缩包安装的方法&#xff0c;那么我们如何进行下载呢&#xff1f;tp5.1的手册中开始就有提到tp5.1框架有两种安…

[连载]《C#通讯(串口和网络)框架的设计与实现》- 13.中英文版本切换设计

目 录 第十三章 中英文版本切换设计... 2 13.1 不用自带的资源文件的理由... 2 13.2 配置文件... 2 13.3 语言管理类... 3 13.4 应用管理类... 12 13.5 小结... 12 第十三章 中英文版本切换设计 13.1 不用自带的资源文件…

Mybaitis JdbcType 和javaType

2019独角兽企业重金招聘Python工程师标准>>> MyBatis 通过包含的jdbcType类型 BIT FLOAT CHAR TIMESTAMP OTHER UNDEFINEDTINYINT REAL VARCHAR BINARY BLOB NVARCHARSMALLINT DOUBLE …

php数据趋势曲线,数据曲线图怎么做

数据曲线图怎么做&#xff1f;1、在电脑桌面上&#xff0c;新建一个excel文件(操作过程即为点击右键&#xff0c;在选项中选择“新建”选项&#xff0c;然后再选择“excel文件”&#xff0c;即可成功新建excel文件了)2、双击将新建的excel文件打开&#xff0c;输入你需要统计制…