From 73e2b899d82828728bb5f167b029dd755f1ecc2a Mon Sep 17 00:00:00 2001 From: Chi Vinh Le Date: Mon, 3 Apr 2017 14:19:51 +0700 Subject: [PATCH] Use custom plugins loader --- client/coral-framework/helpers/plugins.js | 53 ++++------------ .../coral-framework/loaders/plugins-loader.js | 60 +++++++++++++++++++ package.json | 1 + webpack.config.js | 8 +++ yarn.lock | 6 ++ 5 files changed, 87 insertions(+), 41 deletions(-) create mode 100644 client/coral-framework/loaders/plugins-loader.js diff --git a/client/coral-framework/helpers/plugins.js b/client/coral-framework/helpers/plugins.js index 32b5e34d0..8a0d83386 100644 --- a/client/coral-framework/helpers/plugins.js +++ b/client/coral-framework/helpers/plugins.js @@ -1,57 +1,23 @@ -import {client as clientPlugins} from 'pluginsConfig'; import React from 'react'; -import mapValues from 'lodash/mapValues'; import values from 'lodash/values'; import flatten from 'lodash/flatten'; import merge from 'lodash/merge'; - -// Gather require context information of different parts of the plugins. -const contextMap = { - actions: require.context('plugins', true, /\.\/(.*)\/client\/actions.js$/), - reducers: require.context('plugins', true, /\.\/(.*)\/client\/reducer.js$/), - graph: require.context('plugins', true, /\.\/(.*)\/client\/(mutations|queries)\/index.js$/), - configs: require.context('plugins', true, /\.\/(.*)\/client\/config.json$/), - components: require.context('plugins', true, /\.\/(.*)\/client\/index.js$/), -}; - -const getPluginName = (key) => key.match(/\.\/(.*)\/client\/.*$/)[1]; -const isActivePlugin = (plugin) => clientPlugins.indexOf(plugin) > -1; - -/** - * Returns a callback that loads enabled modules of the context and - * returns an Array with {plugin, module} entries. Consecutive calls - * will return a memoized result. - */ -function createLoader(context) { - let loaded = null; - return () => { - if (!loaded) { - loaded = context - .keys() - .map(key => ({key, plugin: getPluginName(key)})) - .filter(info => isActivePlugin(info.plugin)) - .map(info => ({plugin: info.plugin, module: context(info.key)})); - } - return loaded; - }; -} - -const loaders = mapValues(contextMap, createLoader); +import plugins from 'pluginsConfig'; /** * Returns the config object of given plugin. */ function getConfig(plugin) { - return loaders.configs().filter(o => o.plugin === plugin)[0].module; + return plugins.configs.filter(o => o.plugin === plugin)[0].module(); } /** * Returns React Elements for given slot. */ export function getSlotElements(slot, props = {}) { - return loaders.components() + return plugins.components .map((o, i) => ({ - component: o.module, + component: o.module(), props: {...getConfig(o.plugin), ...props, key: i}, })) .filter(o => o.props.slot === slot) @@ -59,11 +25,16 @@ export function getSlotElements(slot, props = {}) { } // actions is a map of redux actions . -export const actions = merge(...loaders.actions().map(o => ({...o.module}))); +export const actions = merge(...plugins.actions.map(o => ({...o.module()}))); // reducers is a map of redux reducers. -export const reducers = merge(...loaders.reducers().map(o => ({...o.module}))); +export const reducers = merge(...plugins.reducers.map(o => ({...o.module()}))); // queriesAndMutators is an array of graphQL queries and mutators. -export const queriesAndMutators = flatten(loaders.graph().map(o => values(o.module))); +export const queriesAndMutators = flatten( + merge( + plugins.queries.map(o => values(o.module())), + plugins.mutators.map(o => values(o.module())), + ) +); diff --git a/client/coral-framework/loaders/plugins-loader.js b/client/coral-framework/loaders/plugins-loader.js new file mode 100644 index 000000000..3d63beee1 --- /dev/null +++ b/client/coral-framework/loaders/plugins-loader.js @@ -0,0 +1,60 @@ +const {stripIndent} = require('common-tags'); +const fs = require('fs'); +const path = require('path'); + +function moduleExists(loc) { + const fileExists = fs.existsSync(path.resolve(__dirname, loc)); + if (fileExists) { + return true; + } + + const hasExtension = /\..*$/.test(loc); + if (hasExtension) { + return false; + } + + // Find file with appended `.js` extension. + return fs.existsSync(path.resolve(__dirname, `${loc}.js`)); +} + +function addIfExists(list, plugin, resource) { + if (moduleExists(`../../../plugins/${plugin}/client/${resource}`)) { + list.push(`{module: () => require('plugins/${plugin}/client/${resource}'), plugin: '${plugin}'}`); + } +} + +module.exports = function(source) { + this.cacheable(); + const plugins = this.exec(source, this.resourcePath).client; + + const exports = { + configs: [], + actions: [], + reducers: [], + components: [], + queries: [], + mutators: [], + }; + + plugins.forEach(plugin => { + addIfExists(exports.components, plugin, 'index.js'); + addIfExists(exports.configs, plugin, 'config.json'); + addIfExists(exports.actions, plugin, 'actions'); + addIfExists(exports.reducers, plugin, 'reducer'); + addIfExists(exports.mutators, plugin, 'mutations'); + addIfExists(exports.queries, plugin, 'queries'); + }); + + let result = ''; + + Object.keys(exports).forEach(key => { + if (result) { result += '\n\n'; } + result += stripIndent` + module.exports.${key} = [ + ${exports[key].join(',')} + ]; + `; + }); + + return result; +}; diff --git a/package.json b/package.json index bb8694fb5..27e0c4f2a 100644 --- a/package.json +++ b/package.json @@ -114,6 +114,7 @@ "chai": "^3.5.0", "chai-as-promised": "^6.0.0", "chai-http": "^3.0.0", + "common-tags": "^1.4.0", "copy-webpack-plugin": "^4.0.0", "css-loader": "^0.27.3", "dialog-polyfill": "^0.4.4", diff --git a/webpack.config.js b/webpack.config.js index 59dc58b33..fe407656c 100644 --- a/webpack.config.js +++ b/webpack.config.js @@ -61,6 +61,11 @@ module.exports = { cacheDirectory: true } }, + { + loader: 'plugins-loader', + test: /\.json$/, + include: path.join(__dirname, 'plugins.json') + }, { loader: 'json-loader', test: /\.json$/, @@ -119,6 +124,9 @@ module.exports = { } }) ], + resolveLoader: { + modules: ['node_modules', path.resolve(__dirname, 'client/coral-framework/loaders')], + }, resolve: { alias: { plugins: path.resolve(__dirname, 'plugins/'), diff --git a/yarn.lock b/yarn.lock index bde912515..6bff77838 100644 --- a/yarn.lock +++ b/yarn.lock @@ -1758,6 +1758,12 @@ commander@~2.1.0: version "2.1.0" resolved "https://registry.yarnpkg.com/commander/-/commander-2.1.0.tgz#d121bbae860d9992a3d517ba96f56588e47c6781" +common-tags@^1.4.0: + version "1.4.0" + resolved "https://registry.yarnpkg.com/common-tags/-/common-tags-1.4.0.tgz#1187be4f3d4cf0c0427d43f74eef1f73501614c0" + dependencies: + babel-runtime "^6.18.0" + commondir@^1.0.1: version "1.0.1" resolved "https://registry.yarnpkg.com/commondir/-/commondir-1.0.1.tgz#ddd800da0c66127393cca5950ea968a3aaf1253b"