Skip to content

Commit

Permalink
Merge pull request #330 from NekR/v4.9.0
Browse files Browse the repository at this point in the history
V4.9.0
  • Loading branch information
NekR committed Dec 25, 2017
2 parents 0845c39 + 5eec617 commit f607943
Show file tree
Hide file tree
Showing 92 changed files with 6,837 additions and 480 deletions.
3 changes: 2 additions & 1 deletion .appveyor.yml
Original file line number Diff line number Diff line change
Expand Up @@ -3,8 +3,9 @@ environment:
matrix:
# node.js
- nodejs_version: "4"
- nodejs_version: "5"
- nodejs_version: "6"
- nodejs_version: "8"
- nodejs_version: "9"

# Install scripts. (runs after repo cloning)
install:
Expand Down
4 changes: 3 additions & 1 deletion .gitignore
Original file line number Diff line number Diff line change
@@ -1,4 +1,6 @@
node_modules/
__output/
/__*
.DS_Store
.idea
.idea
npm-debug.log
12 changes: 10 additions & 2 deletions .travis.yml
Original file line number Diff line number Diff line change
@@ -1,6 +1,14 @@
sudo: false
language: node_js
node_js:
- "4"
- "6"
- "5"
- "4"
- "8"
- "9"
env:
- TEST_METHOD=ci_fixtures
matrix:
include:
- node_js: "8"
env: TEST_METHOD=ci_all
script: npm run test:"$TEST_METHOD"
3 changes: 1 addition & 2 deletions README.md
Original file line number Diff line number Diff line change
Expand Up @@ -7,14 +7,13 @@
<a href="#sponsors"><img src="https://opencollective.com/offline-plugin/sponsors/badge.svg" alt="sponsors" /></a>
<a href="https://www.npmjs.com/package/offline-plugin"><img src="https://img.shields.io/npm/v/offline-plugin.svg?maxAge=3600&v4" alt="npm"></a>
<a href="https://www.npmjs.com/package/offline-plugin"><img src="https://img.shields.io/npm/dm/offline-plugin.svg?maxAge=3600" alt="npm"></a>
<a href="https://gitter.im/NekR/offline-plugin?utm_source=badge&utm_medium=badge&utm_campaign=pr-badge&utm_content=badge"><img src="https://badges.gitter.im/NekR/offline-plugin.svg" alt="Join the chat at https://gitter.im/NekR/offline-plugin"></a>
</div>
<br>

This plugin is intended to provide an offline experience for **webpack** projects. It uses **ServiceWorker**, and **AppCache** as a fallback under the hood. Simply include this plugin in your ``webpack.config``, and the accompanying runtime in your client script, and your project will become offline ready by caching all (or some) of the webpack output assets.

<div align="center">
<strong>Demo:<br><a href="https://offline-plugin.now.sh/"> Progressive Web App built with <code>offline-plugin</code></a></strong><br>
<strong>Demo:<br><a href="https://offline-plugin.now.sh/"> Progressive Web App built with <code>offline-plugin</code></a></strong><br>
<div>(<a href="https://github.com/NekR/offline-plugin-pwa"><i>source code</i></a>)</div>
</div>

Expand Down
18 changes: 18 additions & 0 deletions docs/app-shell.md
Original file line number Diff line number Diff line change
@@ -0,0 +1,18 @@
# `appShell: string`

> Default: `null`.
> **Example:** `'/'`
When making a Singe Page Application, it's common to use [AppShell](https://medium.com/google-developers/instant-loading-web-apps-with-an-application-shell-architecture-7c0c2f10c73) model for it.

To make `offline-plugin` redirect all unknown navigation requests to a specific cache, specify `appShell` option, e.g. `appShell: '/'`.

### SSR

When using Server Side Rendering with AppShell model, make sure that you do not cache any server rendered data with it. Easiest way would be to make a route which will be serving the HTML file without any server rendered data in it (e.g. ready for client side rendering) and cache that route. Example: `appShell: '/app-shell.html'`

### Advanced

