-
Notifications
You must be signed in to change notification settings - Fork 1
/
Copy pathindex.js
132 lines (111 loc) · 3.79 KB
/
index.js
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
const path = require('path');
const _ = require('lodash');
class NginxPushWebpackPlugin {
constructor(options) {
// Default options
this.options = {
filename: 'nginx.push.conf',
index: 'index.html',
omitNginxLocation: false,
...options,
};
}
// Define `apply` as its prototype method which is supplied with compiler as its argument
apply(compiler) {
// convert absolute filename into relative so that webpack can
// generate it at correct location
const { filename } = this.options;
if (path.resolve(filename) === path.normalize(filename)) {
this.options.filename = path.relative(compiler.options.output.path, filename);
}
// Specify the event hook to attach to
compiler.hooks.emit.tapAsync('NginxPushWebpackPlugin', (compilation, callback) => {
const allChunks = compilation.getStats().toJson().chunks;
// Filter out chunks without initialName
const chunks = this.filterChunks(allChunks);
// get all assets
const assets = this.getAssets(compilation, chunks);
Promise
.resolve()
// write assets to nginx
.then(() => this.writeToNginxConf(assets))
.then((conf) => {
// Replace the compilation result with the evaluated conf code
compilation.assets[this.options.filename] = {
source: () => conf,
size: () => conf.length,
};
}).catch((err) => {
console.error(err);
return null;
})
.then(() => {
callback();
});
});
}
writeToNginxConf(assets) {
const { index, omitNginxLocation } = this.options;
const content = [
`# Automatically generated by NginxPushWebpackPlugin, don't change it manually
# Please include this file in your nginx web server directive
# \`\`\`
# include nginx.push.conf;
# \`\`\``];
if (!omitNginxLocation) {
content.push(`location = /${index} {`);
}
assets.forEach((asset) => {
content.push(` http2_push ${asset};`);
});
if (!omitNginxLocation) {
content.push('}');
}
return content.join('\n');
}
/**
* get all assets
*/
getAssets(compilation, chunks) {
const compilationHash = compilation.hash;
// Use the configured public path or build a relative path
let publicPath = typeof compilation.options.output.publicPath !== 'undefined'
// If a hard coded public path exists use it
? compilation.mainTemplate.getPublicPath({ hash: compilationHash })
// If no public path was set get a relative url path
: path.relative(path.resolve(compilation.options.output.path, path.dirname(this.options.filename)), compilation.options.output.path)
.split(path.sep).join('/');
if (publicPath.length && publicPath.substr(-1, 1) !== '/') {
publicPath += '/';
}
const assets = chunks.reduce((prev, chunk) => {
const chunkFiles = [].concat(chunk.files).map((chunkFile) => publicPath + chunkFile);
return prev.concat(chunkFiles);
}, []);
// Duplicate assets can occur on occasion if more than one chunk requires the same css.
return _.uniq(assets);
}
/**
* Return all chunks from the compilation result which match the exclude and include filters
*/
filterChunks(chunks) {
return chunks.filter((chunk) => {
const chunkName = chunk.names[0];
// This chunk doesn't have a name. This script can't handled it.
if (chunkName === undefined) {
return false;
}
// Skip if the chunk should be lazy loaded
if (typeof chunk.isInitial === 'function') {
if (!chunk.isInitial()) {
return false;
}
} else if (!chunk.initial) {
return false;
}
// Add otherwise
return true;
});
}
}
module.exports = NginxPushWebpackPlugin;