forked from webpack/webpack
-
Notifications
You must be signed in to change notification settings - Fork 0
/
Copy pathPersistentCaching.test.js
162 lines (150 loc) · 4.35 KB
/
PersistentCaching.test.js
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
142
143
144
145
146
147
148
149
150
151
152
153
154
155
156
157
158
159
160
161
162
const path = require("path");
const util = require("util");
const fs = require("fs");
const rimraf = require("rimraf");
const vm = require("vm");
const webpack = require("../");
const readdir = util.promisify(fs.readdir);
const writeFile = util.promisify(fs.writeFile);
const utimes = util.promisify(fs.utimes);
const mkdir = util.promisify(fs.mkdir);
describe("Persistent Caching", () => {
const tempPath = path.resolve(__dirname, "js", "persistent-caching");
const outputPath = path.resolve(tempPath, "output");
const cachePath = path.resolve(tempPath, "cache");
const srcPath = path.resolve(tempPath, "src");
const config = {
mode: "none",
context: tempPath,
cache: {
type: "filesystem",
buildDependencies: {
// avoid rechecking build dependencies
// for performance
// this is already covered by another test case
defaultWebpack: []
},
cacheLocation: cachePath
},
target: "node",
output: {
library: { type: "commonjs-module", export: "default" },
path: outputPath
}
};
beforeEach(done => {
rimraf(tempPath, done);
});
const updateSrc = async data => {
const ts = new Date(Date.now() - 10000);
await mkdir(srcPath, { recursive: true });
for (const key of Object.keys(data)) {
const p = path.resolve(srcPath, key);
await writeFile(p, data[key]);
await utimes(p, ts, ts);
}
};
const compile = async (configAdditions = {}) => {
return new Promise((resolve, reject) => {
webpack({ ...config, ...configAdditions }, (err, stats) => {
if (err) return reject(err);
resolve(stats);
});
});
};
const execute = () => {
const cache = {};
const require = name => {
if (cache[name]) return cache[name].exports;
if (!name.endsWith(".js")) name += ".js";
const p = path.resolve(outputPath, name);
const source = fs.readFileSync(p, "utf-8");
const context = {};
const fn = vm.runInThisContext(
`(function(require, module, exports) { ${source} })`,
context,
{
filename: p
}
);
const m = { exports: {} };
cache[name] = m;
fn(require, m, m.exports);
return m.exports;
};
return require("./main");
};
it("should merge multiple small files", async () => {
const files = Array.from({ length: 30 }).map((_, i) => `file${i}.js`);
const data = {
"index.js": `
${files.map((f, i) => `import f${i} from "./${f}";`).join("\n")}
export default ${files.map((_, i) => `f${i}`).join(" + ")};
`
};
for (const file of files) {
data[file] = `export default 1;`;
}
await updateSrc(data);
await compile();
expect(execute()).toBe(30);
for (let i = 0; i < 30; i++) {
updateSrc({
[files[i]]: `export default 2;`
});
await compile();
expect(execute()).toBe(31 + i);
}
const cacheFiles = await readdir(cachePath);
expect(cacheFiles.length).toBeLessThan(20);
expect(cacheFiles.length).toBeGreaterThan(10);
}, 60000);
it("should optimize unused content", async () => {
const data = {
"a.js": 'import "react-dom";',
"b.js": 'import "acorn";',
"c.js": 'import "core-js";',
"d.js": 'import "date-fns";',
"e.js": 'import "lodash";'
};
const createEntry = items => {
const entry = {};
for (const item of items.split("")) entry[item] = `./src/${item}.js`;
return entry;
};
await updateSrc(data);
await compile({ entry: createEntry("abcde") });
await compile({ entry: createEntry("abc") });
await compile({ entry: createEntry("cde") });
await compile({ entry: createEntry("acd") });
await compile({ entry: createEntry("bce") });
await compile({ entry: createEntry("abcde") });
const cacheFiles = await readdir(cachePath);
expect(cacheFiles.length).toBeGreaterThan(4);
}, 60000);
it("should allow persistent caching of container related objects", async () => {
const data = {
"index.js":
"export default import('container/src/exposed').then(m => m.default);",
"exposed.js": "export default 42;"
};
await updateSrc(data);
const configAdditions = {
plugins: [
new webpack.container.ModuleFederationPlugin({
name: "container",
library: { type: "commonjs-module" },
exposes: ["./src/exposed"],
remotes: ["./container"]
})
]
};
await compile(configAdditions);
await expect(execute()).resolves.toBe(42);
await updateSrc({
"exposed.js": "module.exports = { ok: true };"
});
await compile(configAdditions);
await expect(execute()).resolves.toEqual({ ok: true });
});
});