forked from larsnystrom/webpack-php-manifest
-
Notifications
You must be signed in to change notification settings - Fork 2
/
Copy pathindex.js
124 lines (100 loc) · 3.88 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
var _ = require('lodash')
var path = require('path')
var url = require('url')
var fs = require('fs')
function PhpManifestPlugin (options) {
this.options = options || {}
}
const optionOrFallback = (optionValue, fallbackValue) => optionValue !== undefined ? optionValue : fallbackValue;
const withPrefix = (prefix) => (ext) => (assets, filepath) =>
Object.keys(assets)
.reduce((acc, name) => {
// Most of the time the properties of `assets` are just strings (the
// path to the created chunk) but sometimes (mostly for styles
// when using ExtractTextPlugin) a property can be an array containing
// several paths (i.e. ['styles.css', 'styles.js']).
let chunk = ((_.isArray(assets[name])) ? assets[name] : [assets[name]])
.filter(function (filename) {
return filename.endsWith(ext);
})
// Here we're assuming that you only want one of the
// paths in the array. Basically, this assertion should hold:
// .map((v, k, a) => {
// if (a.length !== 1) {
// throw new Error("Unexpected number of filenames for chunk.");
// }
// return v;
// })
.reduce(function (_, filename) {
return (!prefix)
? path.join(filepath, filename)
: url.resolve(prefix, path.join(filepath, filename));
}, undefined);
if (chunk) {
acc[name] = chunk;
}
return acc;
}, {});
PhpManifestPlugin.prototype.apply = function apply (compiler) {
var options = this.options;
// Get webpack options
var filepath = options.path ? options.path : '';
// Public path (like www), used when writing the file
var prefix = options.pathPrefix ? options.pathPrefix : '';
// By default, build the file with node fs. Can be included in webpack with an option.
var output = optionOrFallback(options.output, 'assets-manifest') + '.php';
var phpClassName = optionOrFallback(options.phpClassName, 'WebpackBuiltFiles');
var withExtension = withPrefix(prefix);
var getCssFiles = withExtension('.css');
var getJsFiles = function (assets, filepath) {
var files = withExtension('.js')(assets, filepath);
// Add webpack-dev-server js url
if (options.devServer) {
files['webpack-dev-server'] = url.resolve(prefix, 'webpack-dev-server.js');
}
return files;
}
var arrayToPhpStatic = function(list, varname) {
var out = '\n static $' + varname + ' = ['
_.forEach(list, function (item, name) {
out += "\n '" + name + "' => '" + item + "',";
});
out += '\n ];';
return out;
};
var phpClassComment = function(phpClassName) {
return '/** \n* Built by webpack-php-manifest \n* Class ' + phpClassName + '\n*/\n';
}
var objectToPhpClass = function(phpClassName, obj) {
// Create a header string for the generated file:
var out = '<?php\n'
+ phpClassComment(phpClassName)
+ 'class ' + phpClassName + ' {';
_.forEach(obj, function (list, name) {
out += arrayToPhpStatic(list, name);
});
out += '\n}\n';
return out;
};
var mkOutputDir = function(dir) {
// Make webpack output directory if it doesn't already exist
try {
fs.mkdirSync(dir);
} catch (err) {
// If it does exist, don't worry unless there's another error
if (err.code !== 'EEXIST') throw err;
}
}
compiler.hooks.afterEmit.tap("WepackPhpManifestPlugin", (compilation, done) => {
var stats = compilation.getStats().toJson();
var out = objectToPhpClass(phpClassName, {
jsFiles: getJsFiles(stats.assetsByChunkName, filepath),
cssFiles: getCssFiles(stats.assetsByChunkName, filepath),
});
// Write file using fs
// Build directory if it doesn't exist
mkOutputDir(path.resolve(compiler.options.output.path));
fs.writeFileSync(path.join(compiler.options.output.path, output), out, done);
});
};
module.exports = PhpManifestPlugin;