Skip to content

Commit a3d5e64

Browse files
committed
add virtual fs logic to loader
1 parent 330decd commit a3d5e64

File tree

3 files changed

+200
-1
lines changed

3 files changed

+200
-1
lines changed

index.js

Lines changed: 9 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -1,7 +1,7 @@
11
const { basename, extname, relative } = require('path');
22
const { compile, preprocess } = require('svelte');
33
const { getOptions } = require('loader-utils');
4-
const VirtualModulesPlugin = require('webpack-virtual-modules');
4+
const VirtualModulesPlugin = require('./lib/virtual');
55

66
const hotApi = require.resolve('./lib/hot-api.js');
77
const virtualModules = new VirtualModulesPlugin();
@@ -80,7 +80,14 @@ function deprecatePreprocessOptions(options) {
8080
options.preprocess = options.preprocess || preprocessOptions;
8181
}
8282

83+
const compilers = new Set();
84+
8385
module.exports = function(source, map) {
86+
if (!compilers.has(this._compiler)) {
87+
virtualModules.apply(this._compiler);
88+
compilers.add(this._compiler);
89+
}
90+
8491
this.cacheable();
8592

8693
const options = Object.assign({}, this.options, getOptions(this));
@@ -130,6 +137,7 @@ module.exports = function(source, map) {
130137

131138
callback(null, js.code, js.map);
132139
}, err => callback(err)).catch(err => {
140+
console.log(err.stack);
133141
// wrap error to provide correct
134142
// context when logging to console
135143
callback(new Error(`${err.name}: ${err.toString()}`));

lib/virtual-stats.js

Lines changed: 96 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,96 @@
1+
/**
2+
* Used to cache a stats object for the virtual file.
3+
* Extracted from the `mock-fs` package.
4+
*
5+
* @author Tim Schaub http://tschaub.net/
6+
* @link https://github.com/tschaub/mock-fs/blob/master/lib/binding.js
7+
* @link https://github.com/tschaub/mock-fs/blob/master/license.md
8+
*/
9+
10+
/* eslint-disable no-restricted-syntax, no-prototype-builtins, no-continue */
11+
/* eslint-disable no-bitwise, no-underscore-dangle */
12+
13+
'use strict';
14+
15+
var constants = require('constants');
16+
17+
/**
18+
* Create a new stats object.
19+
* @param {Object} config Stats properties.
20+
* @constructor
21+
*/
22+
function VirtualStats(config) {
23+
for (var key in config) {
24+
if (!config.hasOwnProperty(key)) {
25+
continue;
26+
}
27+
this[key] = config[key];
28+
}
29+
}
30+
31+
/**
32+
* Check if mode indicates property.
33+
* @param {number} property Property to check.
34+
* @return {boolean} Property matches mode.
35+
*/
36+
VirtualStats.prototype._checkModeProperty = function(property) {
37+
return ((this.mode & constants.S_IFMT) === property);
38+
};
39+
40+
41+
/**
42+
* @return {Boolean} Is a directory.
43+
*/
44+
VirtualStats.prototype.isDirectory = function() {
45+
return this._checkModeProperty(constants.S_IFDIR);
46+
};
47+
48+
49+
/**
50+
* @return {Boolean} Is a regular file.
51+
*/
52+
VirtualStats.prototype.isFile = function() {
53+
return this._checkModeProperty(constants.S_IFREG);
54+
};
55+
56+
57+
/**
58+
* @return {Boolean} Is a block device.
59+
*/
60+
VirtualStats.prototype.isBlockDevice = function() {
61+
return this._checkModeProperty(constants.S_IFBLK);
62+
};
63+
64+
65+
/**
66+
* @return {Boolean} Is a character device.
67+
*/
68+
VirtualStats.prototype.isCharacterDevice = function() {
69+
return this._checkModeProperty(constants.S_IFCHR);
70+
};
71+
72+
73+
/**
74+
* @return {Boolean} Is a symbolic link.
75+
*/
76+
VirtualStats.prototype.isSymbolicLink = function() {
77+
return this._checkModeProperty(constants.S_IFLNK);
78+
};
79+
80+
81+
/**
82+
* @return {Boolean} Is a named pipe.
83+
*/
84+
VirtualStats.prototype.isFIFO = function() {
85+
return this._checkModeProperty(constants.S_IFIFO);
86+
};
87+
88+
89+
/**
90+
* @return {Boolean} Is a socket.
91+
*/
92+
VirtualStats.prototype.isSocket = function() {
93+
return this._checkModeProperty(constants.S_IFSOCK);
94+
};
95+
96+
module.exports = VirtualStats;

lib/virtual.js

Lines changed: 95 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,95 @@
1+
var VirtualStats = require('./virtual-stats');
2+
var path = require('path');
3+
// var debug = require('debug')('webpack-virtual-modules');
4+
5+
var inode = 45000000;
6+
7+
function VirtualModulesPlugin() {}
8+
9+
VirtualModulesPlugin.prototype.writeModule = function(filePath, contents) {
10+
var len = contents ? contents.length : 0;
11+
var time = Date.now();
12+
13+
var stats = new VirtualStats({
14+
dev: 8675309,
15+
nlink: 0,
16+
uid: 1000,
17+
gid: 1000,
18+
rdev: 0,
19+
blksize: 4096,
20+
ino: inode++,
21+
mode: 33188,
22+
size: len,
23+
blocks: Math.floor(len / 4096),
24+
atime: time,
25+
mtime: time,
26+
ctime: time,
27+
birthtime: time
28+
});
29+
30+
// debug(this._compiler.name, "Write module:", modulePath, contents);
31+
32+
this._compiler.inputFileSystem._writeVirtualFile(filePath, stats, contents);
33+
if (this._watcher && this._watcher.watchFileSystem.watcher.fileWatchers.length) {
34+
this._watcher.watchFileSystem.watcher.fileWatchers.forEach((fileWatcher) => {
35+
if (fileWatcher.path === filePath) {
36+
// debug(this._compiler.name, "Emit file change:", filePath, time);
37+
fileWatcher.emit("change", time, null);
38+
}
39+
});
40+
}
41+
};
42+
43+
function setData(storage, key, value) {
44+
if (storage.data instanceof Map) {
45+
storage.data.set(key, value);
46+
} else {
47+
storage.data[key] = value;
48+
}
49+
}
50+
51+
VirtualModulesPlugin.prototype.apply = function(compiler) {
52+
this._compiler = compiler;
53+
54+
// var afterEnvironmentHook = function() {
55+
if (!compiler.inputFileSystem._writeVirtualFile) {
56+
var originalPurge = compiler.inputFileSystem.purge;
57+
58+
compiler.inputFileSystem.purge = function() {
59+
originalPurge.call(this, arguments);
60+
if (this._virtualFiles) {
61+
Object.keys(this._virtualFiles).forEach(function(file) {
62+
var data = this._virtualFiles[file];
63+
setData(this._statStorage, file, [null, data.stats]);
64+
setData(this._readFileStorage, file, [null, data.contents]);
65+
}.bind(this));
66+
}
67+
};
68+
69+
compiler.inputFileSystem._writeVirtualFile = function(file, stats, contents) {
70+
this._virtualFiles = this._virtualFiles || {};
71+
this._virtualFiles[file] = {stats: stats, contents: contents};
72+
setData(this._statStorage, file, [null, stats]);
73+
setData(this._readFileStorage, file, [null, contents]);
74+
};
75+
}
76+
// }
77+
78+
const watchRunHook = (watcher, callback) => {
79+
this._watcher = watcher.compiler || watcher;
80+
callback();
81+
}
82+
83+
if(compiler.hooks) {
84+
console.log('>>>1')
85+
// compiler.hooks.afterEnvironment.tap('VirtualModulesPlugin', afterEnvironmentHook);
86+
// compiler.hooks.afterResolvers.tap('VirtualModulesPlugin', afterResolversHook);
87+
compiler.hooks.watchRun.tapAsync('VirtualModulesPlugin', watchRunHook);
88+
} else {
89+
// compiler.plugin("after-environment", afterEnvironmentHook);
90+
// compiler.plugin("after-resolvers", afterResolversHook);
91+
// compiler.plugin("watch-run", watchRunHook);
92+
}
93+
};
94+
95+
module.exports = VirtualModulesPlugin;

0 commit comments

Comments
 (0)