Skip to content

Commit

Permalink
feat: add support for target path transform
Browse files Browse the repository at this point in the history
based on /pull/115
  • Loading branch information
Fetz committed Oct 11, 2018
1 parent 48bc708 commit b9537c5
Show file tree
Hide file tree
Showing 3 changed files with 176 additions and 2 deletions.
38 changes: 38 additions & 0 deletions README.md
Expand Up @@ -60,6 +60,7 @@ Or, in case of just a `from` with the default destination, you can also use a `{
|[`ignore`](#ignore)|`{Array}`|`[]`|Globs to ignore for this pattern|
|`flatten`|`{Boolean}`|`false`|Removes all directory references and only copies file names.⚠️ If files have the same name, the result is non-deterministic|
|[`transform`](#transform)|`{Function\|Promise}`|`(content, path) => content`|Function or Promise that modifies file contents before copying|
|[`transformPath`](#transformPath)|`{Function\|Promise}`|`(targetPath, sourcePath) => path`|Function or Promise that modifies file writing path|
|[`cache`](#cache)|`{Boolean\|Object}`|`false`|Enable `transform` caching. You can use `{ cache: { key: 'my-cache-key' } }` to invalidate the cache|
|[`context`](#context)|`{String}`|`options.context \|\| compiler.options.context`|A path that determines how to interpret the `from` path|

Expand Down Expand Up @@ -234,6 +235,43 @@ and so on...
]
```

### `transformPath`

#### `{Function}`

**webpack.config.js**
```js
[
new CopyWebpackPlugin([
{
from: 'src/*.png',
to: 'dest/',
transformPath (targetPath, absolutePath) {
return 'newPath';
}
}
], options)
]
```

#### `{Promise}`

**webpack.config.js**
```js
[
new CopyWebpackPlugin([
{
from: 'src/*.png',
to: 'dest/',
transform (targePath, absolutePath) {
return Promise.resolve('newPath')
}
}
], options)
]
```


### `cache`

**webpack.config.js**
Expand Down
16 changes: 14 additions & 2 deletions src/writeFile.js
Expand Up @@ -63,8 +63,6 @@ export default function writeFile(globalRef, pattern, file) {

return content;
}).then((content) => {
const hash = loaderUtils.getHashDigest(content);

if (pattern.toType === 'template') {
info(`interpolating template '${file.webpackTo}' for '${file.relativeFrom}'`);

Expand All @@ -84,6 +82,20 @@ export default function writeFile(globalRef, pattern, file) {
}
);
}

return content;
}).then((content) => {
if (pattern.transformPath) {
return Promise.resolve(
pattern.transformPath(file.webpackTo, file.absoluteFrom)
).then((newPath) => {
file.webpackTo = newPath;
}).then(() => content);
}

return content;
}).then((content) => {
const hash = loaderUtils.getHashDigest(content);

if (!copyUnmodified &&
written[file.absoluteFrom] &&
Expand Down
124 changes: 124 additions & 0 deletions tests/index.js
Expand Up @@ -319,6 +319,57 @@ describe('apply function', () => {
.catch(done);
});

it('can transform target path of every file in glob', (done) => {
runEmit({
expectedAssetKeys: [
'/some/path/(special-*file).txt.tst',
'/some/path/binextension.bin.tst',
'/some/path/file.txt.tst',
'/some/path/file.txt.gz.tst',
'/some/path/directoryfile.txt.tst',
'/some/path/nestedfile.txt.tst',
'/some/path/noextension.tst',
'/some/path/hello.txt.tst'
],
patterns: [{
from: '**/*',
transformPath: function(targetPath, absoluteFrom) {
expect(absoluteFrom).to.have.string(HELPER_DIR);
return '/some/path/' + path.basename(targetPath) + '.tst';
}
}]
})
.then(done)
.catch(done);
});

it('can transform target path of every file in glob after applying template', (done) => {
runEmit({
expectedAssetKeys: [
'transformed/[!]/hello-d41d8c.txt',
'transformed/[special?directory]/directoryfile-22af64.txt',
'transformed/[special?directory]/(special-*file)-0bd650.txt',
'transformed/[special?directory]/nested/nestedfile-d41d8c.txt',
'transformed/binextension-d41d8c.bin',
'transformed/file-22af64.txt',
'transformed/file.txt-5b311c.gz',
'transformed/directory/directoryfile-22af64.txt',
'transformed/directory/nested/nestedfile-d41d8c.txt',
'transformed/noextension-d41d8c'
],
patterns: [{
from: '**/*',
to: 'nested/[path][name]-[hash:6].[ext]',
transformPath: function(targetPath, absoluteFrom) {
expect(absoluteFrom).to.have.string(HELPER_DIR);
return targetPath.replace('nested/', 'transformed/');
}
}]
})
.then(done)
.catch(done);
});

it('can use a glob to move multiple files in a different relative context to a non-root directory', (done) => {
runEmit({
expectedAssetKeys: [
Expand Down Expand Up @@ -524,6 +575,23 @@ describe('apply function', () => {
.catch(done);
});

it('can transform target path', (done) => {
runEmit({
expectedAssetKeys: [
'subdir/test.txt'
],
patterns: [{
from: 'file.txt',
transformPath: function(targetPath, absoluteFrom) {
expect(absoluteFrom).to.equal(path.join(HELPER_DIR, 'file.txt'));
return targetPath.replace('file.txt', 'subdir/test.txt');
}
}]
})
.then(done)
.catch(done);
});

it('warns when file not found', (done) => {
runEmit({
expectedAssetKeys: [],
Expand Down Expand Up @@ -555,6 +623,23 @@ describe('apply function', () => {
.catch(done);
});

it('warns when tranformPath failed', (done) => {
runEmit({
expectedAssetKeys: [],
expectedErrors: [
'a failure happened'
],
patterns: [{
from: 'file.txt',
transformPath: function() {
throw 'a failure happened';
}
}]
})
.then(done)
.catch(done);
});

it('can use an absolute path to move a file to the root directory', (done) => {
const absolutePath = path.resolve(HELPER_DIR, 'file.txt');

Expand Down Expand Up @@ -972,6 +1057,26 @@ describe('apply function', () => {
.catch(done);
});

it('transformPath with promise', (done) => {
runEmit({
expectedAssetKeys: [
'/some/path/file.txt'
],
patterns: [{
from: 'file.txt',
transformPath: function(targetPath, absoluteFrom) {
expect(absoluteFrom).to.have.string(HELPER_DIR);

return new Promise((resolve) => {
resolve('/some/path/' + path.basename(targetPath));
});
}
}]
})
.then(done)
.catch(done);
});

it('same file to multiple targets', (done) => {
runEmit({
expectedAssetKeys: [
Expand Down Expand Up @@ -1007,6 +1112,25 @@ describe('apply function', () => {
.catch(done);
});

it('can transform target path of every file in directory', (done) => {
runEmit({
expectedAssetKeys: [
'/some/path/.dottedfile',
'/some/path/directoryfile.txt',
'/some/path/nestedfile.txt'
],
patterns: [{
from: 'directory',
transformPath: function(targetPath, absoluteFrom) {
expect(absoluteFrom).to.have.string(path.join(HELPER_DIR, 'directory'));
return '/some/path/' + path.basename(targetPath);
}
}]
})
.then(done)
.catch(done);
});

it('can move a directory\'s contents to the root directory using from with special characters', (done) => {
runEmit({
expectedAssetKeys: [
Expand Down

0 comments on commit b9537c5

Please sign in to comment.