webpack loader 生成虚拟文件的方案
此文已由作者张磊授权网易云社区发布。
欢迎访问网易云社区,了解更多网易技术产品运营经验。
前言
使用 webpack 的时候,难免需要写一些 loader,接着就会遇到一个很纠结的问题。该 loader 会生成一个文件,一般这个文件的生成时机都是在 loader 处理所有的文件后。一般有两种处理方案。一种是写一个 plugin,监听对应的事件;一种是生成一个临时文件,将每次读到的内容都写在 临时文件 中。第一种在使用的时候也很麻烦,需要同时在 loader 和 plugin 加一下对应的逻辑。第二种,写入临时文件的这个过程很是让人纠结。很明显,两种方案对于有一定洁癖的人来说,都不优雅,那么就来寻找一种方案,既不需要写 plugin,又不需要写入 临时文件 中。
解决方案
在 github 上找到一个可用解决方案的 loader,这个 loader 看起来是关于虚拟文件生成的,使用很简单,指定名字,指定内容,生成一个虚拟文件,研究了一下,对解决问题很有帮助。关键代码如下:
// index.jsimport * as fsPatch from './fs-patch';// 省略...fsPatch.add( this.fs, { path: file, content: src
});// 省略...
这个文件传入 loader.fs,看起来是对 fs 打补丁,接着再来看 fs-patch.js
// fs-patch.jsimport path from 'path';const NS = __filename; export function patch( fs ) { if ( fs[ NS ] ) return; const virtualFS = {
files: {}, add( options ) { const file = path.resolve( options.path );
virtualFS.files[ file ] = {
path: file,
content: options.content
};
} };
fs[ NS ] = virtualFS; createPatchFn( fs, 'readFile', function( orig, args, file, encoding, cb ) { var rfile = path.resolve( file ); var vfile = virtualFS.files[ rfile ]; if ( vfile ) { if ( typeof(encoding) === 'function' ) {
cb = encoding;
encoding = null;
} var content = vfile.content; if ( encoding != null )
content = content.toString( encoding ); cb( null, content ) return;
} return orig.apply( this, args );
});
createPatchFn( fs, 'readFileSync', function( orig, args, file, encoding ) { var rfile = path.resolve( file ); var vfile = virtualFS.files[ rfile ]; if ( vfile ) { var content = vfile.content; if ( encoding != null )
content = content.toString( encoding ); return content;
} return orig.apply( this, args );
}); createPatchFn( fs, 'stat', function( orig, args, p, cb ) { var rp = path.resolve( p ); var vfile = virtualFS.files[ rp ]; if ( vfile ) { var vstat = {
dev: 8675309,
nlink: 1,
uid: 501,
gid: 20,
rdev: 0,
blksize: 4096,
ino: 44700000,
mode: 33188,
size: vfile.content.length,
isFile() { return true; },
isDirectory() { return false; },
isBlockDevice() { return false; },
isCharacterDevice() { return false; },
isSymbolicLink() { return false; },
isFIFO() { return false; },
isSocket() { return false; },
};
cb( null, vstat ); return;
} return orig.apply( this, args );
});
createPatchFn( fs, 'statSync', function( orig, args, p ) { var rp = path.resolve( p ); var vfile = virtualFS.files[ rp ]; if ( vfile ) { var vstat = {
dev: 8675309,
nlink: 1,
uid: 501,
gid: 20,
rdev: 0,
blksize: 4096,
ino: 44700000,
mode: 33188,
size: vfile.content.length,
isFile() { return true; },
isDirectory() { return false; },
isBlockDevice() { return false; },
isCharacterDevice() { return false; },
isSymbolicLink() { return false; },
isFIFO() { return false; },
isSocket() { return false; },
}; return vstat;
} return orig.apply( this, args );
}); }; export function add( fs, options ) {
patch( fs );
fs[ NS ].add( options );
}function createPatchFn( obj, name, fn ) { const origin = obj[ name ];
obj[ name ] = function() { const args = Array.prototype.slice.call( arguments ); return fn.apply( this, [origin, args].concat( args ) );
};
}
代码分析
可以看到 fs-patch.js 直接劫持了 loader.fs,重写了 fs 的一些方法,而重写的这些方法就是生成虚拟文件的关键。劫持后的 fs 在访问这些方法的时候,首先去从缓存中获取路径对应的内容,不存在则再从硬盘中读取。
优缺点
优点是不需要生成临时文件或者另写一个 plugin,缺点在文件比较大或者计算比较频繁,对机器的要求会比较高。
更多网易技术、产品、运营经验分享请点击。
相关文章:
【推荐】 云架构师进阶攻略(1)
【推荐】 BRVAH(让RecyclerView变得更高效)(1)
webpack loader 生成虚拟文件的方案的更多相关文章
- webpack4 系列教程(十三):自动生成HTML文件
作者按:因为教程所示图片使用的是 github 仓库图片,网速过慢的朋友请移步<webpack4 系列教程(十三):自动生成 HTML 文件>原文地址.更欢迎来我的小站看更多原创内容:go ...
- IIs 网站应用程序与虚拟目录的区别及高级应用说明(文件分布式存储方案)
原文 IIs 网站应用程序与虚拟目录的区别及高级应用说明(文件分布式存储方案) 对于IIS网站,大伙用的比较多,就不啰嗦了. 今天和说说大伙比较少使用的"IIS应用程序”和虚拟目录的区别 ...
- webpack中使用html-webpack-plugin生成HTML文件并主动插入css和js引入标签
html-webpack-plugin clean-webpack-plugin 一.html-webpack-plugin 由于打包时生成的css样式文件和js脚本文件会采用hash值作为文件命名的 ...
- shell 编程生成日期文件;Server虚拟机上进行Web服务器配置
shell 编程生成日期文件 1. 请编写一个脚本,命名为sh01.sh,其功能是: 键盘输入文件名(要求使用名字全拼作为文件名). 自动创建3个文件. 1个为系统当天日期(CCYYMMDD). 1个 ...
- 在CabloyJS中将Webpack生成的文件自动上传到阿里云OSS
背景 阿里云OSS提供了一个Webpack插件,可在Webpack打包结束后将webpack生成的文件自动上传到阿里云OSS中 下面看看在CabloyJS中如何使用该插件 新建项目,并配置MySQL连 ...
- vue项目通过webpack打包生成的dist文件放到express环境里运行(vue+webpack+express)
1.首先需要的原料肯定是vue打包生成的dist文件 在vue项目目录下运行:npm run build,等待运行结束,会在项目目录下生成一个dist文件夹,里面会生成一些文件(如下图示) 小的项目文 ...
- 揭秘webpack loader
前言 Loader(加载器) 是 webpack 的核心之一.它用于将不同类型的文件转换为 webpack 可识别的模块.本文将尝试深入探索 webpack 中的 loader,揭秘它的工作原理,以及 ...
- 怎样写一个webpack loader
div{display:table-cell;vertical-align:middle}#crayon-theme-info .content *{float:left}#crayon-theme- ...
- 手把手教你撸一个 Webpack Loader
文:小 boy(沪江网校Web前端工程师) 本文原创,转载请注明作者及出处 经常逛 webpack 官网的同学应该会很眼熟上面的图.正如它宣传的一样,webpack 能把左侧各种类型的文件(webpa ...
随机推荐
- PHP----练习----光标离开文本框时变色
题目::创建若干个输入文本框,当光标离开文本框的时候如果文本框为空,则将文本框背景色设置为红色,如果不为空则为白色. <!DOCTYPE html PUBLIC "-//W3C//DT ...
- windows自定义快捷键功能
如下:
- Kali-linux枚举服务
枚举是一类程序,它允许用户从一个网络中收集某一类的所有相关信息.本节将介绍DNS枚举和SNMP枚举技术.DNS枚举可以收集本地所有DNS服务和相关条目.DNS枚举可以帮助用户收集目标组织的关键信息,如 ...
- mac端抓包工具——Charles使用
一.简介 Charles(http://www.charlesproxy.com/)是在Mac 下常用的截取网络封包的工具.Charles 通过将自己设置成系统的网络访问代理服务器,使得所有的网络访问 ...
- js取整、四舍五入等数学函数
js只保留整数,向上取整,四舍五入,向下取整等函数1.丢弃小数部分,保留整数部分parseInt(5/2) 2.向上取整,有小数就整数部分加1 Math.ceil(5/2) 3,四舍五入. Math. ...
- Epub 阅读器 - iOS
因项目需求接触的 EPub 阅读器,前前后后尝试了很多库,最后找到了个相对兼容不错的展开了调试;其中对解压缩和数据加载方面进行了改造优化,使其更加的完美; 其大概原理是首先将 epub 文件解压后得到 ...
- DW CS5序列号
先要改host文件,以防止其连接 Adobe 的激活验证服务器 1. 用记事本编辑“C:\Windows\System32\Drivers\etc\”目录下的 hosts 文件, 在末尾加上: 127 ...
- HTML5新特性之离线缓存技术
一.离线缓存的起因. HTML5之前的网页,都是无连接,必须联网才能访问,这其实也是web的特色,这其实对于PC是时代问题并不大,但到了移动互联网时代, 设备终端位置不再固定,依赖无线信号,网络的可靠 ...
- 在控制台中操作MYSQL数据库步骤以及一些小问题
一直用Navicat来对MySQL数据库进行操作,今天突然想试试用DOS控制台来操作,特记录自己第一次使用经历,若有错误之处,还望大佬们指点. 首先打开控制台,win+R键,输入cmd,确定 输入my ...
- 搭建Apache服务器并使用自签证书实现https访问
实验环境:两台Centos7.2的虚拟机,一台作CA服务器,一台作Apache服务器,此处安装httpd-2.4.6的版本. 1)CA服务器 # 私钥一般存放位置:/etc/pki/CA/privat ...