-
Notifications
You must be signed in to change notification settings - Fork 2
/
index.js
132 lines (111 loc) · 4.18 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
var Q = require('q');
var evaluate = require('eval');
var path = require('path');
/**
* This module waits for webpack to finish compiling, then it looks at a specified entry file (usually bundle.js)
* It expects the entry file to export a function, which has three arguments
*
* module.exports = function(path, props, callback) {}
*
* This plugin is constructed with an array of paths
* Each of these paths is first created, and then the compiled entry file is called upon
* to generate the html that is desired at the index.html file of each of those paths,
* the path is passed int othe function as the first parameter
*
* props is an object that is passed into the function, and defined in the
* constructor of the render plugin
*
* callback, a function to be called with the return html string
*/
function StaticRenderWebpackPlugin(bundlePath, outputRule, props, watchFiles) {
this.bundlePath = bundlePath;
/**
* Output paths is an array of strings or objects
* Strings are paths
* Objects are {path: PathString, output: PathString}
*/
this.outputRules = outputRule;
// Initial props is an object passed into the render function
this.props = props;
// An array of file paths to keep an eye on for changes
this.watchFiles = watchFiles;
}
StaticRenderWebpackPlugin.prototype.apply = function(compiler) {
var self = this;
compiler.plugin('after-compile', function(compiler, done) {
// Keep an eye on these file paths, and recompile in watch mode if they change
if (Array.isArray(self.watchFiles)) {
self.watchFiles.forEach(function(src) {
compiler.fileDependencies.push(src);
});
}
var sourceAsset = compiler.assets[self.bundlePath];
if (sourceAsset) {
try {
var source = sourceAsset.source(); // The string content of the bundle
// The source file is expected to return a module function by default
// This function takes two parameters, a local and a callback
// Using evaluate to retrieve the exported function from the source file
var render = evaluate(
/* source: */ source,
/* filename: */ self.bundlePath,
/* scope: */ undefined,
/* noGlobals: */ true);
var renderPromises = self.outputRules.map(function(outputRule) {
var renderPath = getInputPath(outputRule);
var outputFilePath = getOutputPath(outputRule);
return Q.Promise(function(resolve) {
/**
* Props is either an object or a function which returns a value
*/
var props = self.props;
if (typeof props == 'function') {
props = props();
}
render(renderPath, props, function(htmlString) {
resolve(htmlString);
});
}).then(function(result) {
// Save the new file created
compiler.assets[outputFilePath] = createAssetFromContents(result);
}).fail(function(error) {
// Catch errors here and print them in webpack's error handler, without stopping webpack-dev-server
compiler.errors.push(error);
});
});
Q.all(renderPromises).then(function() {
done();
});
} catch (err) {
// Catch errors here and print them in webpack's error handler, without stopping webpack-dev-server
compiler.errors.push(err);
done();
}
} else {
done();
}
});
}
var getInputPath = function(outputRule) {
if (typeof outputRule == 'string') return outputRule;
if (typeof outputRule == 'object') return outputRule.path;
}
var getOutputPath = function(outputRule) {
if (typeof outputRule == 'string') return path.join(outputRule, '/index.html');
if (typeof outputRule == 'object') return outputRule.output;
}
var createAssetFromContents = function(contents) {
return {
source: function() {
return contents;
},
size: function() {
return contents.length;
}
}
}
module.exports = StaticRenderWebpackPlugin;
/**
* This plugin was inspired by the static-site-generator-webpack-plugin by Mark Dalgleish
* License (MIT) https://github.com/markdalgleish/static-site-generator-webpack-plugin
*/