Skip to content

Commit db2e3bf

Browse files
authoredOct 22, 2020
feat: added the sourceFilename info (original source filename) to assets info (#542)
1 parent c892451 commit db2e3bf

8 files changed

+258
-11
lines changed
 

‎README.md

+2
Original file line numberDiff line numberDiff line change
@@ -48,6 +48,8 @@ module.exports = {
4848
4949
> ℹ️ If you want `webpack-dev-server` to write files to the output directory during development, you can force it with the [`writeToDisk`](https://github.com/webpack/webpack-dev-middleware#writetodisk) option or the [`write-file-webpack-plugin`](https://github.com/gajus/write-file-webpack-plugin).
5050
51+
> ℹ️ You can get the original source filename from [Asset Objects](https://webpack.js.org/api/stats/#asset-objects).
52+
5153
## Options
5254

5355
The plugin's signature:

‎package-lock.json

+10-2
Some generated files are not rendered by default. Learn more about customizing how changed files appear on GitHub.

‎package.json

+1
Original file line numberDiff line numberDiff line change
@@ -43,6 +43,7 @@
4343
"dependencies": {
4444
"cacache": "^15.0.5",
4545
"fast-glob": "^3.2.4",
46+
"file-loader": "^6.1.1",
4647
"find-cache-dir": "^3.3.1",
4748
"glob-parent": "^5.1.1",
4849
"globby": "^11.0.1",

‎src/index.js

+11-5
Original file line numberDiff line numberDiff line change
@@ -99,12 +99,13 @@ class CopyPlugin {
9999
pattern.to = path.normalize(
100100
typeof pattern.to !== 'undefined' ? pattern.to : ''
101101
);
102+
pattern.compilerContext = compiler.context;
102103
pattern.context = path.normalize(
103104
typeof pattern.context !== 'undefined'
104105
? !path.isAbsolute(pattern.context)
105-
? path.join(compiler.options.context, pattern.context)
106+
? path.join(pattern.compilerContext, pattern.context)
106107
: pattern.context
107-
: compiler.options.context
108+
: pattern.compilerContext
108109
);
109110

110111
logger.debug(`processing from "${pattern.from}" to "${pattern.to}"`);
@@ -303,7 +304,11 @@ class CopyPlugin {
303304

304305
logger.log(`determined that "${from}" should write to "${webpackTo}"`);
305306

306-
return { absoluteFrom, relativeFrom, webpackTo };
307+
const sourceFilename = normalizePath(
308+
path.relative(pattern.compilerContext, absoluteFrom)
309+
);
310+
311+
return { absoluteFrom, sourceFilename, relativeFrom, webpackTo };
307312
});
308313

309314
return Promise.all(
@@ -527,6 +532,7 @@ class CopyPlugin {
527532
.filter(Boolean)
528533
.forEach((asset) => {
529534
const {
535+
sourceFilename,
530536
absoluteFrom,
531537
targetPath,
532538
webpackTo,
@@ -551,7 +557,7 @@ class CopyPlugin {
551557
`force updating "${webpackTo}" to compilation assets from "${absoluteFrom}"`
552558
);
553559

554-
const info = { copied: true };
560+
const info = { copied: true, sourceFilename };
555561

556562
if (asset.immutable) {
557563
info.immutable = true;
@@ -573,7 +579,7 @@ class CopyPlugin {
573579
`writing "${webpackTo}" to compilation assets from "${absoluteFrom}"`
574580
);
575581

576-
const info = { copied: true };
582+
const info = { copied: true, sourceFilename };
577583

578584
if (asset.immutable) {
579585
info.immutable = true;

‎test/CopyPlugin.test.js

+116
Original file line numberDiff line numberDiff line change
@@ -2,6 +2,7 @@ import path from 'path';
22

33
import webpack from 'webpack';
44
import del from 'del';
5+
import { createFsFromVolume, Volume } from 'memfs';
56

67
import CopyPlugin from '../src';
78

@@ -380,6 +381,70 @@ describe('CopyPlugin', () => {
380381
.then(done)
381382
.catch(done);
382383
});
384+
385+
it('should work with multi compiler mode', async () => {
386+
const compiler = webpack([
387+
{
388+
mode: 'development',
389+
context: path.resolve(__dirname, './fixtures'),
390+
entry: path.resolve(__dirname, './helpers/enter.js'),
391+
output: {
392+
path: path.resolve(__dirname, './outputs/multi-compiler/dist/a'),
393+
},
394+
stats: {
395+
source: true,
396+
},
397+
plugins: [
398+
new CopyPlugin({
399+
patterns: [
400+
{
401+
from: path.resolve(__dirname, './fixtures/directory'),
402+
},
403+
],
404+
}),
405+
],
406+
},
407+
{
408+
mode: 'development',
409+
entry: path.resolve(__dirname, './helpers/enter.js'),
410+
output: {
411+
path: path.resolve(__dirname, './outputs/multi-compiler/dist/b'),
412+
},
413+
stats: {
414+
source: true,
415+
},
416+
plugins: [
417+
new CopyPlugin({
418+
patterns: [
419+
{
420+
context: path.resolve(__dirname, './fixtures'),
421+
from: path.resolve(__dirname, './fixtures/directory'),
422+
},
423+
],
424+
}),
425+
],
426+
},
427+
]);
428+
429+
compiler.compilers.forEach((item) => {
430+
const outputFileSystem = createFsFromVolume(new Volume());
431+
// Todo remove when we drop webpack@4 support
432+
outputFileSystem.join = path.join.bind(path);
433+
434+
// eslint-disable-next-line no-param-reassign
435+
item.outputFileSystem = outputFileSystem;
436+
});
437+
438+
const { stats } = await compile(compiler);
439+
440+
stats.stats.forEach((item, index) => {
441+
expect(item.compilation.errors).toMatchSnapshot('errors');
442+
expect(item.compilation.warnings).toMatchSnapshot('warnings');
443+
expect(readAssets(compiler.compilers[index], item)).toMatchSnapshot(
444+
'assets'
445+
);
446+
});
447+
});
383448
});
384449

385450
describe('watch mode', () => {
@@ -747,6 +812,57 @@ describe('CopyPlugin', () => {
747812
});
748813
});
749814

815+
describe('stats', () => {
816+
it('should work have assets info', async () => {
817+
const compiler = getCompiler({
818+
entry: path.resolve(__dirname, './helpers/enter-with-asset-modules.js'),
819+
});
820+
821+
new CopyPlugin({
822+
patterns: [
823+
{
824+
from: path.resolve(__dirname, './fixtures/directory'),
825+
},
826+
],
827+
}).apply(compiler);
828+
829+
const { stats } = await compile(compiler);
830+
831+
expect(stats.compilation.warnings).toMatchSnapshot('warnings');
832+
expect(stats.compilation.errors).toMatchSnapshot('errors');
833+
expect(readAssets(compiler, stats)).toMatchSnapshot('assets');
834+
835+
const assetsInfo = [];
836+
837+
for (const [name, info] of stats.compilation.assetsInfo.entries()) {
838+
assetsInfo.push({
839+
name,
840+
info: {
841+
// Workaround for `file-loader`
842+
// eslint-disable-next-line no-undefined
843+
immutable: info.immutable === false ? undefined : info.immutable,
844+
copied: info.copied,
845+
sourceFilename: info.sourceFilename,
846+
},
847+
});
848+
}
849+
850+
expect(
851+
assetsInfo.sort((a, b) => {
852+
if (a.name < b.name) {
853+
return -1;
854+
}
855+
856+
if (a.name > b.name) {
857+
return 1;
858+
}
859+
860+
return 0;
861+
})
862+
).toMatchSnapshot('assets info');
863+
});
864+
});
865+
750866
describe('logging', () => {
751867
it('should logging when "from" is a file', (done) => {
752868
const expectedAssetKeys = ['file.txt'];

‎test/__snapshots__/CopyPlugin.test.js.snap

+96
Original file line numberDiff line numberDiff line change
@@ -1,5 +1,33 @@
11
// Jest Snapshot v1, https://goo.gl/fbAQLP
22

3+
exports[`CopyPlugin basic should work with multi compiler mode: assets 1`] = `
4+
Object {
5+
".dottedfile": "dottedfile contents
6+
",
7+
"directoryfile.txt": "new",
8+
"nested/deep-nested/deepnested.txt": "",
9+
"nested/nestedfile.txt": "",
10+
}
11+
`;
12+
13+
exports[`CopyPlugin basic should work with multi compiler mode: assets 2`] = `
14+
Object {
15+
".dottedfile": "dottedfile contents
16+
",
17+
"directoryfile.txt": "new",
18+
"nested/deep-nested/deepnested.txt": "",
19+
"nested/nestedfile.txt": "",
20+
}
21+
`;
22+
23+
exports[`CopyPlugin basic should work with multi compiler mode: errors 1`] = `Array []`;
24+
25+
exports[`CopyPlugin basic should work with multi compiler mode: errors 2`] = `Array []`;
26+
27+
exports[`CopyPlugin basic should work with multi compiler mode: warnings 1`] = `Array []`;
28+
29+
exports[`CopyPlugin basic should work with multi compiler mode: warnings 2`] = `Array []`;
30+
331
exports[`CopyPlugin cache should work with the "filesystem" cache: assets 1`] = `
432
Object {
533
".dottedfile": "dottedfile contents
@@ -132,3 +160,71 @@ Object {
132160
],
133161
}
134162
`;
163+
164+
exports[`CopyPlugin stats should work have assets info: assets 1`] = `
165+
Object {
166+
".dottedfile": "dottedfile contents
167+
",
168+
"asset-modules/deepnested.txt": "",
169+
"directoryfile.txt": "new",
170+
"nested/deep-nested/deepnested.txt": "",
171+
"nested/nestedfile.txt": "",
172+
}
173+
`;
174+
175+
exports[`CopyPlugin stats should work have assets info: assets info 1`] = `
176+
Array [
177+
Object {
178+
"info": Object {
179+
"copied": true,
180+
"immutable": undefined,
181+
"sourceFilename": "directory/.dottedfile",
182+
},
183+
"name": ".dottedfile",
184+
},
185+
Object {
186+
"info": Object {
187+
"copied": undefined,
188+
"immutable": undefined,
189+
"sourceFilename": undefined,
190+
},
191+
"name": "asset-modules/deepnested.txt",
192+
},
193+
Object {
194+
"info": Object {
195+
"copied": true,
196+
"immutable": undefined,
197+
"sourceFilename": "directory/directoryfile.txt",
198+
},
199+
"name": "directoryfile.txt",
200+
},
201+
Object {
202+
"info": Object {
203+
"copied": undefined,
204+
"immutable": undefined,
205+
"sourceFilename": undefined,
206+
},
207+
"name": "main.js",
208+
},
209+
Object {
210+
"info": Object {
211+
"copied": true,
212+
"immutable": undefined,
213+
"sourceFilename": "directory/nested/deep-nested/deepnested.txt",
214+
},
215+
"name": "nested/deep-nested/deepnested.txt",
216+
},
217+
Object {
218+
"info": Object {
219+
"copied": true,
220+
"immutable": undefined,
221+
"sourceFilename": "directory/nested/nestedfile.txt",
222+
},
223+
"name": "nested/nestedfile.txt",
224+
},
225+
]
226+
`;
227+
228+
exports[`CopyPlugin stats should work have assets info: errors 1`] = `Array []`;
229+
230+
exports[`CopyPlugin stats should work have assets info: warnings 1`] = `Array []`;
+3
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,3 @@
1+
import txtURL from '../fixtures/directory/nested/deep-nested/deepnested.txt';
2+
3+
export default txtURL;

‎test/helpers/getCompiler.js

+19-4
Original file line numberDiff line numberDiff line change
@@ -11,13 +11,28 @@ export default (config = {}) => {
1111
output: {
1212
path: path.resolve(__dirname, '../build'),
1313
},
14+
module: {
15+
rules: [
16+
webpack.version[0] === '5'
17+
? {
18+
test: /\.txt/,
19+
type: 'asset/resource',
20+
generator: {
21+
filename: 'asset-modules/[name][ext]',
22+
},
23+
}
24+
: {
25+
test: /\.txt/,
26+
loader: 'file-loader',
27+
options: {
28+
name: 'asset-modules/[name].[ext]',
29+
},
30+
},
31+
],
32+
},
1433
...config,
1534
};
1635

17-
if (webpack.version[0] === 5) {
18-
fullConfig.stats.source = true;
19-
}
20-
2136
const compiler = webpack(fullConfig);
2237

2338
if (!config.outputFileSystem) {

0 commit comments

Comments
 (0)
Please sign in to comment.