UNPKG

2.91 kBJavaScriptView Raw
1/*
2 MIT License http://www.opensource.org/licenses/mit-license.php
3 Author Tobias Koppers @sokra
4*/
5"use strict";
6
7const asyncLib = require("neo-async");
8
9class CachePlugin {
10 constructor(cache) {
11 this.cache = cache || {};
12 this.FS_ACCURACY = 2000;
13 }
14
15 apply(compiler) {
16 if (Array.isArray(compiler.compilers)) {
17 compiler.compilers.forEach((c, idx) => {
18 new CachePlugin((this.cache[idx] = this.cache[idx] || {})).apply(c);
19 });
20 } else {
21 const registerCacheToCompiler = (compiler, cache) => {
22 compiler.hooks.thisCompilation.tap("CachePlugin", compilation => {
23 compilation.cache = cache;
24 compilation.hooks.childCompiler.tap(
25 "CachePlugin",
26 (childCompiler, compilerName, compilerIndex) => {
27 if (cache) {
28 let childCache;
29 if (!cache.children) {
30 cache.children = {};
31 }
32 if (!cache.children[compilerName]) {
33 cache.children[compilerName] = [];
34 }
35 if (cache.children[compilerName][compilerIndex]) {
36 childCache = cache.children[compilerName][compilerIndex];
37 } else {
38 cache.children[compilerName].push((childCache = {}));
39 }
40 registerCacheToCompiler(childCompiler, childCache);
41 }
42 }
43 );
44 });
45 };
46 registerCacheToCompiler(compiler, this.cache);
47 compiler.hooks.watchRun.tap("CachePlugin", () => {
48 this.watching = true;
49 });
50 compiler.hooks.run.tapAsync("CachePlugin", (compiler, callback) => {
51 if (!compiler._lastCompilationFileDependencies) {
52 return callback();
53 }
54 const fs = compiler.inputFileSystem;
55 const fileTs = (compiler.fileTimestamps = new Map());
56 asyncLib.forEach(
57 compiler._lastCompilationFileDependencies,
58 (file, callback) => {
59 fs.stat(file, (err, stat) => {
60 if (err) {
61 if (err.code === "ENOENT") return callback();
62 return callback(err);
63 }
64
65 if (stat.mtime) this.applyMtime(+stat.mtime);
66
67 fileTs.set(file, +stat.mtime || Infinity);
68
69 callback();
70 });
71 },
72 err => {
73 if (err) return callback(err);
74
75 for (const [file, ts] of fileTs) {
76 fileTs.set(file, ts + this.FS_ACCURACY);
77 }
78
79 callback();
80 }
81 );
82 });
83 compiler.hooks.afterCompile.tap("CachePlugin", compilation => {
84 compilation.compiler._lastCompilationFileDependencies =
85 compilation.fileDependencies;
86 compilation.compiler._lastCompilationContextDependencies =
87 compilation.contextDependencies;
88 });
89 }
90 }
91
92 /* istanbul ignore next */
93 applyMtime(mtime) {
94 if (this.FS_ACCURACY > 1 && mtime % 2 !== 0) this.FS_ACCURACY = 1;
95 else if (this.FS_ACCURACY > 10 && mtime % 20 !== 0) this.FS_ACCURACY = 10;
96 else if (this.FS_ACCURACY > 100 && mtime % 200 !== 0)
97 this.FS_ACCURACY = 100;
98 else if (this.FS_ACCURACY > 1000 && mtime % 2000 !== 0)
99 this.FS_ACCURACY = 1000;
100 }
101}
102module.exports = CachePlugin;