From c58e6f62395569e3dc33c7e3c670b15b801f8a90 Mon Sep 17 00:00:00 2001 From: Art Lowel Date: Tue, 4 Jun 2019 17:12:12 +0200 Subject: [PATCH] use config to determine active theme --- config/environment.default.js | 4 + package.json | 10 +- .../resolve-absolute-scss-imports.js | 2 +- scripts/sync-build-dir.js | 22 +++ webpack/run-webpack.js => scripts/webpack.js | 0 src/config.js | 150 ++++++++++++++++++ webpack/helpers.js | 47 +++++- webpack/webpack.common.js | 1 - 8 files changed, 224 insertions(+), 12 deletions(-) rename webpack/run-replace.js => scripts/resolve-absolute-scss-imports.js (92%) create mode 100644 scripts/sync-build-dir.js rename webpack/run-webpack.js => scripts/webpack.js (100%) create mode 100644 src/config.js diff --git a/config/environment.default.js b/config/environment.default.js index 804d80b0f2..c3c6e0f386 100644 --- a/config/environment.default.js +++ b/config/environment.default.js @@ -155,5 +155,9 @@ module.exports = { edit: { undoTimeout: 10000 // 10 seconds } + }, + theme: { + name: 'default', + cssClass: 'default', } }; diff --git a/package.json b/package.json index 05bbd026fe..91fa430108 100644 --- a/package.json +++ b/package.json @@ -24,9 +24,9 @@ "prebuild": "yarn run clean:bld && yarn run clean:dist", "prebuild:aot": "yarn run prebuild", "prebuild:prod": "yarn run prebuild", - "build": "node ./webpack/run-webpack.js --progress --mode development", - "build:aot": "yarn run syncbuilddir && node ./webpack/run-replace.js && DSPACE_BUILD_DIR=./build node ./webpack/run-webpack.js --env.aot --env.server --mode development && DSPACE_BUILD_DIR=./build node ./webpack/run-webpack.js --env.aot --env.client --mode development", - "build:prod": "yarn run syncbuilddir && node ./webpack/run-replace.js && DSPACE_BUILD_DIR=./build node ./webpack/run-webpack.js --env.aot --env.server --mode production && DSPACE_BUILD_DIR=./build node ./webpack/run-webpack.js --env.aot --env.client --mode production", + "build": "node ./scripts/webpack.js --progress --mode development", + "build:aot": "yarn run syncbuilddir && node ./scripts/resolve-absolute-scss-imports.js && DSPACE_BUILD_DIR=./build node ./scripts/webpack.js --env.aot --env.server --mode development && DSPACE_BUILD_DIR=./build node ./scripts/webpack.js --env.aot --env.client --mode development", + "build:prod": "yarn run syncbuilddir && node ./scripts/resolve-absolute-scss-imports.js && DSPACE_BUILD_DIR=./build node ./scripts/webpack.js --env.aot --env.server --mode production && DSPACE_BUILD_DIR=./build node ./scripts/webpack.js --env.aot --env.client --mode production", "postbuild:prod": "yarn run rollup", "rollup": "rollup -c rollup.config.js", "prestart": "yarn run build:prod", @@ -41,8 +41,8 @@ "server": "node dist/server.js", "server:watch": "nodemon dist/server.js", "server:watch:debug": "nodemon --debug dist/server.js", - "syncbuilddir": "copyfiles -u 1 \"./src/**/*\" build && copyfiles -u 2 \"./themes/mantis/**/*\" build", - "webpack:watch": "node ./webpack/run-webpack.js -w --mode development", + "syncbuilddir": "node ./scripts/sync-build-dir.js", + "webpack:watch": "node ./scripts/webpack.js -w --mode development", "watch": "yarn run build && npm-run-all -p webpack:watch server:watch", "watch:debug": "yarn run build && npm-run-all -p webpack:watch server:watch:debug", "predebug": "yarn run build", diff --git a/webpack/run-replace.js b/scripts/resolve-absolute-scss-imports.js similarity index 92% rename from webpack/run-replace.js rename to scripts/resolve-absolute-scss-imports.js index fc73f74583..e4e29365f1 100644 --- a/webpack/run-replace.js +++ b/scripts/resolve-absolute-scss-imports.js @@ -1,7 +1,7 @@ const replace = require('replace-in-file'); const { projectRoot, -} = require('./helpers'); +} = require('../webpack/helpers'); /** * This script ensures you can use ~ to reference the project dir diff --git a/scripts/sync-build-dir.js b/scripts/sync-build-dir.js new file mode 100644 index 0000000000..c147f139a5 --- /dev/null +++ b/scripts/sync-build-dir.js @@ -0,0 +1,22 @@ +const syncBuildDir = require('copyfiles'); +const path = require('path'); +const { + projectRoot, + theme, + themePath, +} = require('../webpack/helpers'); + +const projectDepth = projectRoot('./').split(path.sep).length; + +let callback; + +if (theme !== null && theme !== undefined) { + callback = () => { + syncBuildDir([path.join(themePath, '**/*'), 'build'], { up: projectDepth + 2 }, () => {}) + } +} +else { + callback = () => {}; +} + +syncBuildDir([projectRoot('src/**/*'), 'build'], { up: projectDepth + 1 }, callback); diff --git a/webpack/run-webpack.js b/scripts/webpack.js similarity index 100% rename from webpack/run-webpack.js rename to scripts/webpack.js diff --git a/src/config.js b/src/config.js new file mode 100644 index 0000000000..269277643c --- /dev/null +++ b/src/config.js @@ -0,0 +1,150 @@ +const path = require('path'); + +let production = false; + +let mergedConfig; + +let envConfigOverride; + +let envConfigFile; + +__webpack + +// check process.env.NODE_ENV to determine which environment config to use +// process.env.NODE_ENV is defined by webpack, else assume development +switch (process.env.NODE_ENV) { + case 'prod': + case 'production': + // webpack.prod.dspace-angular-config.ts defines process.env.NODE_ENV = 'production' + envConfigFile = './environment.prod.js'; + production = true; + break; + case 'test': + // webpack.test.dspace-angular-config.ts defines process.env.NODE_ENV = 'test' + envConfigFile = './environment.test.js'; + break; + default: + // if not using webpack.prod.dspace-angular-config.ts or webpack.test.dspace-angular-config.ts, it must be development + envConfigFile = './environment.dev.js'; +} + +try { + mergedConfig = require(path.resolve(__dirname, '..', 'config', 'environment.default.js')); +} catch (e) { + console.log('e', e); + throw new Error('Cannot find file config/environment.default.js'); +} + +// if envConfigFile set try to get configs +if (envConfigFile) { + try { + envConfigOverride = require(path.resolve(__dirname, '..', 'config', envConfigFile)); + } catch (e) { + console.log('e', e); + console.warn('Cannot find file ' + envConfigFile.substring(2, envConfigFile.length), 'Using default environment'); + } + try { + merge(envConfigOverride); + } catch (e) { + console.warn('Unable to merge the default environment'); + } +} + +// allow to override a few important options by environment variables +function createServerConfig(host, port, nameSpace, ssl) { + const result = { host, nameSpace }; + + if (port !== null && port !== undefined) { + result.port = port * 1; + } + + if (ssl !== null && ssl !== undefined) { + result.ssl = ssl.trim().match(/^(true|1|yes)$/i) ? true : false; + } + + return result; +} + +const processEnv = { + ui: createServerConfig( + process.env.DSPACE_HOST, + process.env.DSPACE_PORT, + process.env.DSPACE_NAMESPACE, + process.env.DSPACE_SSL), + rest: createServerConfig( + process.env.DSPACE_REST_HOST, + process.env.DSPACE_REST_PORT, + process.env.DSPACE_REST_NAMESPACE, + process.env.DSPACE_REST_SSL) +}; + +// merge the environment variables with our configuration. +try { + merge(processEnv) +} catch (e) { + console.warn('Unable to merge environment variable into the configuration') +} + +buildBaseUrls(); + +// set config for whether running in production +mergedConfig.production = production; + +function merge(config) { + innerMerge(mergedConfig, config); +} + +function innerMerge(globalConfig, config) { + for (const key in config) { + if (config.hasOwnProperty(key)) { + if (isObject(config[key])) { + innerMerge(globalConfig[key], config[key]); + } else { + if (isDefined(config[key])) { + globalConfig[key] = config[key]; + } + } + } + } +} + +function buildBaseUrls() { + for (const key in mergedConfig) { + if (mergedConfig.hasOwnProperty(key) && mergedConfig[key].host) { + mergedConfig[key].baseUrl = [ + getProtocol(mergedConfig[key].ssl), + getHost(mergedConfig[key].host), + getPort(mergedConfig[key].port), + getNameSpace(mergedConfig[key].nameSpace) + ].join(''); + } + } +} + +function getProtocol(ssl) { + return ssl ? 'https://' : 'http://'; +} + +function getHost(host) { + return host; +} + +function getPort(port) { + return port ? (port !== 80 && port !== 443) ? ':' + port : '' : ''; +} + +function getNameSpace(nameSpace) { + return nameSpace ? nameSpace.charAt(0) === '/' ? nameSpace : '/' + nameSpace : ''; +} + +function isDefined(value) { + return typeof value !== 'undefined' && value !== null; +} + +function isObject(item) { + return item && typeof item === 'object' && !Array.isArray(item); +} + +module.exports = { + mergedConfig: mergedConfig +}; diff --git a/webpack/helpers.js b/webpack/helpers.js index 5d52fcf985..13178cd043 100644 --- a/webpack/helpers.js +++ b/webpack/helpers.js @@ -6,6 +6,8 @@ const projectRoot = (relativePath) => { return path.resolve(__dirname, '..', relativePath); }; +const srcPath = projectRoot('src'); + const buildRoot = (relativePath) => { if (process.env.DSPACE_BUILD_DIR) { return path.resolve(projectRoot(process.env.DSPACE_BUILD_DIR), relativePath); @@ -14,10 +16,46 @@ const buildRoot = (relativePath) => { } }; -// const theme = ''; -const theme = 'mantis'; +//TODO refactor to share between this and config.ts. +const getThemeName = () => { + let defaultCfg = require(projectRoot('config/environment.default.js')); + let envConfigFile, envConfigOverride; -const themePath = path.normalize(path.join(__dirname, '..', 'themes', theme)); + switch (process.env.NODE_ENV) { + case 'prod': + case 'production': + // webpack.prod.dspace-angular-config.ts defines process.env.NODE_ENV = 'production' + envConfigFile = projectRoot('config/environment.prod.js'); + break; + case 'test': + // webpack.test.dspace-angular-config.ts defines process.env.NODE_ENV = 'test' + envConfigFile = projectRoot('config/environment.test.js'); + break; + default: + // if not using webpack.prod.dspace-angular-config.ts or webpack.test.dspace-angular-config.ts, it must be development + envConfigFile = projectRoot('config/environment.dev.js'); + } + + if (envConfigFile) { + try { + envConfigOverride = require(envConfigFile); + } catch (e) { + } + } + + return Object.assign({}, defaultCfg.theme, envConfigOverride.theme).name; +} + +const theme = getThemeName(); + +let themePath; + +if (theme !== null && theme !== undefined) { + themePath = path.normalize(path.join(__dirname, '..', 'themes', theme)); +} +else { + themePath = srcPath; +} const globalCSSImports = [ buildRoot('styles/_variables.scss'), @@ -35,7 +73,6 @@ const themeReplaceOptions = ] }; -const srcPath = projectRoot('src'); const getThemedPath = (componentPath, ext) => { const parsedPath = path.parse(componentPath); @@ -71,7 +108,7 @@ const themedUse = (resource, extension) => { module.exports = { projectRoot, buildRoot, - theme, + theme: theme, themePath, getThemedPath, themedTest, diff --git a/webpack/webpack.common.js b/webpack/webpack.common.js index aadbf08424..e935cc3c8d 100644 --- a/webpack/webpack.common.js +++ b/webpack/webpack.common.js @@ -97,7 +97,6 @@ module.exports = { includePaths: [path.join(themePath, 'styles')] } }, - 'debug-loader', { loader: 'sass-resources-loader', options: {