1 | var _ = require('underscore'),
|
2 | path = require('path');
|
3 | const corePlugins = [
|
4 | 'mixin',
|
5 | 'styles-output', 'scripts-output', 'static-output',
|
6 | 'scope', 'router', 'template', 'inline-styles',
|
7 | 'coffee-script', 'stylus', 'handlebars',
|
8 | 'module-map', 'package-config', 'stylus-config',
|
9 | 'update-externals',
|
10 | 'server-scripts',
|
11 | 'inline-styles-resources', 'styles', 'scripts', 'static'
|
12 | ];
|
13 | var fileUtils = require("./fileUtil");
|
14 |
|
15 | var globalPlugins = {};
|
16 |
|
17 | exports.plugin = function(name, plugin) {
|
18 | globalPlugins[name] = plugin;
|
19 | plugin.id = name;
|
20 | };
|
21 |
|
22 | exports.plugin('module-map', require('./plugins/module-map'));
|
23 | exports.plugin('package-config', require('./plugins/package-config'));
|
24 | exports.plugin('router', require('./plugins/router'));
|
25 | exports.plugin('scope', require('./plugins/scope'));
|
26 | exports.plugin('stylus', require('./plugins/stylus'));
|
27 | exports.plugin('stylus-config', require('./plugins/stylus-config'));
|
28 | exports.plugin('coffee-script', require('./plugins/coffee-script'));
|
29 | exports.plugin('handlebars', require('./plugins/handlebars'));
|
30 | exports.plugin('inline-styles', require('./plugins/inline-styles'));
|
31 | exports.plugin('inline-styles-resources', require('./plugins/inline-styles-resources'));
|
32 | exports.plugin('mixin', require('./plugins/mixin'));
|
33 | exports.plugin('update-externals', require('./plugins/update-externals'));
|
34 | exports.plugin('template', require('./plugins/template'));
|
35 | exports.plugin('styles', require('./plugins/styles.js'));
|
36 | exports.plugin('server-scripts', require('./plugins/server-scripts.js'));
|
37 | exports.plugin('scripts', require('./plugins/scripts.js'));
|
38 | exports.plugin('static', require('./plugins/static.js'));
|
39 | exports.plugin('styles-output', require('./plugins/styles-output.js'));
|
40 | exports.plugin('scripts-output', require('./plugins/scripts-output.js'));
|
41 | exports.plugin('static-output', require('./plugins/static-output.js'));
|
42 |
|
43 | exports.create = function(options) {
|
44 | var plugins;
|
45 | var modes;
|
46 | var pluginModes;
|
47 | var modeAll;
|
48 |
|
49 | function runPlugins(context, methodName, complete, failOver, noMode) {
|
50 | var len = 0,
|
51 | pluginMode = pluginModes[context.mode] || [];
|
52 |
|
53 | return (function next(complete) {
|
54 |
|
55 | var plugin;
|
56 | while (plugin = plugins[len++]) {
|
57 |
|
58 | if (!noMode
|
59 | && (!context.mode || pluginMode.indexOf(plugin) < 0)
|
60 | && modeAll.indexOf(plugin) < 0) {
|
61 | continue;
|
62 | }
|
63 |
|
64 | var method = plugin[methodName];
|
65 | if (method) {
|
66 | if (complete) {
|
67 | process.nextTick(function() {
|
68 | method.call(plugin, context, next, complete);
|
69 | });
|
70 | return;
|
71 | } else {
|
72 | return method.call(plugin, context, next, complete);
|
73 | }
|
74 | }
|
75 | }
|
76 |
|
77 |
|
78 | if (complete) {
|
79 |
|
80 |
|
81 | process.nextTick(function() {
|
82 | complete(undefined, failOver && failOver());
|
83 | });
|
84 | } else {
|
85 |
|
86 | return failOver && failOver();
|
87 | }
|
88 | })(complete);
|
89 | }
|
90 |
|
91 | function registerPlugin(plugin) {
|
92 | var _plugin = globalPlugins[plugin] || plugin;
|
93 |
|
94 | var mode = _plugin.mode;
|
95 | if (mode) {
|
96 | if (_.isString(mode)) {
|
97 | mode = [mode];
|
98 | }
|
99 | _.each(mode, function(_mode) {
|
100 | if (mode === 'all') {
|
101 |
|
102 | modeAll.push(_plugin);
|
103 | } else {
|
104 | if (modes.indexOf(_mode) < 0) {
|
105 | modes.push(_mode);
|
106 | pluginModes[_mode] = [];
|
107 | }
|
108 | pluginModes[_mode].push(_plugin);
|
109 | }
|
110 | });
|
111 | } else {
|
112 | modeAll.push(_plugin);
|
113 | }
|
114 | plugins.push(_plugin);
|
115 | plugins.sort(function(a, b) {
|
116 | return (a.priority || 50) - (b.priority || 50);
|
117 | });
|
118 | }
|
119 |
|
120 | return {
|
121 | get: function(name) {
|
122 |
|
123 | var plugin = plugins.reduce(function(plugin, left) {
|
124 | return plugin.id === name ? plugin : left;
|
125 | });
|
126 |
|
127 |
|
128 | if (plugin.id === name) {
|
129 | return plugin;
|
130 | }
|
131 | },
|
132 | use: function(plugin) {
|
133 | if (plugin.path || (_.isString(plugin) && !globalPlugins[plugin])) {
|
134 | var pluginPath = plugin.path || plugin;
|
135 | var options = plugin.options;
|
136 | try {
|
137 | plugin = require(pluginPath);
|
138 | } catch (e) {
|
139 | plugin = require(path.resolve(process.cwd(), fileUtils.lookupPath()) + '/node_modules/' + pluginPath);
|
140 | }
|
141 | if ('function' === typeof plugin) {
|
142 | plugin = plugin(options);
|
143 | }
|
144 | }
|
145 | registerPlugin(plugin);
|
146 | },
|
147 |
|
148 | initialize: function(config) {
|
149 |
|
150 | plugins = [];
|
151 | modes = [];
|
152 | pluginModes = {};
|
153 | modeAll = [];
|
154 |
|
155 |
|
156 | if (!options.ignoreCorePlugins) {
|
157 | corePlugins.forEach(registerPlugin);
|
158 | }
|
159 |
|
160 | var self = this;
|
161 | function plugin(plugins) {
|
162 | if (plugins) {
|
163 | plugins.forEach(self.use, self);
|
164 | }
|
165 | }
|
166 |
|
167 |
|
168 | plugin(options.plugins);
|
169 |
|
170 |
|
171 | plugin(config.attributes.plugins);
|
172 | },
|
173 |
|
174 | loadMixin: function(context, complete) {
|
175 | runPlugins(context, 'loadMixin', complete, undefined, true);
|
176 | },
|
177 | loadConfig: function(context, complete) {
|
178 | runPlugins(context, 'loadConfig', complete, undefined, true);
|
179 | },
|
180 | outputConfigs: function(context, complete) {
|
181 | runPlugins(context, 'outputConfigs', complete, function() {
|
182 |
|
183 | return [ {} ];
|
184 | });
|
185 | },
|
186 | modeComplete: function(context, complete) {
|
187 | runPlugins(context, 'modeComplete', complete);
|
188 | },
|
189 | fileName: function(context, complete) {
|
190 | runPlugins(context, 'fileName', complete);
|
191 | },
|
192 |
|
193 | fileFilter: function(context) {
|
194 | return runPlugins(context, 'fileFilter');
|
195 | },
|
196 | moduleResources: function(context, complete) {
|
197 | runPlugins(context, 'moduleResources', complete, function() {
|
198 | var module = context.module;
|
199 | return (module[context.mode] || []).slice();
|
200 | });
|
201 | },
|
202 | resourceList: function(context, complete) {
|
203 | runPlugins(context, 'resourceList', complete, function() { return [context.resource]; });
|
204 | },
|
205 |
|
206 | file: function(context, complete) {
|
207 | runPlugins(context, 'file', complete);
|
208 | },
|
209 | module: function(context, complete) {
|
210 | runPlugins(context, 'module', complete);
|
211 | },
|
212 | resource: function(context, complete) {
|
213 | runPlugins(context, 'resource', complete, function() { return context.resource; });
|
214 | },
|
215 | modes: function() {
|
216 | return modes;
|
217 | }
|
218 | };
|
219 | };
|