Skip to content

Commit

Permalink
refactor: code (#459)
Browse files Browse the repository at this point in the history
BREAKING CHANGE: migrate on `compilation.additionalAssets` hook
  • Loading branch information
cap-Bernardito committed May 8, 2020
1 parent 1e2f3a1 commit 42194f3
Show file tree
Hide file tree
Showing 6 changed files with 133 additions and 83 deletions.
112 changes: 45 additions & 67 deletions src/index.js
Expand Up @@ -17,81 +17,59 @@ class CopyPlugin {
}

apply(compiler) {
const fileDependencies = new Set();
const contextDependencies = new Set();
const plugin = { name: 'CopyPlugin' };
const logger = compiler.getInfrastructureLogger('copy-webpack-plugin');

compiler.hooks.emit.tapAsync(plugin, (compilation, callback) => {
logger.debug('starting emit');
compiler.hooks.compilation.tap(plugin, (compilation) => {
const logger = compilation.getLogger('copy-webpack-plugin');

const globalRef = {
context: compiler.options.context,
logger,
compilation,
fileDependencies,
contextDependencies,
inputFileSystem: compiler.inputFileSystem,
output: compiler.options.output.path,
ignore: this.options.ignore || [],
concurrency: this.options.concurrency,
};
compilation.hooks.additionalAssets.tapAsync(
'copy-webpack-plugin',
(callback) => {
logger.debug('start to adding additionalAssets');

Promise.all(
this.patterns.map((pattern) =>
Promise.resolve()
.then(() => preProcessPattern(globalRef, pattern))
// Every source (from) is assumed to exist here
// eslint-disable-next-line no-shadow
.then((pattern) =>
processPattern(globalRef, pattern).then((files) => {
if (!files) {
return Promise.resolve();
}
const globalRef = {
context: compiler.options.context,
logger,
compilation,
inputFileSystem: compiler.inputFileSystem,
output: compiler.options.output.path,
ignore: this.options.ignore || [],
concurrency: this.options.concurrency,
};

return Promise.all(
files
.filter(Boolean)
.map((file) => postProcessPattern(globalRef, pattern, file))
);
})
)
)
)
.catch((error) => {
compilation.errors.push(error);
})
.then(() => {
logger.debug('finishing emit');

callback();
});
});

compiler.hooks.afterEmit.tapAsync(plugin, (compilation, callback) => {
logger.debug('starting after-emit');
Promise.all(
this.patterns.map((pattern) =>
Promise.resolve()
.then(() => preProcessPattern(globalRef, pattern))
// Every source (from) is assumed to exist here
// eslint-disable-next-line no-shadow
.then((pattern) =>
processPattern(globalRef, pattern).then((files) => {
if (!files) {
return Promise.resolve();
}

// Add file dependencies
if ('addAll' in compilation.fileDependencies) {
compilation.fileDependencies.addAll(fileDependencies);
} else {
for (const fileDependency of fileDependencies) {
compilation.fileDependencies.add(fileDependency);
}
}
return Promise.all(
files
.filter(Boolean)
.map((file) =>
postProcessPattern(globalRef, pattern, file)
)
);
})
)
)
)
.catch((error) => {
compilation.errors.push(error);
})
.then(() => {
logger.debug('end to adding additionalAssets');

// Add context dependencies
if ('addAll' in compilation.contextDependencies) {
compilation.contextDependencies.addAll(contextDependencies);
} else {
for (const contextDependency of contextDependencies) {
compilation.contextDependencies.add(contextDependency);
callback();
});
}
}

logger.debug('finishing after-emit');

callback();
);
});
}
}
Expand Down
5 changes: 3 additions & 2 deletions src/postProcessPattern.js
Expand Up @@ -15,7 +15,7 @@ import { stat, readFile } from './utils/promisify';
/* eslint-disable no-param-reassign */

export default function postProcessPattern(globalRef, pattern, file) {
const { logger, compilation, fileDependencies, inputFileSystem } = globalRef;
const { logger, compilation, inputFileSystem } = globalRef;

logger.debug(`getting stats for '${file.absoluteFrom}' to write to assets`);

Expand All @@ -35,7 +35,8 @@ export default function postProcessPattern(globalRef, pattern, file) {

// If this came from a glob, add it to the file watchlist
if (pattern.fromType === 'glob') {
fileDependencies.add(file.absoluteFrom);
logger.debug(`add ${file.absoluteFrom} as fileDependencies`);
compilation.fileDependencies.add(file.absoluteFrom);
}

logger.debug(`reading '${file.absoluteFrom}' to write to assets`);
Expand Down
17 changes: 13 additions & 4 deletions src/utils/createPatternGlob.js
Expand Up @@ -16,7 +16,7 @@ function getAbsoluteContext(context) {
}

function createPatternGlob(pattern, globalRef) {
const { logger, fileDependencies, contextDependencies } = globalRef;
const { logger, compilation } = globalRef;

pattern.globOptions = Object.assign(
{
Expand All @@ -29,7 +29,8 @@ function createPatternGlob(pattern, globalRef) {
switch (pattern.fromType) {
case 'dir':
logger.debug(`determined '${pattern.absoluteFrom}' is a directory`);
contextDependencies.add(pattern.absoluteFrom);
logger.debug(`add ${pattern.absoluteFrom} as contextDependencies`);
compilation.contextDependencies.add(pattern.absoluteFrom);

pattern.context = pattern.absoluteFrom;
pattern.glob = path.posix.join(
Expand All @@ -44,7 +45,8 @@ function createPatternGlob(pattern, globalRef) {

case 'file':
logger.debug(`determined '${pattern.absoluteFrom}' is a file`);
fileDependencies.add(pattern.absoluteFrom);
logger.debug(`add ${pattern.absoluteFrom} as fileDependencies`);
compilation.fileDependencies.add(pattern.absoluteFrom);

pattern.context = path.dirname(pattern.absoluteFrom);
pattern.glob = getAbsoluteContext(pattern.absoluteFrom);
Expand All @@ -55,7 +57,14 @@ function createPatternGlob(pattern, globalRef) {

default:
logger.debug(`determined '${pattern.absoluteFrom}' is a glob`);
contextDependencies.add(path.normalize(globParent(pattern.absoluteFrom)));

// eslint-disable-next-line no-case-declarations
const contextDependencies = path.normalize(
globParent(pattern.absoluteFrom)
);

logger.debug(`add ${contextDependencies} as contextDependencies`);
compilation.contextDependencies.add(contextDependencies);

pattern.fromType = 'glob';
pattern.globOptions = pattern.globOptions || {};
Expand Down
29 changes: 29 additions & 0 deletions test/CopyPlugin.test.js
Expand Up @@ -539,3 +539,32 @@ describe('apply function', () => {
});
});
});

describe('logging', () => {
it('should logging', (done) => {
const expectedAssetKeys = ['file.txt'];

run({
patterns: [
{
from: 'file.txt',
},
],
})
.then(({ compiler, stats }) => {
const root = path.resolve(__dirname).replace(/\\/g, '/');
const logs = stats.compilation.logging
.get('copy-webpack-plugin')
.map((entry) =>
entry.args[0].replace(/\\/g, '/').split(root).join('.')
);

expect(
Array.from(Object.keys(readAssets(compiler, stats))).sort()
).toEqual(expectedAssetKeys);
expect({ result: logs }).toMatchSnapshot({ result: logs });
})
.then(done)
.catch(done);
});
});
28 changes: 28 additions & 0 deletions test/__snapshots__/CopyPlugin.test.js.snap
@@ -0,0 +1,28 @@
// Jest Snapshot v1, https://goo.gl/fbAQLP

exports[`logging should logging 1`] = `
Object {
"result": Array [
"start to adding additionalAssets",
"processing from: 'file.txt' to: '.'",
"getting stats for './fixtures/file.txt' to determinate 'fromType'",
"determined './fixtures/file.txt' is a file",
"add ./fixtures/file.txt as fileDependencies",
"begin globbing './fixtures/file.txt' with a context of './fixtures'",
"found ./fixtures/file.txt",
"testing watch/**/* against file.txt",
"watch/**/* doesn't match file.txt",
"testing directory-ln against file.txt",
"directory-ln doesn't match file.txt",
"testing file-ln.txt against file.txt",
"file-ln.txt doesn't match file.txt",
"testing symlink/**/* against file.txt",
"symlink/**/* doesn't match file.txt",
"determined that './fixtures/file.txt' should write to 'file.txt'",
"getting stats for './fixtures/file.txt' to write to assets",
"reading './fixtures/file.txt' to write to assets",
"writing 'file.txt' to compilation assets from './fixtures/file.txt'",
"end to adding additionalAssets",
],
}
`;
25 changes: 15 additions & 10 deletions test/helpers/PreCopyPlugin.js
Expand Up @@ -6,17 +6,22 @@ class PreCopyPlugin {
apply(compiler) {
const plugin = { name: 'PreCopyPlugin' };

compiler.hooks.emit.tapAsync(plugin, (compilation, callback) => {
this.options.existingAssets.forEach((assetName) => {
// eslint-disable-next-line no-param-reassign
compilation.assets[assetName] = {
source() {
return 'existing';
},
};
});
compiler.hooks.compilation.tap(plugin, (compilation) => {
compilation.hooks.additionalAssets.tapAsync(
'copy-webpack-plugin',
(callback) => {
this.options.existingAssets.forEach((assetName) => {
// eslint-disable-next-line no-param-reassign
compilation.assets[assetName] = {
source() {
return 'existing';
},
};
});

callback();
callback();
}
);
});
}
}
Expand Down

0 comments on commit 42194f3

Please sign in to comment.