|
2 | 2 | module.exports = function(grunt) {
|
3 | 3 | var path = require('path');
|
4 | 4 | var os = require('os');
|
| 5 | + var through = require('through2'); |
| 6 | + var proxyquire = require('proxyquireify'); |
| 7 | + var versionify = require('browserify-versionify'); |
| 8 | + var derequire = require('derequire/plugin'); |
| 9 | + var collapser = require('bundle-collapser/plugin'); |
5 | 10 |
|
6 | 11 | var excludedPlugins = ['react-native'];
|
7 | 12 |
|
8 |
| - var plugins = grunt.file.expand('plugins/*.js').filter(function(plugin) { |
| 13 | + var plugins = grunt.option('plugins'); |
| 14 | + // Create plugin paths and verify they exist |
| 15 | + plugins = (plugins ? plugins.split(',') : []).map(function(plugin) { |
| 16 | + var p = 'plugins/' + plugin + '.js'; |
| 17 | + |
| 18 | + if (!grunt.file.exists(p)) |
| 19 | + throw new Error("Plugin '" + plugin + "' not found in plugins directory."); |
| 20 | + |
| 21 | + return p; |
| 22 | + }); |
| 23 | + |
| 24 | + // custom browserify transformer to re-write plugins to |
| 25 | + // self-register with Raven via addPlugin |
| 26 | + function AddPluginBrowserifyTransformer() { |
| 27 | + return function(file) { |
| 28 | + return through(function(buf, enc, next) { |
| 29 | + buf = buf.toString('utf8'); |
| 30 | + if (/plugins/.test(file)) { |
| 31 | + buf += "\nrequire('../src/singleton').addPlugin(module.exports);"; |
| 32 | + } |
| 33 | + this.push(buf); |
| 34 | + next(); |
| 35 | + }); |
| 36 | + }; |
| 37 | + } |
| 38 | + |
| 39 | + // Taken from http://dzone.com/snippets/calculate-all-combinations |
| 40 | + var combine = function(a) { |
| 41 | + var fn = function(n, src, got, all) { |
| 42 | + if (n === 0) { |
| 43 | + all.push(got); |
| 44 | + return; |
| 45 | + } |
| 46 | + |
| 47 | + for (var j = 0; j < src.length; j++) { |
| 48 | + fn(n - 1, src.slice(j + 1), got.concat([src[j]]), all); |
| 49 | + } |
| 50 | + }; |
| 51 | + |
| 52 | + var excluded = excludedPlugins.map(function(plugin) { |
| 53 | + return 'plugins/' + plugin + '.js'; |
| 54 | + }); |
| 55 | + |
| 56 | + // Remove the plugins that we don't want to build |
| 57 | + a = a.filter(function(n) { |
| 58 | + return excluded.indexOf(n) === -1; |
| 59 | + }); |
| 60 | + |
| 61 | + var all = [a]; |
| 62 | + |
| 63 | + for (var i = 0; i < a.length; i++) { |
| 64 | + fn(i, a, [], all); |
| 65 | + } |
| 66 | + |
| 67 | + return all; |
| 68 | + }; |
| 69 | + |
| 70 | + var plugins = grunt.file.expand('plugins/*.js'); |
| 71 | + |
| 72 | + var cleanedPlugins = plugins.filter(function(plugin) { |
9 | 73 | var pluginName = path.basename(plugin, '.js');
|
10 | 74 |
|
11 | 75 | return excludedPlugins.indexOf(pluginName) === -1;
|
12 | 76 | });
|
13 | 77 |
|
14 |
| - // These files are generated with the 'generate:plugins-combined' npm script |
15 |
| - var pluginCombinations = grunt.file.expand('plugins/combinations/*.js'); |
| 78 | + var pluginSingleFiles = cleanedPlugins.map(function(plugin) { |
| 79 | + var filename = path.basename(plugin); |
16 | 80 |
|
17 |
| - var tests = grunt.file.expand('test/**/*.test.js'); |
| 81 | + var file = {}; |
| 82 | + file.src = plugin; |
| 83 | + file.dest = path.join('build', 'plugins', filename); |
18 | 84 |
|
19 |
| - var rollupConfig = { |
20 |
| - core: { |
21 |
| - options: [ |
22 |
| - { |
23 |
| - input: { |
24 |
| - input: 'src/singleton.js' |
25 |
| - }, |
26 |
| - output: { |
27 |
| - file: 'build/raven.js', |
28 |
| - name: 'Raven', |
29 |
| - banner: grunt.file.read('template/_copyright.js') |
30 |
| - } |
31 |
| - } |
32 |
| - ] |
| 85 | + return file; |
| 86 | + }); |
| 87 | + |
| 88 | + var pluginCombinations = combine(plugins); |
| 89 | + var pluginConcatFiles = pluginCombinations.reduce(function(dict, comb) { |
| 90 | + var key = comb.map(function(plugin) { |
| 91 | + return path.basename(plugin, '.js'); |
| 92 | + }); |
| 93 | + key.sort(); |
| 94 | + |
| 95 | + var dest = path.join('build/', key.join(','), '/raven.js'); |
| 96 | + dict[dest] = ['src/singleton.js'].concat(comb); |
| 97 | + |
| 98 | + return dict; |
| 99 | + }, {}); |
| 100 | + |
| 101 | + var browserifyConfig = { |
| 102 | + options: { |
| 103 | + banner: grunt.file.read('template/_copyright.js'), |
| 104 | + browserifyOptions: { |
| 105 | + standalone: 'Raven' // umd |
| 106 | + }, |
| 107 | + transform: [versionify], |
| 108 | + plugin: [derequire, collapser] |
33 | 109 | },
|
34 |
| - plugins: { |
35 |
| - options: [] |
| 110 | + core: { |
| 111 | + src: 'src/singleton.js', |
| 112 | + dest: 'build/raven.js' |
36 | 113 | },
|
37 |
| - pluginCombinations: { |
38 |
| - options: [] |
| 114 | + 'plugins-combined': { |
| 115 | + files: pluginConcatFiles, |
| 116 | + options: { |
| 117 | + transform: [[versionify], [new AddPluginBrowserifyTransformer()]] |
| 118 | + } |
39 | 119 | },
|
40 |
| - tests: { |
41 |
| - options: [] |
| 120 | + test: { |
| 121 | + src: 'test/**/*.test.js', |
| 122 | + dest: 'build/raven.test.js', |
| 123 | + options: { |
| 124 | + browserifyOptions: { |
| 125 | + debug: false // source maps |
| 126 | + }, |
| 127 | + ignore: ['react-native'], |
| 128 | + plugin: [proxyquire.plugin] |
| 129 | + } |
42 | 130 | }
|
43 | 131 | };
|
44 | 132 |
|
45 |
| - // Create a dedicated entry in rollup config for each individual |
46 |
| - // plugin (each needs a unique `standalone` config) |
47 |
| - plugins.forEach(function(plugin) { |
48 |
| - var name = plugin |
| 133 | + // Create a dedicated entry in browserify config for |
| 134 | + // each individual plugin (each needs a unique `standalone` |
| 135 | + // config) |
| 136 | + var browserifyPluginTaskNames = []; |
| 137 | + pluginSingleFiles.forEach(function(item) { |
| 138 | + var name = item.src |
49 | 139 | .replace(/.*\//, '') // everything before slash
|
50 | 140 | .replace('.js', ''); // extension
|
51 | 141 | var capsName = name.charAt(0).toUpperCase() + name.slice(1);
|
52 | 142 | var config = {
|
53 |
| - input: { |
54 |
| - input: plugin |
55 |
| - }, |
56 |
| - output: { |
57 |
| - file: path.join('build', 'plugins', path.basename(plugin)), |
58 |
| - name: 'Raven.Plugins.' + capsName, |
59 |
| - banner: grunt.file.read('template/_copyright.js') |
60 |
| - } |
61 |
| - }; |
62 |
| - |
63 |
| - rollupConfig.plugins.options.push(config); |
64 |
| - }); |
65 |
| - |
66 |
| - // Create a dedicated entry in rollup config for each individual plugin combination |
67 |
| - pluginCombinations.forEach(function(pluginCombination) { |
68 |
| - var config = { |
69 |
| - input: { |
70 |
| - input: pluginCombination |
71 |
| - }, |
72 |
| - output: { |
73 |
| - file: path.join('build', path.basename(pluginCombination, '.js'), 'raven.js'), |
74 |
| - name: 'Raven', |
75 |
| - banner: grunt.file.read('template/_copyright.js') |
76 |
| - } |
77 |
| - }; |
78 |
| - |
79 |
| - rollupConfig.pluginCombinations.options.push(config); |
80 |
| - }); |
81 |
| - |
82 |
| - // Transpile all test scripts |
83 |
| - tests.forEach(function(test) { |
84 |
| - var config = { |
85 |
| - input: { |
86 |
| - input: test |
87 |
| - }, |
88 |
| - output: { |
89 |
| - file: path.join('build', path.basename(test)), |
90 |
| - name: path.basename(test, '.js') |
| 143 | + src: item.src, |
| 144 | + dest: item.dest, |
| 145 | + options: { |
| 146 | + browserifyOptions: { |
| 147 | + // e.g. Raven.Plugins.Angular |
| 148 | + standalone: 'Raven.Plugins.' + capsName |
| 149 | + } |
91 | 150 | }
|
92 | 151 | };
|
93 |
| - |
94 |
| - rollupConfig.tests.options.push(config); |
| 152 | + browserifyConfig[name] = config; |
| 153 | + browserifyPluginTaskNames.push('browserify:' + name); |
95 | 154 | });
|
96 | 155 |
|
97 | 156 | var awsConfigPath = path.join(os.homedir(), '.aws', 'raven-js.json');
|
98 | 157 | var gruntConfig = {
|
99 | 158 | pkg: grunt.file.readJSON('package.json'),
|
100 | 159 | aws: grunt.file.exists(awsConfigPath) ? grunt.file.readJSON(awsConfigPath) : {},
|
101 | 160 |
|
102 |
| - clean: ['build', 'plugins/combinations'], |
| 161 | + clean: ['build'], |
103 | 162 |
|
104 |
| - rollup: rollupConfig, |
| 163 | + browserify: browserifyConfig, |
105 | 164 |
|
106 | 165 | uglify: {
|
107 | 166 | options: {
|
@@ -218,30 +277,6 @@ module.exports = function(grunt) {
|
218 | 277 | grunt.initConfig(gruntConfig);
|
219 | 278 |
|
220 | 279 | // Custom Grunt tasks
|
221 |
| - grunt.registerMultiTask('rollup', 'Create the bundles', function() { |
222 |
| - var build = require('./scripts/build'); |
223 |
| - var options = this.options(); |
224 |
| - var done = this.async(); |
225 |
| - |
226 |
| - var promises = Object.keys(options).map(function(key) { |
227 |
| - return build(options[key].input, options[key].output); |
228 |
| - }); |
229 |
| - |
230 |
| - Promise.all(promises) |
231 |
| - .then(function() { |
232 |
| - done(); |
233 |
| - }) |
234 |
| - ['catch'](function(error) { |
235 |
| - grunt.fail.warn(error); |
236 |
| - }); |
237 |
| - }); |
238 |
| - |
239 |
| - grunt.registerTask('generate-plugin-combinations', function() { |
240 |
| - var dest = './plugins/combinations'; |
241 |
| - grunt.file.mkdir(dest); |
242 |
| - require('./scripts/generate-plugin-combinations')(plugins, dest); |
243 |
| - }); |
244 |
| - |
245 | 280 | grunt.registerTask('version', function() {
|
246 | 281 | var pkg = grunt.config.get('pkg');
|
247 | 282 |
|
@@ -280,28 +315,34 @@ module.exports = function(grunt) {
|
280 | 315 | grunt.loadNpmTasks('grunt-contrib-copy');
|
281 | 316 |
|
282 | 317 | // 3rd party Grunt tasks
|
| 318 | + grunt.loadNpmTasks('grunt-browserify'); |
283 | 319 | grunt.loadNpmTasks('grunt-release');
|
284 | 320 | grunt.loadNpmTasks('grunt-s3');
|
285 | 321 | grunt.loadNpmTasks('grunt-gitinfo');
|
286 | 322 | grunt.loadNpmTasks('grunt-sri');
|
287 | 323 |
|
288 | 324 | // Build tasks
|
289 |
| - grunt.registerTask('_prep', ['gitinfo', 'version']); |
290 |
| - grunt.registerTask('build.test', ['_prep', 'rollup:core', 'rollup:tests']); |
291 |
| - grunt.registerTask('build.core', ['_prep', 'rollup:core']); |
292 |
| - grunt.registerTask('build.plugins', [ |
| 325 | + grunt.registerTask('_prep', ['clean', 'gitinfo', 'version']); |
| 326 | + grunt.registerTask( |
| 327 | + 'browserify.core', |
| 328 | + ['_prep', 'browserify:core'].concat(browserifyPluginTaskNames) |
| 329 | + ); |
| 330 | + grunt.registerTask('browserify.plugins-combined', [ |
293 | 331 | '_prep',
|
294 |
| - 'generate-plugin-combinations', |
295 |
| - 'rollup:plugins', |
296 |
| - 'rollup:pluginCombinations', |
| 332 | + 'browserify:plugins-combined' |
| 333 | + ]); |
| 334 | + grunt.registerTask('build.test', ['_prep', 'browserify.core', 'browserify:test']); |
| 335 | + grunt.registerTask('build.core', ['browserify.core', 'uglify', 'sri:dist']); |
| 336 | + grunt.registerTask('build.plugins-combined', [ |
| 337 | + 'browserify.plugins-combined', |
| 338 | + 'uglify', |
| 339 | + 'sri:dist', |
297 | 340 | 'sri:build'
|
298 | 341 | ]);
|
299 |
| - grunt.registerTask('build', ['build.core', 'build.plugins', 'uglify']); |
300 |
| - |
301 |
| - grunt.registerTask('dist', ['clean', 'build', 'copy:dist', 'sri:dist']); |
| 342 | + grunt.registerTask('build', ['build.plugins-combined']); |
| 343 | + grunt.registerTask('dist', ['build.core', 'copy:dist']); |
302 | 344 |
|
303 |
| - // Test tasks |
304 |
| - grunt.registerTask('test:ci', ['config:ci', 'build:test']); |
| 345 | + grunt.registerTask('test:ci', ['config:ci', 'build.test']); |
305 | 346 |
|
306 | 347 | // Webserver tasks
|
307 | 348 | grunt.registerTask('run:test', ['build.test', 'connect:test']);
|
|
0 commit comments