Skip to content

Commit c32ecf0

Browse files
committed
Update VirtualModulesPlugin from upstream
This updates the internal VirtualModulesPlugin, which is copied from https://github.com/sysgears/webpack-virtual-modules. I went through all commits since this virtual.js was added, and applied them manually to the svelte-loader version where applicable. These upstream changes allow for using Webpack 5 with svelte-loader. This also adds a LICENSE file to comply with the requirements of the MIT license for the plugin files. The LICENSE file also adds in the text of MIT license that svelte-loader is licensed under (with a different copyright line, since svelte-loader wasn't written by SysGears)
1 parent 929eebe commit c32ecf0

File tree

4 files changed

+190
-17
lines changed

4 files changed

+190
-17
lines changed

LICENSE

Lines changed: 42 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,42 @@
1+
svelte-loader is licensed under the MIT license:
2+
Copyright (c) 2020 svelte-loader contributors
3+
4+
Permission is hereby granted, free of charge, to any person obtaining a copy
5+
of this software and associated documentation files (the "Software"), to deal
6+
in the Software without restriction, including without limitation the rights
7+
to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
8+
copies of the Software, and to permit persons to whom the Software is
9+
furnished to do so, subject to the following conditions:
10+
11+
The above copyright notice and this permission notice shall be included in all
12+
copies or substantial portions of the Software.
13+
14+
THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
15+
IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
16+
FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
17+
AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
18+
LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
19+
OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE
20+
SOFTWARE.
21+
22+
lib/virtual.js and lib/virtual-stats.js also contain code licensed under the
23+
MIT license:
24+
Copyright (c) 2017 SysGears
25+
26+
Permission is hereby granted, free of charge, to any person obtaining a copy
27+
of this software and associated documentation files (the "Software"), to deal
28+
in the Software without restriction, including without limitation the rights
29+
to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
30+
copies of the Software, and to permit persons to whom the Software is
31+
furnished to do so, subject to the following conditions:
32+
33+
The above copyright notice and this permission notice shall be included in all
34+
copies or substantial portions of the Software.
35+
36+
THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
37+
IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
38+
FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
39+
AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
40+
LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
41+
OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE
42+
SOFTWARE.

index.js

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -178,6 +178,6 @@ module.exports = function(source, map) {
178178
}, err => callback(err)).catch(err => {
179179
// wrap error to provide correct
180180
// context when logging to console
181-
callback(new Error(`${err.name}: ${err.toString()}`));
181+
callback(new Error(`${err.name || "Error"}: ${err.toString()}`));
182182
});
183183
};

lib/virtual-stats.js

