From 46f4b9d14a9d54c9f28f52390f36c15ac98f90eb Mon Sep 17 00:00:00 2001 From: Alex Mikhalev Date: Mon, 3 Sep 2018 17:37:19 -0600 Subject: [PATCH] feat: Use oclif cli for server; clean up webpack config --- bin/sprinklers3 | 9 + client/env.js | 77 ++++---- client/webpack.config.js | 108 +++++------ common/browserLogger.ts | 126 ++++++++++++ common/logger.ts | 120 +----------- package.json | 28 ++- server/Database.ts | 6 +- server/bin/server.ts | 28 --- server/commands/manage.ts | 11 ++ .../prettyPrint.ts => commands/pretty.ts} | 17 +- server/commands/serve.ts | 33 ++++ server/state.ts | 18 +- yarn.lock | 179 +++++++++++++++++- 13 files changed, 480 insertions(+), 280 deletions(-) create mode 100755 bin/sprinklers3 create mode 100644 common/browserLogger.ts delete mode 100644 server/bin/server.ts create mode 100644 server/commands/manage.ts rename server/{bin/prettyPrint.ts => commands/pretty.ts} (87%) create mode 100644 server/commands/serve.ts diff --git a/bin/sprinklers3 b/bin/sprinklers3 new file mode 100755 index 0000000..cccd1ad --- /dev/null +++ b/bin/sprinklers3 @@ -0,0 +1,9 @@ +#!/usr/bin/env node + +const { run } = require("@oclif/command"); +const flush = require("@oclif/command/flush"); +const handleError = require("@oclif/errors/handle"); + +run() + .then(flush) + .catch(handleError); diff --git a/client/env.js b/client/env.js index 4559427..cf7b349 100644 --- a/client/env.js +++ b/client/env.js @@ -1,58 +1,45 @@ const fs = require("fs"); -const path = require("path"); +const dotenv = require("dotenv"); const paths = require("../paths") -const NODE_ENV = process.env.NODE_ENV; -if (!NODE_ENV) { - throw new Error( - "The NODE_ENV environment variable is required but was not specified.", - ); -} - -// https://github.com/bkeepers/dotenv#what-other-env-files-can-i-use -const dotenvFiles = [ - `${paths.dotenv}.${NODE_ENV}.local`, - `${paths.dotenv}.${NODE_ENV}`, - // Don"t include `.env.local` for `test` environment - // since normally you expect tests to produce the same - // results for everyone - NODE_ENV !== "test" && `${paths.dotenv}.local`, - paths.dotenv, -].filter(Boolean); +const validEnvs = ["production", "development"]; -// Load environment variables from .env* files. Suppress warnings using silent -// if this file is missing. dotenv will never modify any environment variables -// that have already been set. -// https://github.com/motdotla/dotenv -dotenvFiles.forEach(dotenvFile => { - if (fs.existsSync(dotenvFile)) { - require("dotenv").config({ - path: dotenvFile, - }); +exports.loadEnv = function loadEnv(env) { + if (validEnvs.indexOf(env) === -1) { + throw new Error("Must specify webpack --env as one of: " + validEnvs.join(',')); } -}); -// We support resolving modules according to `NODE_PATH`. -// This lets you use absolute paths in imports inside large monorepos: -// https://github.com/facebookincubator/create-react-app/issues/253. -// It works similar to `NODE_PATH` in Node itself: -// https://nodejs.org/api/modules.html#modules_loading_from_the_global_folders -// Note that unlike in Node, only *relative* paths from `NODE_PATH` are honored. -// Otherwise, we risk importing Node.js core modules into an app instead of Webpack shims. -// https://github.com/facebookincubator/create-react-app/issues/1023#issuecomment-265344421 -// We also resolve them to make sure all tools using them work consistently. -const appDirectory = fs.realpathSync(process.cwd()); -process.env.NODE_PATH = (process.env.NODE_PATH || "") - .split(path.delimiter) - .filter(folder => folder && !path.isAbsolute(folder)) - .map(folder => path.resolve(appDirectory, folder)) - .join(path.delimiter); + const dotenvFiles = [ + `${paths.dotenv}.${env}.local`, + `${paths.dotenv}.${env}`, + // Don"t include `.env.local` for `test` environment + // since normally you expect tests to produce the same + // results for everyone + env !== "test" && `${paths.dotenv}.local`, + paths.dotenv, + ].filter(Boolean); + + dotenvFiles.forEach(dotenvFile => { + if (fs.existsSync(dotenvFile)) { + dotenv.config({ + path: dotenvFile, + }); + } + }); + + delete require.cache[require.resolve("../paths")]; // so new env applies + + return { + isProd: env === "production", + isDev: env === "development" + }; +} // Grab NODE_ENV and REACT_APP_* environment variables and prepare them to be // injected into the application via DefinePlugin in Webpack configuration. const REACT_APP = /^REACT_APP_/i; -exports.getClientEnvironment = function getClientEnvironment(publicUrl) { +exports.getClientEnvironment = function getClientEnvironment(env, publicUrl) { const raw = Object.keys(process.env) .filter(key => REACT_APP.test(key)) .reduce( @@ -62,7 +49,7 @@ exports.getClientEnvironment = function getClientEnvironment(publicUrl) { }, { // Useful for determining whether we’re running in production mode. // Most importantly, it switches React into the correct mode. - NODE_ENV: process.env.NODE_ENV || "development", + NODE_ENV: process.env.NODE_ENV || env, // Useful for resolving the correct path to static assets in `public`. // For example, . // This should only be used as an escape hatch. Normally you would put diff --git a/client/webpack.config.js b/client/webpack.config.js index 42c1629..e47a42f 100644 --- a/client/webpack.config.js +++ b/client/webpack.config.js @@ -11,53 +11,58 @@ const BundleAnalyzerPlugin = require("webpack-bundle-analyzer") const MiniCssExtractPlugin = require("mini-css-extract-plugin"); const ForkTsCheckerWebpackPlugin = require("fork-ts-checker-webpack-plugin"); -const { getClientEnvironment } = require("./env"); -const paths = require("../paths"); +const { loadEnv, getClientEnvironment } = require("./env"); -// Webpack uses `publicPath` to determine where the app is being served from. -// It requires a trailing slash, or the file assets will get an incorrect path. -const publicPath = paths.publicPath; -// `publicUrl` is just like `publicPath`, but we will provide it to our app -// as %PUBLIC_URL% in `index.html` and `process.env.PUBLIC_URL` in JavaScript. -// Omit trailing slash as %PUBLIC_URL%/xyz looks better than %PUBLIC_URL%xyz. -const publicUrl = paths.publicUrl.slice(0, -1); -// Source maps are resource heavy and can cause out of memory issue for large source files. -const shouldUseSourceMap = process.env.GENERATE_SOURCEMAP !== "false"; -// Get environment variables to inject into our app. -const environ = getClientEnvironment(publicUrl); +function getConfig(env) { + const { isProd, isDev } = loadEnv(env); -const postCssConfig = { - loader: require.resolve("postcss-loader"), - options: { - // Necessary for external CSS imports to work - // https://github.com/facebookincubator/create-react-app/issues/2677 - ident: "postcss", - plugins: () => [ - require("postcss-flexbugs-fixes"), - require("postcss-preset-env")({ - stage: 0 - }) - ] - } -}; + const paths = require("../paths"); -const sassConfig = { - loader: require.resolve("sass-loader"), - options: {} -}; + // Webpack uses `publicPath` to determine where the app is being served from. + // It requires a trailing slash, or the file assets will get an incorrect path. + const publicPath = paths.publicPath; + // `publicUrl` is just like `publicPath`, but we will provide it to our app + // as %PUBLIC_URL% in `index.html` and `process.env.PUBLIC_URL` in JavaScript. + // Omit trailing slash as %PUBLIC_URL%/xyz looks better than %PUBLIC_URL%xyz. + const publicUrl = paths.publicUrl.slice(0, -1); + // Source maps are resource heavy and can cause out of memory issue for large source files. + const shouldUseSourceMap = process.env.GENERATE_SOURCEMAP !== "false"; + const shouldExtractCss = process.env.EXTRACT_CSS + ? process.env.EXTRACT_CSS === "true" + : isProd; + // Get environment variables to inject into our app. + const environ = getClientEnvironment(env, publicUrl); + + const postCssConfig = { + loader: require.resolve("postcss-loader"), + options: { + // Necessary for external CSS imports to work + // https://github.com/facebookincubator/create-react-app/issues/2677 + ident: "postcss", + plugins: () => [ + require("postcss-flexbugs-fixes"), + require("postcss-preset-env")({ + stage: 0 + }) + ] + } + }; + + const sassConfig = { + loader: require.resolve("sass-loader"), + options: {} + }; -const rules = env => { // "postcss" loader applies autoprefixer to our CSS. // "css" loader resolves paths in CSS and adds assets as dependencies. // "style" loader turns CSS into JS modules that inject