update guide

This commit is contained in:
Conduitry 2018-04-16 23:47:42 -04:00
parent f6d22e630a
commit 92954e53f4
1 changed files with 20 additions and 6 deletions

View File

@ -4,11 +4,11 @@
Defiler's concept of a file is something that can come from one of two places: a physical file on the disk, or a virtual file that is generated by your code. These two types of files differ very slightly in how they are treated, but for the most part Defiler handles them both the same.
`File`s have a `path` property containing the relative path to the file, as well as `dir`, `filename`, and `ext` properties containing portions of the path. All of these can be updated and keep the others in sync.
`File`s have a `path` property containing the relative path to the file, as well as `dir`, `filename`, and `ext` properties containing portions of the path. All of these can be updated and will keep the others in sync.
For physical files, the `stats` property contains the `fs.Stats` object retrieved for the original file.
`File`s also have `text` and `bytes` properties, containing string and `Buffer` representations of the file's contents. Either can be updated and keeps the other in sync. (You shouldn't mutate `bytes`, only reassign it.) The `enc` property specifies the encoding to be used when converting between `text` and `bytes`, and can be changed.
`File`s also have `text` and `bytes` properties, containing string and `Buffer` representations of the file's contents. Either can be updated and will keep the other in sync. (You shouldn't mutate `bytes`, only reassign it.) The `enc` property specifies the encoding to be used when converting between `text` and `bytes`, and can be changed.
See the [API docs](API.md#file) for more information.
@ -16,11 +16,22 @@ See the [API docs](API.md#file) for more information.
Every file (physical and virtual) is run through the transform function you register with Defiler. The transform mutates the object representing the file in-place, and returns a promise indicating when it's finished.
The transform is called, for each file, with an object containing `defiler` (the `Defiler` instance) and `file` (the `File` instance). The transform should mutate the `file` object as it sees fit. It can also take whichever actions it wishes based on the file (including, for example, writing output to disk). Files' paths can be changed as they're transformed, but the main way to refer to them from other files will continue to be by their original path (see [dependence](#dependence)).
The transform is called, for each file, with an object containing `defiler` (the `Defiler` instance), `file` (the `File` instance), and `type` (a string representing why this file is being run through the transform, see [The `type` field](#the-type-field)). The transform should mutate the `file` object as it sees fit. It can also take whichever actions it wishes based on the file (including, for example, writing output to disk). Files' paths can be changed as they're transformed, but the main way to refer to them from other files will continue to be by their original paths (see [Dependence](#dependence)).
### The `type` field
The `type` passed to the transform is a string that can be one of four values:
- `'read'` - This indicates that the file was just read in from the disk
- `'add'` - This indicates that the file was just manually added (see [Virtual files](#virtual-files))
- `'delete'` - This indicates that the file was just deleted from the disk. In this case, the `file` object will be the transformed version of the file that was just deleted, and not an untransformed file for you to transform
- `'retransform'` - This indicates that the file was not changed, but that it is being re-transformed because one of its dependencies changed
At the very least, your transform should probably check whether `type` is `'delete'`, because in this case `file` isn't a file to transform, but is instead the fully-transformed version of the file that was just deleted.
## Dependence
Files can be made to depend on other files, so that changes to a dependency cause the dependent to be re-transformed. For physical files, the file does not need to be re-read from the disk before it can be re-transformed, as the original version is kept in memory.
Files can be made to depend on other files, so that changes to a dependency cause the dependent to be re-transformed. For physical files, the file does not need to be re-read from the disk before it can be re-transformed, as the original version is kept in memory. When a file is being re-transformed because one of its dependencies changed, the transform will be called with the `read`, `added`, and `deleted` flags all set to `false`.
The `defiler.get(path)` method, when used inside the transform, lets you depend on and retrieve other transformed files. It should be passed the original path of a file, and will return a `Promise` resolving to the transformed `File` instance. If the requested file does not exist (or if you have a deadlock via a system of mutually-depending files, none of which will continue transforming until another one finishes), the `Promise` will resolve to `undefined`.
@ -30,7 +41,7 @@ See the [API docs](API.md#getpath) for more information.
## Virtual files
During the transform's processing of a file, you can also create virtual files, which don't directly correspond one-to-one with physical files. The `Defiler` instance has a `defiler.add(file)` method, which you can pass a `File` instance to (or a POJO, which will be turned into a `File`). The virtual file will run through the transform and will thereafter be treated pretty much like a physical file. In particular, you can make other files depend on it with `defiler.get(path)`.
During the transform's processing of a file, you can also create virtual files, which don't directly correspond one-to-one with physical files. The `Defiler` instance has a `defiler.add(file)` method, which you can pass a `File` instance to (or, more commonly, a POJO, which will be turned into a `File`). The virtual file will run through the transform and will thereafter be treated pretty much like a physical file. In particular, you can make other files depend on it with `defiler.get(path)`.
Since Defiler has no way of knowing which virtual files will be created from transforming which files, when `defiler.get` is used to request a file that doesn't exist yet, Defiler waits until it does. Requesting a file that's never going to exist would cause a deadlock, so Defiler resolves this as a generalization of the above-mentioned deadlock resolution: If it ever happens that every in-process action is waiting for some other transformed file to exist, Defiler will resolve each of those pending `Promise`s returned by `defiler.get` to `undefined`.
@ -50,7 +61,7 @@ When performing production builds, you probably only want to have a first wave,
# Usage
First, [create a new `Defiler` instance](API.md#defiler), initializing it with the directories to watch, the transform, and (optionally) the generators and/or a path resolver.
First, [create a new `Defiler` instance](API.md#defiler), initializing it with the directories to watch, the transform, and (optionally) the generators, a path resolver, and/or an error handler.
```javascript
import { Defiler } from 'defiler'
@ -73,6 +84,9 @@ let defiler = new Defiler({
resolver: (base, path) => {
// return path resolved from base
},
onerror: (error) => {
// handle the error / abort the build / etc.
},
},
})
```