Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Update from base repository #1

Merged
3 commits merged into from
Mar 1, 2019
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
2 changes: 2 additions & 0 deletions .travis.yml
Original file line number Diff line number Diff line change
Expand Up @@ -7,6 +7,8 @@ node_js:
env:
- TEST_METHOD=ci_fixtures WEBPACK_VERSION=2
- TEST_METHOD=ci_fixtures WEBPACK_VERSION=3
# webpack 4.26 switched to terser-webpack-plugin
- TEST_METHOD=ci_fixtures WEBPACK_VERSION=4.25
- TEST_METHOD=ci_fixtures WEBPACK_VERSION=4
matrix:
include:
Expand Down
11 changes: 10 additions & 1 deletion docs/FAQ.md
Original file line number Diff line number Diff line change
Expand Up @@ -3,7 +3,7 @@
___________________________________

**Is it possible to minify `ServiceWorker` script output?**
Yes, `offline-plugin` perfectly works with official `webpack.optimize.UglifyJsPlugin`, so if it's used you will get minified `ServiceWorker` script as well (no additional options required).
Yes, `offline-plugin` perfectly works with official `webpack.optimize.UglifyJsPlugin` and `terser-webpack-plugin`. If used, the `ServiceWorker` script will be minified as well (no additional options required).

**Is there a way to match assets with dynamic file names, like compilation hash or version?**
Yes, it's possible with `pattern matching`, which is performed by [minimatch](https://www.npmjs.com/package/minimatch) library.
Expand Down Expand Up @@ -34,3 +34,12 @@ onUpdateReady: function() {
OfflinePlugin.applyUpdate();
}
```

**How can I use absolute paths?**
By default `offline-plugin` uses `relativePaths: true`. You can override this by setting an (absolute) `publicPath`. This makes `offline-plugin` ignore `relativePaths`:

```js
new OfflinePlugin({
publicPath: '/'
})
```
2 changes: 1 addition & 1 deletion docs/options.md
Original file line number Diff line number Diff line change
Expand Up @@ -95,7 +95,7 @@ _Default:_ `':auto:'`
_Default:_ `{ credentials: 'omit', mode: 'cors' }`
_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` or `terser-webpack-plugin` in your configuration.
_Default:_ `null`

#### `publicPath: string`
Expand Down
1 change: 1 addition & 0 deletions docs/runtime.md
Original file line number Diff line number Diff line change
Expand Up @@ -9,6 +9,7 @@ require('offline-plugin/runtime').install();
```

ES6/Babel/TypeScript

```js
import * as OfflinePluginRuntime from 'offline-plugin/runtime';
OfflinePluginRuntime.install();
Expand Down
30 changes: 29 additions & 1 deletion docs/troubleshooting.md
Original file line number Diff line number Diff line change
Expand Up @@ -20,8 +20,8 @@ Automatic updates isn't the default behavior, but can be achieved using the [aut

#### All routes/resources aren't being cached


