Skip to content

Commit

Permalink
make config optional
Browse files Browse the repository at this point in the history
  • Loading branch information
bdefore committed Jan 5, 2016
1 parent 25f6136 commit aac5e45
Show file tree
Hide file tree
Showing 10 changed files with 139 additions and 125 deletions.
4 changes: 3 additions & 1 deletion bin/build_es6.js
Original file line number Diff line number Diff line change
Expand Up @@ -4,9 +4,11 @@ process.env.NODE_ENV = 'production';

const fs = require('fs');
const webpack = require('webpack');
const webpackConfig = require('./merge-configs');
const userConfig = require('./user-config');
const config = require('./merge-configs')(userConfig);
const buildStats = false;
const outputStatsPath = './webpack-stats.json';
const webpackConfig = config.webpack.config;

console.log('\nBuilding webpack bundle...');
webpack(webpackConfig, (err, stats) => {
Expand Down
2 changes: 1 addition & 1 deletion bin/merge-babel-config.js
Original file line number Diff line number Diff line change
Expand Up @@ -42,7 +42,7 @@ module.exports = (userBabelConfig, verbose) => {
colors: true
};

console.log('Babel config:');
console.log('\nBabel config:');
console.log(util.inspect(babelConfig, utilOptions));
}

Expand Down
186 changes: 96 additions & 90 deletions bin/merge-configs.js
Original file line number Diff line number Diff line change
@@ -1,4 +1,5 @@
#!/usr/bin/env node
const fs = require('fs');
const path = require('path');
const util = require('util');

Expand All @@ -14,100 +15,105 @@ const WebpackErrorNotificationPlugin = require('webpack-error-notification');

const isProduction = process.env.NODE_ENV === 'production';

// gather user config
const userConfigPath = 'config/universal-redux.config.js';
const userConfig = require(path.resolve(userConfigPath));

// derive root and sourceDir, alowing for absolute, relative, or not provided
// TODO: create helper for deriving root, also in src/server.js
const root = userConfig.root ? userConfig.root[0] === '/' ? userConfig.root : path.resolve(__dirname, '../..', userConfig.root) : path.resolve(__dirname, '../../..');
const sourceDir = userConfig.sourceDir ? userConfig.sourceDir[0] === '/' ? userConfig.sourceDir : path.resolve(root, userConfig.sourceDir) : path.resolve(root, './src');

// merge with base config
const universalReduxConfig = lodash.merge(require('../config/universal-redux.config.js')(root), userConfig);

// merge with base webpack config
const baseConfig = isProduction ? baseProdConfig : baseDevConfig;
const combinedWebpackConfig = mergeWebpack(baseConfig, universalReduxConfig.webpack.config);
combinedWebpackConfig.context = root;
combinedWebpackConfig.resolve.root = sourceDir;

// derive webpack output destination from staticPath
combinedWebpackConfig.output.path = universalReduxConfig.server.staticPath + '/dist';

// add babel for js transpiling
const babelConfig = mergeBabel(universalReduxConfig.babelConfig, universalReduxConfig.verbose);
combinedWebpackConfig.module.loaders.unshift({ test: /\.jsx?$/, exclude: /node_modules/, loaders: babelConfig });

// gather tools config
const combinedToolsConfig = baseToolsConfig;
if (universalReduxConfig.toolsConfigPath) {
const userToolsConfig = require(path.resolve(universalReduxConfig.toolsConfigPath));
combinedToolsConfig = lodash.merge(baseToolsConfig, userToolsConfig);
}
combinedToolsConfig.webpack_assets_file_path = 'node_modules/universal-redux/webpack-assets.json';

// add tools settings to combined weback config
const WebpackIsomorphicToolsPlugin = require('webpack-isomorphic-tools/plugin');
const toolsPlugin = new WebpackIsomorphicToolsPlugin(combinedToolsConfig);

combinedWebpackConfig.module.loaders.push({ test: toolsPlugin.regular_expression('images'), loader: 'url-loader?limit=10240' });
combinedWebpackConfig.plugins.push(isProduction ? toolsPlugin : toolsPlugin.development());

// turn on linting per webpack build, unless directed not to
if (universalReduxConfig.lint && universalReduxConfig.lint.enabled !== false && !isProduction) {
combinedWebpackConfig.module.loaders[0].loaders.push('eslint-loader');
const lintConfigPath = universalReduxConfig.lint.config || path.resolve(__dirname, '../.eslintrc');
combinedWebpackConfig.eslint = {
configFile: lintConfigPath
function inspect(obj) {
const utilOptions = {
depth: 12,
colors: true
};
}

// turn on desktop notifications if user elects to
if (universalReduxConfig.notifications === true && !isProduction) {
combinedWebpackConfig.plugins.push(new WebpackErrorNotificationPlugin());
}

// add default settings that are used by server via process.env
const definitions = {
__LOGGER__: false,
__DEVTOOLS__: !isProduction,
__DEVELOPMENT__: !isProduction,
__REDUCER_INDEX__: universalReduxConfig.redux.reducers // only used for hot reloader in src/redux/create.js. may be able to remove?
};

// override with user settings
lodash.each(universalReduxConfig.globals, (value, key) => { definitions[key] = JSON.stringify(value); });
combinedWebpackConfig.plugins.push(new webpack.DefinePlugin(definitions));

// add routes and reducer aliases so that client has access to them
combinedWebpackConfig.resolve.alias = combinedWebpackConfig.resolve.alias || {};
combinedWebpackConfig.resolve.alias.routes = universalReduxConfig.routes;
combinedWebpackConfig.resolve.alias.reducers = universalReduxConfig.redux.reducers;
if (universalReduxConfig.redux.middleware) {
combinedWebpackConfig.resolve.alias.middleware = universalReduxConfig.redux.middleware;
} else {
combinedWebpackConfig.resolve.alias.middleware = path.resolve(__dirname, '../lib/redux/middleware/index.js');
console.log(util.inspect(obj, utilOptions));
}

// add project level vendor libs
if (universalReduxConfig.webpack && universalReduxConfig.webpack.vendorLibraries && isProduction) {
lodash.each(universalReduxConfig.webpack.vendorLibraries, (lib) => {
combinedWebpackConfig.entry.vendor.push(lib);
});
}

// output configuration files if user wants verbosity
if (universalReduxConfig.verbose) {
const utilOptions = {
depth: 6,
colors: true
module.exports = (userConfig) => {

// derive root and sourceDir, alowing for absolute, relative, or not provided
// TODO: create helper for deriving root, also in src/server.js
const root = userConfig.root ? userConfig.root[0] === '/' ? userConfig.root : path.resolve(__dirname, '../..', userConfig.root) : path.resolve(__dirname, '../../..');
const sourceDir = userConfig.sourceDir ? userConfig.sourceDir[0] === '/' ? userConfig.sourceDir : path.resolve(root, userConfig.sourceDir) : path.resolve(root, './src');

// merge with base config
const universalReduxConfig = lodash.merge(require('../config/universal-redux.config.js')(root, sourceDir), userConfig);

// merge with base webpack config
const baseConfig = isProduction ? baseProdConfig : baseDevConfig;
const combinedWebpackConfig = mergeWebpack(baseConfig, universalReduxConfig.webpack.config);
combinedWebpackConfig.context = root;
combinedWebpackConfig.resolve.root = sourceDir;

// derive webpack output destination from staticPath
combinedWebpackConfig.output.path = universalReduxConfig.server.staticPath + '/dist';

// add babel for js transpiling
const babelConfig = mergeBabel(universalReduxConfig.babelConfig, universalReduxConfig.verbose);
combinedWebpackConfig.module.loaders.unshift({ test: /\.jsx?$/, exclude: /node_modules/, loaders: babelConfig });

// gather tools config
const combinedToolsConfig = baseToolsConfig;
if (universalReduxConfig.toolsConfigPath) {
const userToolsConfig = require(path.resolve(universalReduxConfig.toolsConfigPath));
combinedToolsConfig = lodash.merge(baseToolsConfig, userToolsConfig);
}
combinedToolsConfig.webpack_assets_file_path = 'node_modules/universal-redux/webpack-assets.json';

// add tools settings to combined weback config
const WebpackIsomorphicToolsPlugin = require('webpack-isomorphic-tools/plugin');
const toolsPlugin = new WebpackIsomorphicToolsPlugin(combinedToolsConfig);

combinedWebpackConfig.module.loaders.push({ test: toolsPlugin.regular_expression('images'), loader: 'url-loader?limit=10240' });
combinedWebpackConfig.plugins.push(isProduction ? toolsPlugin : toolsPlugin.development());

// turn on linting per webpack build, unless directed not to
if (universalReduxConfig.lint && universalReduxConfig.lint.enabled !== false && !isProduction) {
combinedWebpackConfig.module.loaders[0].loaders.push('eslint-loader');
const lintConfigPath = universalReduxConfig.lint.config || path.resolve(__dirname, '../.eslintrc');
combinedWebpackConfig.eslint = {
configFile: lintConfigPath
};
}

// turn on desktop notifications if user elects to
if (universalReduxConfig.notifications === true && !isProduction) {
combinedWebpackConfig.plugins.push(new WebpackErrorNotificationPlugin());
}

// add default settings that are used by server via process.env
const definitions = {
__LOGGER__: false,
__DEVTOOLS__: !isProduction,
__DEVELOPMENT__: !isProduction,
__REDUCER_INDEX__: universalReduxConfig.redux.reducers // only used for hot reloader in src/redux/create.js. may be able to remove?
};

console.log('Webpack config:');
console.log(util.inspect(combinedWebpackConfig, utilOptions));
console.log('\nIsomorphic tools config:');
console.log(util.inspect(combinedToolsConfig, utilOptions));
// override with user settings
lodash.each(universalReduxConfig.globals, (value, key) => { definitions[key] = JSON.stringify(value); });
combinedWebpackConfig.plugins.push(new webpack.DefinePlugin(definitions));

// add routes and reducer aliases so that client has access to them
combinedWebpackConfig.resolve.alias = combinedWebpackConfig.resolve.alias || {};
combinedWebpackConfig.resolve.alias.routes = universalReduxConfig.routes;
combinedWebpackConfig.resolve.alias.reducers = universalReduxConfig.redux.reducers;
if (universalReduxConfig.redux.middleware) {
combinedWebpackConfig.resolve.alias.middleware = universalReduxConfig.redux.middleware;
} else {
combinedWebpackConfig.resolve.alias.middleware = path.resolve(__dirname, '../lib/redux/middleware/index.js');
}

// add project level vendor libs
if (universalReduxConfig.webpack.vendorLibraries && isProduction) {
lodash.each(universalReduxConfig.webpack.vendorLibraries, (lib) => {
combinedWebpackConfig.entry.vendor.push(lib);
});
}

// output configuration files if user wants verbosity
if (universalReduxConfig.verbose) {
console.log('\nWebpack config:');
inspect(combinedWebpackConfig);
console.log('\nIsomorphic tools config:');
inspect(combinedToolsConfig);
}

universalReduxConfig.webpack.config = combinedWebpackConfig;

return universalReduxConfig;
}

module.exports = combinedWebpackConfig;
7 changes: 6 additions & 1 deletion bin/server_es6.js
Original file line number Diff line number Diff line change
@@ -1,7 +1,12 @@
#!/usr/bin/env node
const path = require('path');
const renderer = require('../lib/server').default;
const config = require(path.resolve('config/universal-redux.config.js'));
const userConfig = require('./user-config');

// since typically the dev server is logging this out too
userConfig.verbose = false;

const config = require('./merge-configs')(userConfig);

// method 1
renderer.setup(config);
Expand Down
10 changes: 10 additions & 0 deletions bin/user-config.js
Original file line number Diff line number Diff line change
@@ -0,0 +1,10 @@
const path = require('path');

try {
const config = require(path.resolve('config/universal-redux.config.js'));
} catch (err) {
console.error('No configuration file provided, using defaults.');
return {};
}

module.exports = config;
10 changes: 6 additions & 4 deletions bin/webpack-dev-server_es6.js
Original file line number Diff line number Diff line change
Expand Up @@ -2,13 +2,15 @@
const path = require('path');
const Express = require('express');
const webpack = require('webpack');
const webpackConfig = require('./merge-configs');
const userConfig = require(path.resolve('config/universal-redux.config.js'));
const userConfig = require('./user-config');

const config = require('./merge-configs')(userConfig);

const webpackConfig = config.webpack.config;
const compiler = webpack(webpackConfig);

const host = userConfig.server.host || 'localhost';
const port = parseInt(userConfig.server.port, 10) + 1 || 3001;
const host = config.server.host || 'localhost';
const port = parseInt(config.server.port, 10) + 1 || 3001;
const serverOptions = {
contentBase: 'http://' + host + ':' + port,
quiet: true,
Expand Down
10 changes: 5 additions & 5 deletions config/universal-redux.config.js
Original file line number Diff line number Diff line change
@@ -1,4 +1,4 @@
module.exports = (projectRoot) => {
module.exports = (projectRoot, sourceRoot) => {

const isProduction = process.env.NODE_ENV === 'production';

Expand Down Expand Up @@ -114,7 +114,7 @@ module.exports = (projectRoot) => {
/*
// The react-router Routes file. Required. Will be added to Webpack aliases.
*/
routes: 'src/routes.js',
routes: sourceRoot + '/routes.js',

redux: {
/*
Expand All @@ -123,15 +123,15 @@ module.exports = (projectRoot) => {
//
// Expects: String
*/
reducers: 'src/redux/modules/index.js',
reducers: sourceRoot + '/redux/modules/index.js',

/*
// A path to an index of middleware functions. On the serverside, these will
// be called with the Express request and response. Optional.
//
// Expects: String
*/
// middleware: 'src/redux/middleware/index.js',
// middleware: sourceRoot + '/redux/middleware/index.js',
},

/*
Expand All @@ -141,7 +141,7 @@ module.exports = (projectRoot) => {
//
// Expects: String
*/
// htmlShell: 'src/containers/HtmlShell/HtmlShell.js',
// htmlShell: sourceRoot + '/containers/HtmlShell/HtmlShell.js',

/*
// Customizations for Webpack configuration. Optional.
Expand Down
10 changes: 1 addition & 9 deletions src/client.js
Original file line number Diff line number Diff line change
Expand Up @@ -32,16 +32,8 @@ const history = useScroll(createHistory)();

syncReduxAndRouter(history, store);

function createElement(Component, propz) {
if (Component.fetchData) {
Component.fetchData(store.getState, store.dispatch,
propz.location, propz.params);
}
return React.createElement(Component, propz);
}

const component = (
<Router createElement={createElement} history={history}>
<Router history={history}>
{getRoutes(store)}
</Router>
);
Expand Down
2 changes: 0 additions & 2 deletions src/redux/middleware/index.js

This file was deleted.

23 changes: 11 additions & 12 deletions src/server.js
Original file line number Diff line number Diff line change
Expand Up @@ -15,6 +15,7 @@ import WebpackIsomorphicTools from 'webpack-isomorphic-tools';
import createStore from './redux/create';
import Html from './containers/HtmlShell/HtmlShell';
import getStatusFromRoutes from './helpers/getStatusFromRoutes';
import mergeConfigs from '../bin/merge-configs';

let app;
let hasSetup = false;
Expand All @@ -33,8 +34,7 @@ global.__DEVELOPMENT__ = process.env.NODE_ENV !== 'production';
function setupTools() {
toolsConfig.webpack_assets_file_path = 'node_modules/universal-redux/webpack-assets.json';

// TODO: create helper for deriving root, also in merge-configs.js
const rootDir = config.root ? config.root[0] === '/' ? config.root : path.resolve(__dirname, '../..', config.root) : path.resolve(__dirname, '../../..');
const rootDir = config.webpack.config.context;

tools = new WebpackIsomorphicTools(toolsConfig);
tools
Expand Down Expand Up @@ -148,20 +148,19 @@ function validateConfig() {

export default class Renderer {

static configure(userConfig, userToolsConfig) {
static configure(providedConfig, userToolsConfig) {
if (!hasSetup) {
Renderer.app();
}

// TODO: create helper for deriving root, also in merge-configs.js
const root = userConfig.root ? userConfig.root[0] === '/' ? userConfig.root : path.resolve(__dirname, '../..', userConfig.root) : path.resolve(__dirname, '../../..');
const baseConfig = require('../config/universal-redux.config.js')(root);
// since typically the dev server is logging this out too
providedConfig.verbose = false;

config = merge(baseConfig, userConfig);
config = mergeConfigs(providedConfig);

// add user defined globals for serverside access
each(userConfig.globals, (value, key) => { global[key] = JSON.stringify(value); });
global.__REDUCER_INDEX__ = userConfig.redux.reducers;
each(config.globals, (value, key) => { global[key] = JSON.stringify(value); });
global.__REDUCER_INDEX__ = config.redux.reducers;

if (userToolsConfig) {
toolsConfig = userToolsConfig;
Expand All @@ -187,9 +186,9 @@ export default class Renderer {
return app;
}

static setup(userConfig, userToolsConfig) {
if (userConfig) {
const errors = Renderer.configure(userConfig, userToolsConfig);
static setup(providedConfig, userToolsConfig) {
if (providedConfig) {
const errors = Renderer.configure(providedConfig, userToolsConfig);
if (errors.length > 0) {
return;
}
Expand Down

0 comments on commit aac5e45

Please sign in to comment.