Lines changed: 2 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -1,3 +1,5 @@
1+
// Adapted from https://github.com/sysgears/webpack-virtual-modules
2+
13
/**
24
* Used to cache a stats object for the virtual file.
35
* Extracted from the `mock-fs` package.

lib/virtual.js

Lines changed: 145 additions & 16 deletions
Original file line numberDiff line numberDiff line change
@@ -1,9 +1,26 @@
1+
// Adapted from https://github.com/sysgears/webpack-virtual-modules
2+
13
var VirtualStats = require('./virtual-stats');
4+
var path = require("path");
25

36
var inode = 45000000;
47

5-
// Adapted from https://github.com/sysgears/webpack-virtual-modules
6-
// MIT Licensed https://github.com/sysgears/webpack-virtual-modules/blob/master/LICENSE
8+
function createWebpackData(result) {
9+
return (function(backendOrStorage) {
10+
// In Webpack v5, this variable is a "Backend", and has the data stored in a field
11+
// _data. In V4, the `_` prefix isn't present.
12+
if (backendOrStorage._data) {
13+
const curLevelIdx = backendOrStorage._currentLevel;
14+
const curLevel = backendOrStorage._levels[curLevelIdx];
15+
return {
16+
result: this.result,
17+
level: curLevel
18+
};
19+
}
20+
// Webpack 4
21+
return [null, result];
22+
}).bind({ result: result });
23+
}
724

825
/**
926
* @param {Compiler} compiler - the webpack compiler
@@ -16,24 +33,69 @@ function VirtualModulesPlugin(compiler) {
1633

1734
compiler.inputFileSystem.purge = function() {
1835
if (originalPurge) {
19-
originalPurge.call(this, arguments);
36+
originalPurge.apply(this, arguments);
2037
}
2138
if (this._virtualFiles) {
22-
Object.keys(this._virtualFiles).forEach(
23-
function(file) {
24-
var data = this._virtualFiles[file];
25-
setData(this._statStorage, file, [null, data.stats]);
26-
setData(this._readFileStorage, file, [null, data.contents]);
27-
}.bind(this)
28-
);
39+
Object.keys(this._virtualFiles).forEach(function(file) {
40+
var data = this._virtualFiles[file];
41+
this._writeVirtualFile(file, data.stats, data.contents);
42+
}.bind(this));
2943
}
3044
};
3145

3246
compiler.inputFileSystem._writeVirtualFile = function(file, stats, contents) {
47+
const statStorage = getStatStorage(this);
48+
const fileStorage = getFileStorage(this);
49+
const readDirStorage = getReadDirBackend(this);
3350
this._virtualFiles = this._virtualFiles || {};
3451
this._virtualFiles[file] = { stats: stats, contents: contents };
35-
setData(this._statStorage, file, [null, stats]);
36-
setData(this._readFileStorage, file, [null, contents]);
52+
setData(statStorage, file, createWebpackData(stats));
53+
setData(fileStorage, file, createWebpackData(contents));
54+
var segments = file.split(/[\\/]/);
55+
var count = segments.length - 1;
56+
var minCount = segments[0] ? 1 : 0;
57+
while (count > minCount) {
58+
var dir = segments.slice(0, count).join(path.sep) || path.sep;
59+
try {
60+
compiler.inputFileSystem.readdirSync(dir);
61+
} catch (e) {
62+
var time = new Date();
63+
var timeMs = time.getTime();
64+
var dirStats = new VirtualStats({
65+
dev: 8675309,
66+
nlink: 0,
67+
uid: 1000,
68+
gid: 1000,
69+
rdev: 0,
70+
blksize: 4096,
71+
ino: inode++,
72+
mode: 16877,
73+
size: stats.size,
74+
blocks: Math.floor(stats.size / 4096),
75+
atimeMs: timeMs,
76+
mtimeMs: timeMs,
77+
ctimeMs: timeMs,
78+
birthtimeMs: timeMs,
79+
atime: time,
80+
mtime: time,
81+
ctime: time,
82+
birthtime: time
83+
});
84+
setData(readDirStorage, dir, createWebpackData([]));
85+
setData(statStorage, dir, createWebpackData(dirStats));
86+
}
87+
var dirData = getData(getReadDirBackend(this), dir);
88+
// Webpack v4 returns an array, webpack v5 returns an object
89+
dirData = dirData[1] || dirData.result;
90+
var filename = segments[count];
91+
if (dirData.indexOf(filename) < 0) {
92+
var files = dirData.concat([filename]).sort();
93+
setData(getReadDirBackend(this), dir, createWebpackData(files));
94+
} else {
95+
break;
96+
}
97+
count--;
98+
}
3799
};
38100
}
39101

@@ -75,14 +137,81 @@ VirtualModulesPlugin.prototype.writeModule = function(filePath, contents) {
75137
birthtime: time
76138
});
77139

140+
// When using the WatchIgnorePlugin (https://github.com/webpack/webpack/blob/52184b897f40c75560b3630e43ca642fcac7e2cf/lib/WatchIgnorePlugin.js),
141+
// the original watchFileSystem is stored in `wfs`. The following "unwraps" the ignoring
142+
// wrappers, giving us access to the "real" watchFileSystem.
143+
let finalWatchFileSystem = this._watcher && this._watcher.watchFileSystem;
144+
145+
while (finalWatchFileSystem && finalWatchFileSystem.wfs) {
146+
finalWatchFileSystem = finalWatchFileSystem.wfs;
147+
}
78148
this.compiler.inputFileSystem._writeVirtualFile(filePath, stats, contents);
79149
};
80150

81-
function setData(storage, key, value) {
82-
if (storage.data instanceof Map) {
83-
storage.data.set(key, value);
151+
function getData(storage, key) {
152+
// Webpack 5
153+
if (storage._data instanceof Map) {
154+
return storage._data.get(key);
155+
} else if (storage._data) {
156+
return storage.data[key];
157+
} else if (storage.data instanceof Map) {
158+
// Webpack v4
159+
return storage.data.get(key);
160+
} else {
161+
return storage.data[key];
162+
}
163+
}
164+
165+
function setData(backendOrStorage, key, valueFactory) {
166+
const value = valueFactory(backendOrStorage);
167+
168+
// Webpack v5
169+
if (backendOrStorage._data instanceof Map) {
170+
backendOrStorage._data.set(key, value);
171+
} else if (backendOrStorage._data) {
172+
backendOrStorage.data[key] = value;
173+
} else if (backendOrStorage.data instanceof Map) {
174+
// Webpack 4
175+
backendOrStorage.data.set(key, value);
176+
backendOrStorage.data.set(key, value);
177+
} else {
178+
backendOrStorage.data[key] = value;
179+
backendOrStorage.data[key] = value;
180+
}
181+
}
182+
183+
function getStatStorage(fileSystem) {
184+
if (fileSystem._statStorage) {
185+
// Webpack v4
186+
return fileSystem._statStorage;
187+
} else if (fileSystem._statBackend) {
188+
// webpack v5
189+
return fileSystem._statBackend;
190+
} else {
191+
// Unknown version?
192+
throw new Error("Couldn't find a stat storage");
193+
}
194+
}
195+
196+
function getFileStorage(fileSystem) {
197+
if (fileSystem._readFileStorage) {
198+
// Webpack v4
199+
return fileSystem._readFileStorage;
200+
} else if (fileSystem._readFileBackend) {
201+
// Webpack v5
202+
return fileSystem._readFileBackend;
203+
} else {
204+
throw new Error("Couldn't find a readFileStorage");
205+
}
206+
}
207+
208+
function getReadDirBackend(fileSystem) {
209+
if (fileSystem._readdirBackend) {
210+
return fileSystem._readdirBackend;
211+
} else if (fileSystem._readdirStorage) {
212+
return fileSystem._readdirStorage;
84213
} else {
85-
storage.data[key] = value;
214+
throw new Error("Couldn't find a readDirStorage from Webpack Internals");
86215
}
87216
}
88217

0 commit comments

Comments
 (0)