`offline-plugin` automatically caches all resources generated by webpack. Any other resource needs to be explicitly cached as [external](options.md#externals-arraystring).

#### Some pages / resources are not being served at all

The ServiceWorker can only serve resources within its [scope](https://developer.mozilla.org/en-US/docs/Web/API/ServiceWorkerContainer/register). Serve your sw file from the root of your public folder, or supply the correct [`ServiceWorker.scope` option](options.md#serviceworker-object--null--false).
Expand Down Expand Up @@ -53,3 +53,31 @@ There are multiple ways to fix this depending on your setup. One way is to set [
#### Resources served from a CDN are not being cached

`offline-plugin` can cache resources served from a CDN, given the correct configuration. Make sure the resources are served with the correct headers.

#### DOMException: Failed to register a ServiceWorker: The script has an unsupported MIME type ('text/html') Error

Make sure your webserver is serving your assets (including `sw.js`) with the correct mime type. Also, make sure you are using relative / absolute paths correctly (see the [`FAQ`](FAQ.md) regarding this). Also make sure that ServiceWorker and/or AppCache files are generated into the correct folder. You may use `ServiceWorker.output` and `AppCache.output` to change the output path. See [options](options.md) for details.

#### Fetching the ServiceWorker results in an error

Some errors, like being unable to fetch the ServiceWorker file, originates from the browser, network or server and are out of control of `offline-plugin`. Here is a list of common errors and their causes.

> TypeError: Failed to update a ServiceWorker: A bad HTTP response code (500) was received when fetching the script.

This is a server error. Whatever happens there - it shouldn't. Could be that the server is temporarily down (e.g. changing a deployment on Zeit).

> TypeError: Failed to fetch

This is the most generic error you will receive. It typically happens when there's no network connection - it simply can't fetch the file.

> AbortError: Failed to update a ServiceWorker: The request to fetch the script was interrupted.

This is a network error - something interrupted the connection. It might be due to the network connection being changed or temporarily lost (it happens all the time in the wild).

> TypeError: Script URL https://my-page.com/sw.js fetch resulted in error: An SSL error has occurred and a secure connection to the server cannot be made.

This is a proxy issue. Ie. someone sitting at an airport or on a train and that network injects fake HTTPS certificates (man in the middle).

#### How to handle out-of-control errors

As the above errors are out of the control of `offline-plugin`, there is nothing we can do to prevent them. What you may do if you receive any of them is to catch them in your code and try to reschedule the update. Also make sure that your server works correctly and remove any potential bugs / error situation causing HTTP 500 Internal Server Error.
46 changes: 46 additions & 0 deletions lib/misc/get-minification-plugin.js
Original file line number Diff line number Diff line change
@@ -0,0 +1,46 @@
'use strict';

var webpack = require('webpack');
var MinificationPlugin = undefined;
var isUsingTerser = false;

if (!MinificationPlugin) {
try {
MinificationPlugin = require('terser-webpack-plugin');
isUsingTerser = true;
} catch (e) {}
}

if (!MinificationPlugin) {
try {
MinificationPlugin = webpack.optimize.UglifyJsPlugin;
} catch (e) {}
}

if (!MinificationPlugin) {
try {
MinificationPlugin = require('uglifyjs-webpack-plugin');
} catch (e) {}
}

module.exports = MinificationPlugin ? {
makeMinificationPlugin: function makeMinificationPlugin(args) {
var normalizedArgs = args;
// port uglifyOptions to terserOptions when using terser webpack plugin
if (isUsingTerser && args && args.uglifyOptions) {
normalizedArgs = Object.assign({}, args);
normalizedArgs.terserOptions = args.uglifyOptions;
delete normalizedArgs.uglifyOptions;
}

return new MinificationPlugin(normalizedArgs);
},
isMinificationPlugin: function isMinificationPlugin(plugin) {
return plugin instanceof MinificationPlugin;
}
} : {
makeMinificationPlugin: null,
isMinificationPlugin: function isMinificationPlugin(plugin) {
return false;
}
};
16 changes: 0 additions & 16 deletions lib/misc/get-uglify-plugin.js

This file was deleted.

24 changes: 10 additions & 14 deletions lib/service-worker.js
Original file line number Diff line number Diff line change
Expand Up @@ -14,9 +14,7 @@ var _webpackLibSingleEntryPlugin = require('webpack/lib/SingleEntryPlugin');

var _webpackLibSingleEntryPlugin2 = _interopRequireDefault(_webpackLibSingleEntryPlugin);

var _miscGetUglifyPlugin = require('./misc/get-uglify-plugin');

var _miscGetUglifyPlugin2 = _interopRequireDefault(_miscGetUglifyPlugin);
var _miscGetMinificationPlugin = require('./misc/get-minification-plugin');

var _path = require('path');

Expand Down Expand Up @@ -104,25 +102,25 @@ var ServiceWorker = (function () {
};

if (this.minify === true) {
if (!_miscGetUglifyPlugin2['default']) {
throw new Error('OfflinePlugin: uglifyjs-webpack-plugin is required to preform a minification');
if (_miscGetMinificationPlugin.makeMinificationPlugin == null) {
throw new Error('OfflinePlugin: uglifyjs-webpack-plugin or terser-webpack-plugin is required to preform a minification');
}

var options = {
test: new RegExp(name),
uglifyOptions: uglifyOptions
};

new _miscGetUglifyPlugin2['default'](options).apply(childCompiler);
} else if ((this.minify !== false || optimization.minimize) && _miscGetUglifyPlugin2['default']) {
// Do not perform auto-minification if UglifyJsPlugin isn't installed
(0, _miscGetMinificationPlugin.makeMinificationPlugin)(options).apply(childCompiler);
} else if ((this.minify !== false || optimization.minimize) && _miscGetMinificationPlugin.makeMinificationPlugin) {
// Do not perform auto-minification if MinificationPlugin isn't installed

var added = (optimization.minimize && optimization.minimizer || []).concat(compiler.options.plugins || []).some(function (plugin) {
if (plugin instanceof _miscGetUglifyPlugin2['default']) {
if ((0, _miscGetMinificationPlugin.isMinificationPlugin)(plugin)) {
var options = (0, _deepExtend2['default'])({}, plugin.options);

options.test = new RegExp(name);
new _miscGetUglifyPlugin2['default'](options).apply(childCompiler);
(0, _miscGetMinificationPlugin.makeMinificationPlugin)(options).apply(childCompiler);

return true;
}
Expand All @@ -134,7 +132,7 @@ var ServiceWorker = (function () {
uglifyOptions: uglifyOptions
};

new _miscGetUglifyPlugin2['default'](options).apply(childCompiler);
(0, _miscGetMinificationPlugin.makeMinificationPlugin)(options).apply(childCompiler);
}
}

Expand Down Expand Up @@ -176,9 +174,7 @@ var ServiceWorker = (function () {
if (typeof this.minify === 'boolean') {
minify = this.minify;
} else {
minify = !!_miscGetUglifyPlugin2['default'] && (!!(compiler.options.optimization && compiler.options.optimization.minimize) || !!(compiler.options.plugins || []).some(function (plugin) {
return plugin instanceof _miscGetUglifyPlugin2['default'];
}));
minify = _miscGetMinificationPlugin.makeMinificationPlugin && (!!(compiler.options.optimization && compiler.options.optimization.minimize) || !!(compiler.options.plugins || []).some(_miscGetMinificationPlugin.isMinificationPlugin));
}

var source = this.getDataTemplate(plugin.caches, plugin, minify);
Expand Down
40 changes: 40 additions & 0 deletions src/misc/get-minification-plugin.js
Original file line number Diff line number Diff line change
@@ -0,0 +1,40 @@
const webpack = require('webpack');
let MinificationPlugin;
let isUsingTerser = false;

if (!MinificationPlugin) {
try {
MinificationPlugin = require('terser-webpack-plugin');
isUsingTerser = true;
} catch (e) {}
}

if (!MinificationPlugin) {
try {
MinificationPlugin = webpack.optimize.UglifyJsPlugin;
} catch (e) {}
}

if (!MinificationPlugin) {
try {
MinificationPlugin = require('uglifyjs-webpack-plugin');
} catch (e) {}
}

module.exports = MinificationPlugin ? {
makeMinificationPlugin: (args) => {
let normalizedArgs = args;
// port uglifyOptions to terserOptions when using terser webpack plugin
if (isUsingTerser && args && args.uglifyOptions) {
normalizedArgs = Object.assign({}, args);
normalizedArgs.terserOptions = args.uglifyOptions;
delete normalizedArgs.uglifyOptions;
}

return new MinificationPlugin(normalizedArgs);
},
isMinificationPlugin: (plugin) => plugin instanceof MinificationPlugin,
} : {
makeMinificationPlugin: null,
isMinificationPlugin: (plugin) => false,
};
14 changes: 0 additions & 14 deletions src/misc/get-uglify-plugin.js

This file was deleted.

28 changes: 13 additions & 15 deletions src/service-worker.js
Original file line number Diff line number Diff line change
@@ -1,5 +1,5 @@
import SingleEntryPlugin from 'webpack/lib/SingleEntryPlugin';
import UglifyJsPlugin from './misc/get-uglify-plugin';
import { makeMinificationPlugin, isMinificationPlugin } from './misc/get-minification-plugin';
import path from 'path';
import deepExtend from 'deep-extend';
import {
Expand Down Expand Up @@ -82,28 +82,28 @@ export default class ServiceWorker {
};

if (this.minify === true) {
if (!UglifyJsPlugin) {
throw new Error('OfflinePlugin: uglifyjs-webpack-plugin is required to preform a minification')
if (makeMinificationPlugin == null) {
throw new Error('OfflinePlugin: uglifyjs-webpack-plugin or terser-webpack-plugin is required to preform a minification')
}

const options = {
test: new RegExp(name),
uglifyOptions: uglifyOptions
uglifyOptions,
};

new UglifyJsPlugin(options).apply(childCompiler);
makeMinificationPlugin(options).apply(childCompiler);
} else if (
(this.minify !== false || optimization.minimize) && UglifyJsPlugin
(this.minify !== false || optimization.minimize) && makeMinificationPlugin
) {
// Do not perform auto-minification if UglifyJsPlugin isn't installed
// Do not perform auto-minification if MinificationPlugin isn't installed

const added = ((optimization.minimize && optimization.minimizer) || [])
.concat(compiler.options.plugins || []).some((plugin) => {
if (plugin instanceof UglifyJsPlugin) {
if (isMinificationPlugin(plugin)) {
const options = deepExtend({}, plugin.options);

options.test = new RegExp(name);
new UglifyJsPlugin(options).apply(childCompiler);
makeMinificationPlugin(options).apply(childCompiler);

return true;
}
Expand All @@ -112,10 +112,10 @@ export default class ServiceWorker {
if (!added && optimization.minimize) {
const options = {
test: new RegExp(name),
uglifyOptions: uglifyOptions
uglifyOptions,
};

new UglifyJsPlugin(options).apply(childCompiler);
makeMinificationPlugin(options).apply(childCompiler);
}
}

Expand Down Expand Up @@ -156,14 +156,12 @@ export default class ServiceWorker {
if (typeof this.minify === 'boolean') {
minify = this.minify;
} else {
minify = !!UglifyJsPlugin && (
minify = makeMinificationPlugin && (
!!(
compiler.options.optimization &&
compiler.options.optimization.minimize
) || !!(
(compiler.options.plugins || []).some((plugin) => {
return plugin instanceof UglifyJsPlugin;
})
(compiler.options.plugins || []).some(isMinificationPlugin)
)
);
}
Expand Down
4 changes: 2 additions & 2 deletions tests/legacy/fixtures/sw-minify-auto/webpack.config.js
Original file line number Diff line number Diff line change
@@ -1,4 +1,4 @@
var UglifyJsPlugin = require(__ROOT__ + '/lib/misc/get-uglify-plugin');
var makeMinificationPlugin = require(__ROOT__ + '/lib/misc/get-minification-plugin').makeMinificationPlugin;

var config = __CONFIG__({
caches: {
Expand All @@ -11,7 +11,7 @@ var config = __CONFIG__({
swMetadataOnly: false
});

config.plugins.push(new UglifyJsPlugin({
config.plugins.push(makeMinificationPlugin({
uglifyOptions: {
compress: {
warnings: false,
Expand Down
4 changes: 2 additions & 2 deletions tests/legacy/fixtures/sw-minify-false/webpack.config.js
Original file line number Diff line number Diff line change
@@ -1,4 +1,4 @@
var UglifyJsPlugin = require(__ROOT__ + '/lib/misc/get-uglify-plugin');
var makeMinificationPlugin = require(__ROOT__ + '/lib/misc/get-minification-plugin').makeMinificationPlugin;

var config = __CONFIG__({
caches: {
Expand All @@ -14,7 +14,7 @@ var config = __CONFIG__({
swMetadataOnly: false
});

config.plugins.push(new UglifyJsPlugin({
config.plugins.push(makeMinificationPlugin({
uglifyOptions: {
compress: {
warnings: false,
Expand Down