Skip to content
This repository was archived by the owner on Oct 12, 2021. It is now read-only.

Commit 0183d00

Browse files
authored
feat(worker): webpack plugin for generating service worker manifests (#97)
1 parent 508c55c commit 0183d00

File tree

6 files changed

+132
-3
lines changed

6 files changed

+132
-3
lines changed

service-worker/worker/gulpfile.ts

Lines changed: 51 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -14,6 +14,9 @@ var merge = require('merge-stream');
1414
var exec = require('child_process').exec;
1515
var uglify = require('gulp-uglify');
1616
var rename = require('gulp-rename');
17+
var webpack = require('webpack');
18+
19+
import AngularServiceWorkerPlugin from './src/webpack';
1720

1821
let assign = (dest, ...sources) => {
1922
sources.forEach(source => {
@@ -44,13 +47,21 @@ gulp.task('clean', (done) => {
4447
rimraf('./dist', done);
4548
});
4649

47-
gulp.task('prepublish', ['build']);
50+
gulp.task('clean:src', done => {
51+
rimraf('./dist/src', done);
52+
});
53+
54+
gulp.task('prepublish', done => runSequence(
55+
'build',
56+
'clean:src',
57+
done
58+
));
4859

4960
gulp.task('build', done => runSequence(
5061
'clean',
5162
[
5263
'task:companion:build',
53-
'task:generator:build',
64+
'task:webpack:build',
5465
'task:worker:build'
5566
],
5667
done
@@ -71,6 +82,44 @@ gulp.task('generator:build', done => runSequence(
7182
'task:generator:build',
7283
done));
7384

85+
gulp.task('task:webpack_test:pack', done => {
86+
console.log(process.cwd());
87+
webpack({
88+
context: `${process.cwd()}/src/test/webpack`,
89+
entry: './index.js',
90+
output: {
91+
path: `${process.cwd()}/dist/src/test/webpack`,
92+
filename: 'index.js'
93+
},
94+
plugins: [
95+
new AngularServiceWorkerPlugin()
96+
]
97+
}, () => done())
98+
});
99+
100+
gulp.task('task:webpack:build', done => runSequence(
101+
'task:webpack:compile',
102+
'task:webpack:copy_deploy',
103+
done
104+
));
105+
106+
gulp.task('task:webpack:compile', () => gulp
107+
.src([
108+
'src/webpack/**/*.ts'
109+
], {
110+
base: 'src/webpack'
111+
})
112+
.pipe(ts(commonCompilerConfig))
113+
.pipe(gulp.dest('dist')));
114+
115+
gulp.task('task:webpack:copy_deploy', () => gulp
116+
.src([
117+
'dist/src/webpack/index.js'
118+
], {
119+
base: 'dist/src/webpack'
120+
})
121+
.pipe(gulp.dest('dist/webpack')));
122+
74123
gulp.task('task:companion:build', done => runSequence(
75124
'task:companion:compile',
76125
'task:companion:copy_deploy',

service-worker/worker/package.json

Lines changed: 2 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -57,6 +57,7 @@
5757
"base64-js": "^1.1.2",
5858
"broccoli-caching-writer": "^2.2.1",
5959
"fs-extra": "^0.30.0",
60-
"jshashes": "^1.0.5"
60+
"jshashes": "^1.0.5",
61+
"webpack": "^2.1.0-beta.21"
6162
}
6263
}
Lines changed: 8 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,8 @@
1+
<!doctype html>
2+
<html>
3+
<head>
4+
<script src="/index.js"></script>
5+
</head>
6+
<body>
7+
</body>
8+
</html>
Lines changed: 4 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,4 @@
1+
// This is a test.
2+
require('./other');
3+
4+
console.log('testing');
Lines changed: 2 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,2 @@
1+
// This is another file.
2+
console.log('this is another file');
Lines changed: 65 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,65 @@
1+
declare var require;
2+
3+
let fs = require('fs');
4+
let SHA1 = require('jshashes').SHA1;
5+
6+
/**
7+
* Webpack plugin that generates a basic Angular service worker manifest.
8+
*/
9+
export default class AngularServiceWorkerPlugin {
10+
11+
constructor(public manifestFile = 'ngsw-manifest.json') {}
12+
13+
apply(compiler) {
14+
// Determine the destination directory and the URL prefix for the app.
15+
let outputPath = compiler.options.output.path;
16+
let publicPrefix = compiler.options.output.publicPath || '';
17+
if (!outputPath) {
18+
throw 'Must have output path set.';
19+
}
20+
21+
// Used to compute version hashes.
22+
let sha1 = new SHA1();
23+
24+
// Wait until webpack builds the whole output directory. Every file being
25+
// deployed to the server needs to be included in the manifest.
26+
compiler.plugin('done', stats => {
27+
// Manifest into which assets to be fetched will be recorded. This will either
28+
// be read from the existing template or created fresh.
29+
let manifest: any = {};
30+
31+
// Look for an existing manifest. If there is one, parse it.
32+
let manifestPath = `${outputPath}/${this.manifestFile}`;
33+
if (fs.existsSync(manifestPath)) {
34+
manifest = JSON.parse(fs.readFileSync(manifestPath, 'utf8')) || {};
35+
}
36+
37+
// Validate that the manifest has a default group set up properly, with
38+
// the map for its URLs.
39+
if (!manifest.group) {
40+
manifest.group = {};
41+
}
42+
if (!manifest.group.default) {
43+
manifest.group.default = {};
44+
}
45+
if (!manifest.group.default.url) {
46+
manifest.group.default.url = {};
47+
}
48+
49+
// Go through every asset in the compilation and include it in the manifest,
50+
// computing a hash for proper versioning.
51+
Object
52+
.keys(stats.compilation.assets)
53+
.forEach(asset => {
54+
let url = `${publicPrefix}/${asset}`;
55+
manifest.group.default.url[url] = {
56+
// TODO(alxhub): use webpack cached version if available.
57+
hash: sha1.hex(fs.readFileSync(`${outputPath}/${asset}`, 'utf8'))
58+
};
59+
});
60+
61+
// Write the merged manifest to disk.
62+
fs.writeFileSync(manifestPath, JSON.stringify(manifest));
63+
});
64+
}
65+
}

0 commit comments

Comments
 (0)