Previously, to achieve the same effect, `ServiceWorker.navigateFallbackURL` and `AppCache.FALLBACK` option had to be used. `ServiceWorker.navigateFallbackURL` is now deprecated and shouldn't be used at all. Instead, `appShell` should be used.

`appShell` is baked by `cacheMaps` option for `ServiceWorker` and `AppCache.FALLBACK` option for `AppCache`.
76 changes: 76 additions & 0 deletions docs/navigation-preload.md
Original file line number Diff line number Diff line change
@@ -0,0 +1,76 @@
## `navigationPreload: boolean | Object | ':auto:'`
> _Default:_ `':auto:'`
[Navigation preload](https://developers.google.com/web/updates/2017/02/navigation-preload) is a ServiceWorker's feature which provides a way to make a request to the website even before ServiceWorker or a page is initialized. This can be useful for data fetching to speedup loading of the application.

### Usage

In `offline-plugin`, _Navigation preload_ behaves differently for `cache-first` and `network-first` response strategies.

For `network-first` navigation preload is enabled by default and allows to fetch navigation pages ahead of time, even before ServiceWorker was initialized. To disabled it set `ServiceWorker.navigationPreload` option to `false`.

For `cache-first` navigation preload has to be enabled manually and also handled on the server side. To enabled navigation preload two functions has to be specified:

```js
ServiceWorker: {
navigationPreload: {
map: (url) => {
if (url.pathname === '/') {
return '/api/feed';
}

var post = url.pathname.match(/^\/post\/(\d+)$/);

if (post) {
return '/api/post/' + post[1];
}
},
test: (url) => {
if (url.pathname.indexOf('/api/') === 0) {
return true;
}
}
},
}
```

* `map` function is used to map navigation preload request to other requests, e.g. API requests.
* `test` function is used to test for possible consumers of navigation preload mapping

In previous example `map` function maps navigation preload of `/` to `/api/feed`. Then when a request to `/api/feed` happens, `test` function is used to determine that such request might be preloaded with _navigation preload_ (it checks if `pathname` of the request starts with `/api/`).

#### Server Side

When a navigation preload request happens, it contains `Service-Worker-Navigation-Preload: true` header. Server side should use this header to detect the preload and send different content to such request.

Express.js example:

```js
function serveIndex(req, res) {
if (req.headers['service-worker-navigation-preload']) {
res.set({
'Cache-Control': 'no-cache',
'Vary': 'Service-Worker-Navigation-Preload'
});

fetchFeedData(req).then((data) => {
res.send(data);
});

return;
}

res.sendFile(path.join(WWW_FOLDER, 'index.html'), {
cacheControl: false,
acceptRanges: false,
headers: {
'Cache-Control': 'no-cache',
'Vary': 'Service-Worker-Navigation-Preload'
}
});
}
```

Make sure to set **`'Vary': 'Service-Worker-Navigation-Preload'`** header if you're planning on caching those responses.

For more details on Navigation Preload see [this article](https://developers.google.com/web/updates/2017/02/navigation-preload).
92 changes: 58 additions & 34 deletions docs/options.md
Original file line number Diff line number Diff line change
@@ -1,7 +1,14 @@
## Options

**All options are optional and `offline-plugin` can be used without specifying them.**
_Also see list of default options [here](https://github.com/NekR/offline-plugin/blob/master/src/index.js#L17)._
_Also see list of default options [here](../src/default-options.js)._

#### `appShell: string`

[See `appShell` option documentation](app-shell.md)

> Default: `null`.
> **Example:** `'/index.html'`
#### `caches: 'all' | Object`

Expand All @@ -16,37 +23,45 @@ Allows you to define what to cache and how.
#### `publicPath: string`

Same as `webpack`'s `output.publicPath` option. Useful to specify or override `publicPath` specifically for `offline-plugin`. When not specified, `webpack`'s `output.publicPath` value is used. When `webpack`'s `output.publicPath` value isn't specified, relative paths are used (see `relativePaths` option).
Similar to `webpack`'s `output.publicPath` option. Useful to specify or override `publicPath` specifically for `offline-plugin`. When not specified, `webpack`'s `output.publicPath` value is used. When `publicPath` value isn't spsecified at all (either by this option or by `webpack`'s `output.publicPath` option), relative paths are used (see `relativePaths` option).

> __Examples:__
`publicPath: '/project/'`
`publicPath: 'https://example.com/project'`

#### `responseStrategy: 'cache-first' | 'network-first'`
Response strategy. Whether to use a cache or network first for responses.

With `'cache-first'` all request are sent to consult the cache first and if the cache is empty, request is sent to the network.

With `'network-first'` all request are sent to the network first and if network request fails consult the cache as a fallback.
> Default: `'cache-first'`.
#### `updateStrategy: 'changed' | 'all'`
Cache update strategy. [More details about `updateStrategy`](update-strategies.md)
**Please, do not change this option unless you're sure you know what you're doing.**
> Default: `'changed'`.
#### `externals: Array<string>`
Allows you to specify _external_ assets (assets which aren't generated by webpack) that should be included in the cache. If you don't change the `caches` configuration option then it should be enough to simply add assets to this (`externals`) option. For other details and more advanced use cases see [`caches` docs](caches.md).

Allows you to specify additional (external to the build process) URLs to be cached.

> Default: `null`
> **Example value:** `['fonts/roboto.woff']`
> **Example:** `['/static/file-on-the-server.json', 'https://fonts.googleapis.com/css?family=Roboto']`
#### `excludes: Array<string | globs_pattern>`
Excludes matched assets from being added to the [caches](https://github.com/NekR/offline-plugin#caches-all--object). Exclusion is performed before [_rewrites_](https://github.com/NekR/offline-plugin/blob/master/docs/options.md#rewrites-function--object) happens.
[Learn more about assets _rewrite_](rewrites.md)

> Default: `['**/.*', '**/*.map']`
> _Excludes all files which start with `.` or end with `.map`_
> Default: `['**/.*', '**/*.map', '**/*.gz']`
> _Excludes all files which start with `.` or end with `.map` or `.gz`_
#### `relativePaths: boolean`
When set to `true`, all the asset paths generated in the cache will be relative to the `ServiceWorker` file or the `AppCache` folder location respectively.
`publicPath` option is ignored when this is **explicitly** set to `true`.
> **Default:** `true`

This option is ignored when `publicPath` is set.
`publicPath` option is ignored when this option is set **explicitly** to `true`.
> Default: `true`
#### `version: string | (plugin: OfflinePlugin) => void`
Version of the cache. Can be a function, which is useful in _watch-mode_ when you need to apply dynamic value.
Expand All @@ -58,7 +73,10 @@ Version of the cache. Can be a function, which is useful in _watch-mode_ when yo
#### `rewrites: Function | Object`

Rewrite function or rewrite map (`Object`). Useful when assets are served in a different way from the client perspective, e.g. usually `index.html` is served as `/`.
Provides a way to rewrite final representation of the file on the server.
Useful when assets are served in a different way from the client perspective, e.g. usually `/index.html` is served as `/`.

Can be either a function or an `Object`.

[See more about `rewrites` option and default function](rewrites.md)

Expand All @@ -68,7 +86,7 @@ See [documentation of `cacheMaps`](cache-maps.md) for syntax and usage examples

#### `autoUpdate: true | number`

Enables automatic updates of ServiceWorker and AppCache. If set to `true`, it uses default interval of _1 hour_. Set a `number` value to have provide custom update interval.
Enables automatic updates of ServiceWorker and AppCache. If set to `true`, it uses default interval of _1 hour_. Set a `number` value to provide custom update interval.

_**Note:** Please note that if user has multiple opened tabs of your website then update may happen more often because each opened tab will have its own interval for updates._

Expand All @@ -80,66 +98,72 @@ _**Note:** Please note that if user has multiple opened tabs of your website the

Settings for the `ServiceWorker` cache. Use `null` or `false` to disable `ServiceWorker` generation.

* `output`: `string`. Relative (from the _webpack_'s config `output.path`) output path for emitted script.
* **`output`**: `string`. Relative (from the _webpack_'s config `output.path`) output path for emitted script.
_Default:_ `'sw.js'`

* `entry`: `string`. Relative or absolute path to the file which will be used as the `ServiceWorker` entry/bootstrapping. Useful to implement additional features or handlers for Service Worker events such as `push`, `sync`, etc.
* **`entry`**: `string`. Relative or absolute path to the file which will be used as the `ServiceWorker` entry/bootstrapping. Useful to implement additional features or handlers for Service Worker events such as `push`, `sync`, etc.
_Default:_ _empty file_

* `scope`: `string`. Reflects [ServiceWorker.register](https://developer.mozilla.org/en-US/docs/Web/API/ServiceWorkerContainer/register)'s `scope` option.
* **`scope`**: `string`. Reflects [ServiceWorker.register](https://developer.mozilla.org/en-US/docs/Web/API/ServiceWorkerContainer/register)'s `scope` option.
_Default:_ `null`

* `cacheName`: `string`. **This option is very dangerous. Touching it you must realize that you should **not** change it after you go production. Changing it may corrupt the cache and leave old caches on users' devices. This option is useful when you need to run more than one project on _the same domain_.
* **`cacheName`**: `string`. **This option is very dangerous.** This option should **not** be changed at all after you deploy `ServiceWorker` to production. Changing it may corrupt the cache and leave old caches on users' devices.

This option is useful when you need to run more than one project on _the same domain_.
_Default:_ _`''`_ (empty string)
_Example:_ `'my-project'`

* `navigateFallbackURL`: `string`. The URL that should be returned from the cache when a requested navigation URL isn't available on the cache or network. Similar to the `AppCache.FALLBACK` option.
_Example:_ `navigateFallbackURL: '/'`

* `navigateFallbackForRedirects`: `boolean`. If this flag is false `navigateFallbackURL` will not be used for 3xx responses. (By default it will be used for all non 2xx navigate responses).
_Example:_ `navigateFallbackForRedirects: false`
_Default:_ `true`

* `events`: `boolean`. Enables runtime events for the ServiceWorker. For supported events see `Runtime`'s `install()` options.
* **`events`**: `boolean`. Enables runtime events for the ServiceWorker. For supported events see [`Runtime`](runtime.md)'s `install()` options.
_Default:_ `false`

* `publicPath`: `string`. Provides a way to override `ServiceWorker`'s script file location on the server. Should be an exact path to the generated `ServiceWorker` file.
* **`publicPath`**: `string`. Provides a way to override `ServiceWorker`'s script file location on the server. Should be an exact path to the generated `ServiceWorker` file.
_Default:_ `null`
_Example:_ `'my/new/path/sw.js'`
_Example:_ `'/my/new/path/sw.js'`

* **`navigationPreload`**: `boolean | Object | ':auto:'`. [See `ServiceWorker.navigationPreload` option documentation](navigation-preload.md)

_Default:_ `':auto:'`

* `prefetchRequest`: `Object`. Provides a way to specify [request init options](https://developer.mozilla.org/en-US/docs/Web/API/Request/Request) for pre-fetch requests (pre-cache requests on `install` event). Allowed options: `credentials`, `headers`, `mode`, `cache`.
* **`prefetchRequest`**: `Object`. Provides a way to specify [request init options](https://developer.mozilla.org/en-US/docs/Web/API/Request/Request) for pre-fetch requests (pre-cache requests on `install` event). Allowed options: `credentials`, `headers`, `mode`, `cache`.
_Default:_ `{ credentials: 'omit', mode: 'cors' }`
_Example:_ `{ credentials: 'same-origin' }`
_Example:_ `{ credentials: 'include' }`

* `minify`: `boolean`. If set to `true` or `false`, the `ServiceWorker`'s output will be minified or not accordingly. If set to something else, the `ServiceWorker` output will be minified **if** you are using `webpack.optimize.UglifyJsPlugin` in your configuration.
* **`minify`**: `boolean`. If set to `true` or `false`, the `ServiceWorker`'s output will be minified or not accordingly. If set to something else, the `ServiceWorker` output will be minified **if** you are using `webpack.optimize.UglifyJsPlugin` in your configuration.
_Default:_ `null`

* **[Deprecated]** `navigateFallbackURL`: `string`. The URL that should be returned from the cache when a requested navigation URL isn't available on the cache or network. Similar to the `AppCache.FALLBACK` option.
_Example:_ `navigateFallbackURL: '/'`

* **[Deprecated]** `navigateFallbackForRedirects`: `boolean`. If this flag is false `navigateFallbackURL` will not be used for 3xx responses. (By default it will be used for all non 2xx navigate responses).
_Example:_ `navigateFallbackForRedirects: false`
_Default:_ `true`

#### `AppCache: Object | null | false`

Settings for the `AppCache` cache. Use `null` or `false` to disable `AppCache` generation.

> _**Warning**_: Officially the AppCache feature [has been deprecated](https://developer.mozilla.org/en-US/docs/Web/HTML/Using_the_application_cache) in favour of Service Workers. However, Service Workers are still being implemented across all browsers (you can track progress [here](https://jakearchibald.github.io/isserviceworkerready/)) so AppCache is unlikely to suddenly disappear. Therefore please don't be afraid to use the AppCache feature if you have a need to provide offline support to browsers that do not support Service Workers, but it is good to be aware of this fact and make a deliberate decision on your configuration.
* `directory`: `string`. Relative (from the _webpack_'s config `output.path`) output directly path for the `AppCache` emitted files.
* **`directory`**: `string`. Relative (from the _webpack_'s config `output.path`) output directly path for the `AppCache` emitted files.
_Default:_ `'appcache/'`

* `NETWORK`: `string`. Reflects `AppCache`'s `NETWORK` section.
* **`NETWORK`**: `string`. Reflects `AppCache`'s `NETWORK` section.
_Default:_ `'*'`

* `FALLBACK`: `Object`. Reflects `AppCache`'s `FALLBACK` section. Useful for single page applications making use of HTML5 routing or for displaying custom _Offline page_.
* **`FALLBACK`**: `Object`. Reflects `AppCache`'s `FALLBACK` section. Useful for single page applications making use of HTML5 routing or for displaying custom _Offline page_.
_Example 1:_ `{ '/blog': '/' }` will map all requests starting with `/blog` to the domain roboto when request fails.
_Example 2:_ `{ '/': '/offline-page.html' }` will return contents of `/offline-page.html` for any failed request.
_Default:_ `null`

* `events`: `boolean`. Enables runtime events for AppCache. For supported events see `Runtime`'s `install()` options.
* **`events`**: `boolean`. Enables runtime events for AppCache. For supported events see [`Runtime`](runtime.md)'s `install()` options.
_Default:_ `false`

* `publicPath`: `string`. Provides a way to override `AppCache`'s folder location on the server. Should be exact path to the generated `AppCache` folder.
* **`publicPath`**: `string`. Provides a way to override `AppCache`'s folder location on the server. Should be exact path to the generated `AppCache` folder.
_Default:_ `null`
_Example:_ `'my/new/path/appcache'`

* `disableInstall` :`boolean`. Disable the automatic installation of the `AppCache` when calling to `runtime.install()`. Useful when you to specify `<html manifest="...">` attribute manually (to cache every page user visits).
* **`disableInstall`**: `boolean`. Disable the automatic installation of the `AppCache` when calling `runtime.install()`. Useful when you want to specify `<html manifest="...">` attribute manually (to cache every page user visits).
_Default:_ `false`

* `includeCrossOrigin` :`boolean`. Outputs cross-origin URLs into `AppCache`'s manifest file. **Cross-origin URLs aren't supported in `AppCache` when used on HTTPS.**
* **`includeCrossOrigin`**: `boolean`. Outputs cross-origin URLs into `AppCache`'s manifest file. **Cross-origin URLs aren't supported in `AppCache` when used on HTTPS.**
_Default:_ `false`
Loading

0 comments on commit f607943

Please sign in to comment.