Skip to content

Commit

Permalink
Improved docs and handle dev-server edge case (#78)
Browse files Browse the repository at this point in the history
Related-to: #65
  • Loading branch information
kevlened committed Oct 23, 2016
1 parent 8531cbd commit 323b1d7
Show file tree
Hide file tree
Showing 5 changed files with 80 additions and 50 deletions.
64 changes: 20 additions & 44 deletions README.md
Original file line number Diff line number Diff line change
Expand Up @@ -18,50 +18,25 @@ A pattern looks like:
`{ from: 'source', to: 'dest' }`

#### Pattern properties:
* `from`
- is required
- can be an absolute or path relative to the context
- can be a file or directory
- can be a glob
* `to`
- is optional
- if not absolute, it's relative to the build root
- must be a directory if `from` is a directory
* `toType`
- is optional
- is ignored if `from` is a directory
- defaults to `'file'` if `to` has an extension
- defaults to `'dir'` if `to` doesn't have an extension
* `force`
- is optional
- defaults to `false`
- forces the plugin to overwrite files staged by previous plugins
* `context`
- is optional
- defaults to the base context
- is a pattern specific context
* `flatten`
- is optional
- defaults to `false`
- removes all directory references and only copies file names
- if files have the same name, the result is non-deterministic
* `ignore`
- additional globs to ignore for this pattern

| Name | Required | Default | Details |
|------|----------|------------ |---------------------------------------------------------|
| `from` | Y | | _examples:_<br>'relative/file.txt'<br>'/absolute/file.txt'<br>'relative/dir'<br>'/absolute/dir'<br>'\*\*/\*'<br>{glob:'\*\*/\*', dot: true}<br><br>Globs accept [minimatch options](https://github.com/isaacs/minimatch) |
| `to` | N | output root if `from` is file or dir<br><br>resolved glob path if `from` is glob | _examples:_<br>'relative/file.txt'<br>'/absolute/file.txt'<br>'relative/dir'<br>'/absolute/dir'<br>'relative/[name].[ext]'<br>'/absolute/[name].[ext]'<br><br>Templates are [file-loader patterns](https://github.com/webpack/file-loader) |
| `toType` | N | **'file'** if `to` has extension or `from` is file<br><br>**'dir'** if `from` is directory, `to` has no extension or ends in '/'<br><br>**'template'** if `to` contains [a template pattern](https://github.com/webpack/file-loader) | |
| `context` | N | compiler.options.context | A path that determines how to interpret the `from` path |
| `flatten` | N | false | Removes all directory references and only copies file names<br><br>If files have the same name, the result is non-deterministic |
| `ignore` | N | [] | Additional globs to ignore for this pattern |
| `transform` | N | function(content, path) {<br>&nbsp;&nbsp;return content;<br>} | Function that modifies file contents before writing to webpack |
| `force` | N | false | Overwrites files already in compilation.assets (usually added by other plugins) |

#### Available options:
* `ignore`
- an array of files and directories to ignore
- accepts globs
- globs are evaluated on the `from` path, relative to the context
* `copyUnmodified`
- is optional
- defaults to `false` (only copies modified files)
- `true` copies all files while using watch or webpack-dev-server
* `debug`
- is optional
- defaults to `'warning'` (only logs on warning)
- `true` is the same as `'info'`
- options are `'warning'`, `'info'`, and `'debug'`

| Name | Default | Details |
| ---- | ------- | ------- |
| `ignore` | [] | Array of globs to ignore (applied to `from`) |
| `copyUnmodified` | false | Copies files, regardless of modification when using watch or webpack-dev-server. All files are copied on first build, regardless of this option. |
| `debug` | **'warning'** | _options:_<br>**'warning'** - only warnings<br>**'info'** or true - file location and read info<br>**'debug'** - very detailed debugging info

### Examples

Expand All @@ -72,8 +47,9 @@ var path = require('path');
module.exports = {
context: path.join(__dirname, 'app'),
devServer: {
// This is required for webpack-dev-server if using a version <3.0.0.
// The path should be an absolute path to your build destination.
// This is required for older versions of webpack-dev-server
// if you use absolute 'to' paths. The path should be an
// absolute path to your build destination.
outputPath: path.join(__dirname, 'build')
},
plugins: [
Expand Down
6 changes: 6 additions & 0 deletions src/index.js
Original file line number Diff line number Diff line change
Expand Up @@ -68,6 +68,12 @@ function CopyWebpackPlugin(patterns = [], options = {}) {
concurrency: options.concurrency
};

if (globalRef.output === '/' &&
compiler.options.devServer &&
compiler.options.devServer.outputPath) {
globalRef.output = compiler.options.devServer.outputPath;
}

Promise.each(patterns, (pattern) => {
// Identify absolute source of each pattern and destination type
return preProcessPattern(globalRef, pattern)
Expand Down
4 changes: 4 additions & 0 deletions src/processPattern.js
Original file line number Diff line number Diff line change
Expand Up @@ -70,6 +70,10 @@ export default function processPattern(globalRef, pattern) {
}

if (path.isAbsolute(file.webpackTo)) {
if (output === '/') {
throw '[copy-webpack-plugin] Using older versions of webpack-dev-server, devServer.outputPath must be defined to write to absolute paths';
}

file.webpackTo = path.relative(output, file.webpackTo);
}

Expand Down
2 changes: 1 addition & 1 deletion src/writeFile.js
Original file line number Diff line number Diff line change
Expand Up @@ -23,7 +23,7 @@ export default function writeFile(globalRef, pattern, file) {
return fs.readFileAsync(file.absoluteFrom)
.then((content) => {
if (pattern.transform) {
content = pattern.transform(content);
content = pattern.transform(content, file.absoluteFrom);
}

var hash = loaderUtils.getHashDigest(content);
Expand Down
54 changes: 49 additions & 5 deletions tests/index.js
Original file line number Diff line number Diff line change
Expand Up @@ -16,14 +16,18 @@ const HELPER_DIR = path.join(__dirname, 'helpers');
const TEMP_DIR = path.join(__dirname, 'tempdir');

class MockCompiler {
constructor () {
constructor (options = {}) {
this.options = {
context: HELPER_DIR,
output: {
path: BUILD_DIR
path: options.outputPath || BUILD_DIR
}
};

if (options.devServer && options.devServer.outputPath) {
_.set(this.options, 'devServer.outputPath', options.devServer.outputPath);
}

this.outputFileSystem = {
constructor: {
name: 'NotMemoryFileSystem'
Expand Down Expand Up @@ -356,12 +360,13 @@ describe('apply function', () => {
'file.txt'
],
expectedAssetContent: {
'file.txt': 'changed'
'file.txt': 'newchanged'
},
patterns: [{
from: 'file.txt',
transform: function() {
return 'changed';
transform: function(content, absoluteFrom) {
expect(absoluteFrom).to.equal(path.join(HELPER_DIR, 'file.txt'));
return content + 'changed';
}
}]
})
Expand Down Expand Up @@ -443,6 +448,45 @@ describe('apply function', () => {
.catch(done);
});

it('allows absolute to if outpath is defined with webpack-dev-server', (done) => {
runEmit({
compiler: new MockCompiler({
outputPath: '/',
devServer: {
outputPath: BUILD_DIR
}
}),
expectedAssetKeys: [
'file.txt'
],
patterns: [{
from: 'file.txt',
to: BUILD_DIR
}]
})
.then(done)
.catch(done);
});

it('throws an error when output path isn\'t defined with webpack-dev-server', (done) => {
runEmit({
compiler: new MockCompiler({
outputPath: '/'
}),
expectedAssetKeys: [],
expectedErrors: [
'[copy-webpack-plugin] Using older versions of webpack-dev-server, devServer.outputPath must be ' +
'defined to write to absolute paths'
],
patterns: [{
from: 'file.txt',
to: BUILD_DIR
}]
})
.then(done)
.catch(done);
});

it('can move a file to a new directory using an absolute to', (done) => {
runEmit({
expectedAssetKeys: [
Expand Down

0 comments on commit 323b1d7

Please sign in to comment.