2017-06-14 09:37:39 +00:00
|
|
|
# static
|
2016-11-23 09:37:28 +00:00
|
|
|
|
2017-06-14 09:37:39 +00:00
|
|
|
[![Pub](https://img.shields.io/pub/v/angel_static.svg)](https://pub.dartlang.org/packages/angel_static)
|
2017-02-22 23:43:27 +00:00
|
|
|
[![build status](https://travis-ci.org/angel-dart/static.svg?branch=master)](https://travis-ci.org/angel-dart/static)
|
2016-11-23 09:37:28 +00:00
|
|
|
|
2016-04-21 21:27:22 +00:00
|
|
|
Static server middleware for Angel.
|
|
|
|
|
|
|
|
# Installation
|
|
|
|
In `pubspec.yaml`:
|
|
|
|
|
2016-07-01 20:33:42 +00:00
|
|
|
```yaml
|
|
|
|
dependencies:
|
2017-06-16 02:05:06 +00:00
|
|
|
angel_static: ^1.2.0
|
2016-07-01 20:33:42 +00:00
|
|
|
```
|
2016-04-21 21:27:22 +00:00
|
|
|
|
|
|
|
# Usage
|
2016-11-23 17:22:23 +00:00
|
|
|
To serve files from a directory, your app needs to have a
|
|
|
|
`VirtualDirectory` mounted on it.
|
2016-04-21 21:27:22 +00:00
|
|
|
|
|
|
|
```dart
|
|
|
|
import 'dart:io';
|
|
|
|
import 'package:angel_framework/angel_framework.dart';
|
|
|
|
import 'package:angel_static/angel_static.dart';
|
|
|
|
|
|
|
|
main() async {
|
2016-11-23 17:22:23 +00:00
|
|
|
final app = new Angel();
|
2017-02-27 00:19:34 +00:00
|
|
|
|
|
|
|
// Normal static server
|
2016-11-23 20:14:05 +00:00
|
|
|
await app.configure(new VirtualDirectory(source: new Directory('./public')));
|
2017-02-27 00:19:34 +00:00
|
|
|
|
|
|
|
// Send Cache-Control, ETag, etc. as well
|
|
|
|
await app.configure(new CachingVirtualDirectory(source: new Directory('./public')));
|
|
|
|
|
2016-11-23 17:22:23 +00:00
|
|
|
await app.startServer();
|
2016-04-21 21:27:22 +00:00
|
|
|
}
|
|
|
|
```
|
|
|
|
|
2017-04-01 01:08:01 +00:00
|
|
|
# Push State Example
|
|
|
|
```dart
|
|
|
|
var vDir = new VirtualDirectory(...);
|
|
|
|
var indexFile = new File.fromUri(vDir.source.uri.resolve('index.html'));
|
|
|
|
|
|
|
|
app.after.add((req, ResponseContext res) {
|
|
|
|
// Fallback to index.html on 404
|
|
|
|
return res.sendFile(indexFile);
|
|
|
|
});
|
|
|
|
```
|
|
|
|
|
2016-05-02 23:11:25 +00:00
|
|
|
# Options
|
2016-11-23 17:22:23 +00:00
|
|
|
The `VirtualDirectory` API accepts a few named parameters:
|
|
|
|
- **source**: A `Directory` containing the files to be served. If left null, then Angel will serve either from `web` (in development) or
|
2016-06-24 22:23:32 +00:00
|
|
|
`build/web` (in production), depending on your `ANGEL_ENV`.
|
2016-11-23 17:24:04 +00:00
|
|
|
- **indexFileNames**: A `List<String>` of filenames that should be served as index pages. Default is `['index.html']`.
|
2016-11-23 17:22:23 +00:00
|
|
|
- **publicPath**: To serve index files, you need to specify the virtual path under which
|
2016-05-02 23:11:25 +00:00
|
|
|
angel_static is serving your files. If you are not serving static files at the site root,
|
|
|
|
please include this.
|
2016-11-23 17:22:23 +00:00
|
|
|
- **debug**: Print verbose debug output.
|
2017-01-25 22:40:41 +00:00
|
|
|
- **callback**: Runs before sending a file to a client. Use this to set headers, etc. If it returns anything other than `null` or `true`,
|
|
|
|
then the callback's result will be sent to the user, instead of the file contents.
|
2017-04-01 01:08:01 +00:00
|
|
|
- **streamToIO**: If set to `true`, files will be streamed to `res.io`, instead of added to `res.buffer`.. Default is `false`.
|
2017-06-16 02:05:06 +00:00
|
|
|
|
|
|
|
# Transformers
|
|
|
|
`angel_static` now supports *transformers*. Similarly to `pub serve`, or `package:build`, these
|
|
|
|
let you dynamically compile assets before sending them to users. For example, in development, you might
|
|
|
|
consider using transformers to compile CSS files, or to even replace `pub serve`.
|
|
|
|
Transformers are supported by `VirtualDirectory` and `CachingVirtualDirectory`.
|
|
|
|
|
|
|
|
To create a transformer:
|
|
|
|
```dart
|
2017-06-16 02:11:27 +00:00
|
|
|
class MinifierTransformer extends FileTransformer {
|
2017-06-16 02:05:06 +00:00
|
|
|
/// Use this to declare outputs, and indicate if your transformer
|
|
|
|
/// will compile a file.
|
|
|
|
@override
|
|
|
|
FileInfo declareOutput(FileInfo file) {
|
|
|
|
// For example, we might only want to minify HTML files.
|
|
|
|
if (!file.extensions.endsWith('.min.html'))
|
|
|
|
return null;
|
|
|
|
else return file.changeExtension('.min.html');
|
|
|
|
}
|
|
|
|
|
|
|
|
/// Actually compile the asset here.
|
|
|
|
@override
|
|
|
|
FutureOr<FileInfo> transform(FileInfo file) async {
|
|
|
|
return file
|
|
|
|
.changeExtension('.min.html')
|
|
|
|
.changeContent(
|
|
|
|
file.content
|
|
|
|
.transform(UTF8.decoder)
|
|
|
|
.transform(const LineSplitter()
|
|
|
|
.transform(UTF8.encoder))
|
|
|
|
);
|
|
|
|
}
|
|
|
|
}
|
|
|
|
```
|
|
|
|
|
|
|
|
To use it:
|
|
|
|
```dart
|
|
|
|
configureServer(Angel app) async {
|
|
|
|
var vDir = new CachingVirtualDirectory(
|
|
|
|
transformers: [new MinifierTransformer()]
|
|
|
|
);
|
|
|
|
await app.configure(vDir);
|
|
|
|
|
|
|
|
// It is suggested that you await `transformersLoaded`.
|
|
|
|
// Otherwise, you may receive 404's on paths that should send a compiled asset.
|
|
|
|
await vDir.transformersLoaded;
|
|
|
|
}
|
|
|
|
```
|
|
|
|
|
|
|
|
## Pre-building
|
|
|
|
You can pre-build all your assets with one command:
|
|
|
|
|
|
|
|
```dart
|
|
|
|
configureServer(Angel app) async {
|
|
|
|
var vDir = new VirtualDirectory(transformers: [...]);
|
|
|
|
await app.configure(vDir);
|
|
|
|
|
|
|
|
// Build if in production
|
|
|
|
if (app.isProduction) {
|
|
|
|
await vDir.buildToDisk();
|
|
|
|
}
|
|
|
|
}
|
|
|
|
```
|
|
|
|
|
|
|
|
## In Production
|
|
|
|
By default, transformers are disabled in production mode.
|
|
|
|
To force-enable them:
|
|
|
|
|
|
|
|
```dart
|
|
|
|
configureServer(Angel app) async {
|
|
|
|
var vDir = new VirtualDirectory(useTransformersInProduction: true, transformers: [...]);
|
|
|
|
}
|
|
|
|
```
|