Skip to content

Commit

Permalink
refactor: fix cache (#549)
Browse files Browse the repository at this point in the history
  • Loading branch information
evilebottnawi authored Nov 3, 2020
1 parent 87a8486 commit bc2833e
Show file tree
Hide file tree
Showing 6 changed files with 745 additions and 514 deletions.
22 changes: 11 additions & 11 deletions package-lock.json

Some generated files are not rendered by default. Learn more about how customized files appear on GitHub.

2 changes: 1 addition & 1 deletion package.json
Original file line number Diff line number Diff line change
Expand Up @@ -79,7 +79,7 @@
"npm-run-all": "^4.1.5",
"prettier": "^2.1.2",
"standard-version": "^9.0.0",
"webpack": "^5.3.0"
"webpack": "^5.3.2"
},
"keywords": [
"webpack",
Expand Down
188 changes: 118 additions & 70 deletions src/index.js
Original file line number Diff line number Diff line change
Expand Up @@ -87,7 +87,14 @@ class CopyPlugin {
});
}

static async runPattern(compiler, compilation, logger, cache, inputPattern) {
static async runPattern(
compiler,
compilation,
logger,
cache,
inputPattern,
index
) {
const pattern =
typeof inputPattern === 'string'
? { from: inputPattern }
Expand Down Expand Up @@ -357,7 +364,10 @@ class CopyPlugin {
logger.debug(`getting cache for '${absoluteFilename}'...`);

try {
cacheEntry = await cache.getPromise(sourceFilename, null);
cacheEntry = await cache.getPromise(
`${sourceFilename}|${index}`,
null
);
} catch (error) {
compilation.errors.push(error);

Expand Down Expand Up @@ -417,71 +427,6 @@ class CopyPlugin {

logger.debug(`read '${absoluteFilename}'`);

if (pattern.transform) {
logger.log(`transforming content for '${absoluteFilename}'...`);

if (pattern.cacheTransform) {
const cacheDirectory = pattern.cacheTransform.directory
? pattern.cacheTransform.directory
: typeof pattern.cacheTransform === 'string'
? pattern.cacheTransform
: findCacheDir({ name: 'copy-webpack-plugin' }) ||
os.tmpdir();
let defaultCacheKeys = {
version,
transform: pattern.transform,
contentHash: crypto
.createHash('md4')
.update(data)
.digest('hex'),
};

defaultCacheKeys =
typeof pattern.cacheTransform.keys === 'function'
? await pattern.cacheTransform.keys(
defaultCacheKeys,
absoluteFilename
)
: {
...defaultCacheKeys,
...pattern.cacheTransform.keys,
};

const cacheKeys = serialize(defaultCacheKeys);

try {
logger.debug(
`getting transformation cache for '${absoluteFilename}'...`
);

const cachedResult = await cacache.get(
cacheDirectory,
cacheKeys
);

({ data } = cachedResult);
} catch (_ignoreError) {
logger.debug(
`no transformation cache for '${absoluteFilename}'...`
);

data = await pattern.transform(data, absoluteFilename);

logger.debug(
`caching transformation for '${absoluteFilename}'`
);

await cacache.put(cacheDirectory, cacheKeys, data);

logger.debug(
`cached transformation for '${absoluteFilename}'`
);
}
} else {
data = await pattern.transform(data, absoluteFilename);
}
}

result.source = new RawSource(data);

if (cache) {
Expand All @@ -506,7 +451,7 @@ class CopyPlugin {
logger.debug(`storing cache for '${absoluteFilename}'...`);

try {
await cache.storePromise(sourceFilename, null, {
await cache.storePromise(`${sourceFilename}|${index}`, null, {
source: result.source,
snapshot,
});
Expand All @@ -521,6 +466,108 @@ class CopyPlugin {
}
}

if (pattern.transform) {
logger.log(`transforming content for '${absoluteFilename}'...`);

const buffer = result.source.source();

if (pattern.cacheTransform) {
const defaultCacheKeys = {
version,
sourceFilename,
transform: pattern.transform,
contentHash: crypto
.createHash('md4')
.update(buffer)
.digest('hex'),
index,
};
const cacheKeys = `transform|${serialize(
typeof pattern.cacheTransform.keys === 'function'
? await pattern.cacheTransform.keys(
defaultCacheKeys,
absoluteFilename
)
: { ...defaultCacheKeys, ...pattern.cacheTransform.keys }
)}`;

let cacheItem;
let cacheDirectory;

logger.debug(
`getting transformation cache for '${absoluteFilename}'...`
);

// webpack@5 API
if (cache) {
cacheItem = cache.getItemCache(
cacheKeys,
cache.getLazyHashedEtag(result.source)
);

result.source = await cacheItem.getPromise();
} else {
cacheDirectory = pattern.cacheTransform.directory
? pattern.cacheTransform.directory
: typeof pattern.cacheTransform === 'string'
? pattern.cacheTransform
: findCacheDir({ name: 'copy-webpack-plugin' }) ||
os.tmpdir();

let cached;

try {
cached = await cacache.get(cacheDirectory, cacheKeys);
} catch (error) {
logger.debug(
`no transformation cache for '${absoluteFilename}'...`
);
}

// eslint-disable-next-line no-undefined
result.source = cached ? new RawSource(cached.data) : undefined;
}

logger.debug(
result.source
? `found transformation cache for '${absoluteFilename}'`
: `no transformation cache for '${absoluteFilename}'`
);

if (!result.source) {
const transformed = await pattern.transform(
buffer,
absoluteFilename
);

result.source = new RawSource(transformed);

logger.debug(
`caching transformation for '${absoluteFilename}'...`
);

// webpack@5 API
if (cache) {
await cacheItem.storePromise(result.source);
} else {
try {
await cacache.put(cacheDirectory, cacheKeys, transformed);
} catch (error) {
compilation.errors.push(error);

return;
}
}

logger.debug(`cached transformation for '${absoluteFilename}'`);
}
} else {
result.source = new RawSource(
await pattern.transform(buffer, absoluteFilename)
);
}
}

if (pattern.toType === 'template') {
logger.log(
`interpolating template '${filename}' for '${sourceFilename}'...`
Expand Down Expand Up @@ -615,14 +662,15 @@ class CopyPlugin {

try {
assets = await Promise.all(
this.patterns.map((item) =>
this.patterns.map((item, index) =>
limit(async () =>
CopyPlugin.runPattern(
compiler,
compilation,
logger,
cache,
item
item,
index
)
)
)
Expand Down
Loading

0 comments on commit bc2833e

Please sign in to comment.