UNPKG

3.38 kBJavaScriptView Raw
1'use strict';
2
3var _loaderUtils = require('loader-utils');
4
5var _loaderUtils2 = _interopRequireDefault(_loaderUtils);
6
7function _interopRequireDefault(obj) { return obj && obj.__esModule ? obj : { default: obj }; }
8
9/**
10 * Every component is run through this loader, and the plugins and data specified by
11 * plugin developers are properly generated and emitted
12 *
13 * @param {String} source The raw, unchanged source code of the component
14 */
15module.exports = function pluginsLoader(source) {
16 // Flag this loader as cacheable to webpack
17 this.cacheable();
18 var query = _loaderUtils2.default.parseQuery(this.query);
19
20 var pluginPromises = [];
21 /**
22 * Define an api which can be called by the plugins in the
23 * carte-blanche-plugin-processing step
24 */
25 function renderToClient(pluginOptions) {
26 // Make the plugin name mandatory
27 if (!pluginOptions || !pluginOptions.name) {
28 throw new Error('Plugin name is mandatory');
29 }
30
31 // Load the frontend data and pass it to the frontend part of the plugin
32 pluginPromises.push(new Promise(function (resolve, reject) {
33 Promise.resolve(pluginOptions.frontendData).then(function (frontendData) {
34 return resolve({
35 name: pluginOptions.name,
36 frontendData: frontendData,
37 frontendPlugin: pluginOptions.frontendPlugin
38 });
39 }).catch(function (err) {
40 return reject(err);
41 });
42 }));
43 }
44
45 // Pass the source code of the component to the plugins
46 var pluginData = { source: source, dest: query.dest, commonsChunkFilename: query.commonsChunkFilename };
47
48 // Trigger events for carte-blanche child plugins
49 this._compilation.applyPlugins( // eslint-disable-line no-underscore-dangle
50 'carte-blanche-plugin-before-processing', pluginData, this);
51
52 this._compilation.applyPlugins( // eslint-disable-line no-underscore-dangle
53 'carte-blanche-plugin-processing', renderToClient, pluginData, this);
54
55 // The callback sends webpack the result of this loader. By using this.async(),
56 // we tell webpack that this loader will asynchronously return the result.
57 // See http://mxs.is/goognh for more information.
58 var callback = this.async();
59 // Wait for all plugins to be loaded
60 Promise.all(pluginPromises).then(function (plugins) {
61 // eslint-disable-line arrow-body-style
62 // Get the component data from each plugin
63 return plugins.map(function (plugin) {
64 // Execute the default export of the plugin frontend module
65 var frontendCode = 'function() {\n return (require(' + JSON.stringify(plugin.frontendPlugin) + '))\n .default.apply(\n this,\n Array.prototype.concat.apply([this.frontendData, pluginData], arguments)\n )\n }';
66 // Return the data of the plugin
67 return '{\n name: ' + JSON.stringify(plugin.name) + ',\n frontendData: ' + JSON.stringify(plugin.frontendData) + ',\n frontendPlugin: ' + (plugin.frontendPlugin ? frontendCode : '""') + '\n }';
68 });
69 })
70 // Send the data of all the plugins to the next loader via the callback
71 .then(function (pluginsData) {
72 callback(null, '\n var pluginData = ' + JSON.stringify(pluginData) + ';\n module.exports = [' + pluginsData.join(',') + '];\n ');
73 }).catch(function (err) {
74 return callback(err);
75 });
76};
\No newline at end of file