Skip to content

Commit bfc712d

Browse files
fix: concurrency writing assets (#484)
1 parent 0e62695 commit bfc712d

File tree

2 files changed

+54
-33
lines changed

2 files changed

+54
-33
lines changed

src/index.js

Lines changed: 49 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -38,7 +38,7 @@ class CopyPlugin {
3838
};
3939

4040
try {
41-
await Promise.all(
41+
const assets = await Promise.all(
4242
this.patterns.map((pattern) =>
4343
limit(async () => {
4444
const patternAfterPreProcess = await preProcessPattern(
@@ -70,6 +70,54 @@ class CopyPlugin {
7070
)
7171
);
7272

73+
// Avoid writing assets inside `p-limit`, because it creates concurrency.
74+
// It could potentially lead to an error - "Multiple assets emit different content to the same filename"
75+
assets
76+
.reduce((acc, val) => acc.concat(val), [])
77+
.filter(Boolean)
78+
.forEach((asset) => {
79+
const {
80+
absoluteFrom,
81+
targetPath,
82+
webpackTo,
83+
source,
84+
force,
85+
} = asset;
86+
87+
// For old version webpack 4
88+
/* istanbul ignore if */
89+
if (typeof compilation.emitAsset !== 'function') {
90+
// eslint-disable-next-line no-param-reassign
91+
compilation.assets[targetPath] = source;
92+
93+
return;
94+
}
95+
96+
if (compilation.getAsset(targetPath)) {
97+
if (force) {
98+
logger.log(
99+
`force updating '${webpackTo}' to compilation assets from '${absoluteFrom}'`
100+
);
101+
102+
compilation.updateAsset(targetPath, source);
103+
104+
return;
105+
}
106+
107+
logger.log(
108+
`skipping '${webpackTo}', because it already exists`
109+
);
110+
111+
return;
112+
}
113+
114+
logger.log(
115+
`writing '${webpackTo}' to compilation assets from '${absoluteFrom}'`
116+
);
117+
118+
compilation.emitAsset(targetPath, source);
119+
});
120+
73121
logger.debug('end to adding additional assets');
74122

75123
callback();

src/postProcessPattern.js

Lines changed: 5 additions & 32 deletions
Original file line numberDiff line numberDiff line change
@@ -7,7 +7,6 @@ import cacache from 'cacache';
77
import serialize from 'serialize-javascript';
88
import findCacheDir from 'find-cache-dir';
99
import normalizePath from 'normalize-path';
10-
1110
import { RawSource } from 'webpack-sources';
1211

1312
import { version } from '../package.json';
@@ -148,36 +147,10 @@ export default async function postProcessPattern(globalRef, pattern, file) {
148147
);
149148
}
150149

151-
const targetPath = normalizePath(file.webpackTo);
152-
const source = new RawSource(content);
153-
154-
// For old version webpack 4
155-
/* istanbul ignore if */
156-
if (typeof compilation.emitAsset !== 'function') {
157-
compilation.assets[targetPath] = source;
158-
159-
return;
160-
}
161-
162-
if (compilation.getAsset(targetPath)) {
163-
if (pattern.force) {
164-
logger.log(
165-
`force updating '${file.webpackTo}' to compilation assets from '${file.absoluteFrom}'`
166-
);
167-
168-
compilation.updateAsset(targetPath, source);
169-
170-
return;
171-
}
172-
173-
logger.log(`skipping '${file.webpackTo}', because it already exists`);
174-
175-
return;
176-
}
177-
178-
logger.log(
179-
`writing '${file.webpackTo}' to compilation assets from '${file.absoluteFrom}'`
180-
);
150+
file.source = new RawSource(content);
151+
file.targetPath = normalizePath(file.webpackTo);
152+
file.force = pattern.force;
181153

182-
compilation.emitAsset(targetPath, source);
154+
// eslint-disable-next-line consistent-return
155+
return file;
183156
}

0 commit comments

Comments
 (0)