From e13f33e5165c7504e1678c1c3698b7b012623f63 Mon Sep 17 00:00:00 2001 From: Matthew Morgan Date: Fri, 28 Dec 2018 09:50:26 -0500 Subject: [PATCH 1/3] Update README to explain serving production build --- README.md | 11 ++++++++++- 1 file changed, 10 insertions(+), 1 deletion(-) diff --git a/README.md b/README.md index 74dcb2a..ce6ffbb 100644 --- a/README.md +++ b/README.md @@ -230,7 +230,16 @@ React Redux Boilerplate supports production preview, which means that you can ru 1. Run `npm run build` and wait until it is done 2. Go to the project `docroot`, you will see a `index.html` (template is customizable, please read `Developing Template` section) -3. Open that `index.html` in your browser, and that is the build version that just got generated +3. Serve the build directory, for example like so: + +```bash +npm i -g http-server +cd docroot +http-server +``` +By default http-server will serve your production build at port 8080. Docs are [here](https://www.npmjs.com/package/http-server). + +4. Navigate to [that address](http://localhost:8080) to see your build. That's very easy, isn't it? From fd43238dde583734215f7e098d62c59a61f845b2 Mon Sep 17 00:00:00 2001 From: martino87r Date: Thu, 10 Jan 2019 21:22:16 +0100 Subject: [PATCH 2/3] Fixes redux-dev-tool deprecation warning --- src/js/redux/configureStore.js | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/src/js/redux/configureStore.js b/src/js/redux/configureStore.js index 0f62ecc..1c36a65 100644 --- a/src/js/redux/configureStore.js +++ b/src/js/redux/configureStore.js @@ -12,7 +12,7 @@ import rootReducer from './rootReducers'; // Redux DevTools Extension for Chrome and Firefox const reduxDevTool = () => { return typeof window === 'object' - && typeof window.devToolsExtension !== 'undefined' ? window.devToolsExtension() : (f) => f; + && typeof window.__REDUX_DEVTOOLS_EXTENSION__ !== 'undefined' ? window.__REDUX_DEVTOOLS_EXTENSION__() : (f) => f; }; export default function configureStore(initialState, history) { From 373cbb4659e05c0f3a4f24b8b3c4ce8fa8e0c026 Mon Sep 17 00:00:00 2001 From: Matthew Morgan Date: Sat, 19 Jan 2019 08:48:51 -0500 Subject: [PATCH 3/3] Update S3 deploy and docs --- README.md | 69 +++++++++++++----------------- config/default.json | 5 --- package.json | 2 + webpack.config.build.babel.js | 20 ++++++--- webpack.config.common.js | 5 +++ webpack.config.dev-server.babel.js | 5 --- 6 files changed, 49 insertions(+), 57 deletions(-) diff --git a/README.md b/README.md index ce6ffbb..3f254a4 100644 --- a/README.md +++ b/README.md @@ -167,6 +167,7 @@ If you see the landing page, it means you have set up everything successfully. ```sh $ npm run dev # build and watch, but javascript not minified $ npm run build # build a minified production version +$ npm run build:s3 # build a minified production version, deploy it to S3 as a static app $ npm run lint # linting using ESLint $ npm run test # run test using Jest $ npm run clean # it runs before each build, so you don't need to @@ -294,23 +295,40 @@ __Note:__ If you want to add new npm target ( e.g. `npm run build:stage` ), you ### Configuring secret key/value pair -There are times you may want to put in `secret information` you don't want to check into the source code. In this boilerplate, you just need to create a file called `.env` in your `PROJECT_ROOT`, and you can put your secret over there ( we have put that into `.gitignore` just in case ). For example, in order to use the feature to deploy to S3, you need to provide the following information. +There are times you may want to put in `secret information` you don't want to check into the source code. In this boilerplate, you just need to create a file called `.env` in your `PROJECT_ROOT`, and you can put your secrets there ( we have put that into `.gitignore` just in case ). +Specifically for deployment to S3, there are two options for providing your secrets: +1. In ~/.aws/credentials, configure a block like so, for example for a profile called "default": + +```bash +[default] +AWS_ACCESS_KEY_ID=XXXXXXXX # replace with your key +AWS_SECRET_ACCESS_KEY=XXXXXXX # replace with your secret ``` -AWS_ACCESS_KEY=YOUR_AWS_ACCESS_KEY -AWS_SECRET_KEY=YOUR_AWS_SECRET_KEY -AWS_BUCKET=YOUR_AWS_BUCKET -AWS_CDN_URL=YOUR_AWS_CDN_URL +2. You can provide the same values in a `.env` file within your project: + +```bash +AWS_ACCESS_KEY_ID=YOUR_AWS_ACCESS_KEY +AWS_SECRET_ACCESS_KEY=YOUR_AWS_SECRET_KEY +``` + +If you are using the AWS CLI, chances are you already have an `~/.aws/credentials` file, so you may find option 1 simpler locally. Option 2 may be better when using a build server like Jenkins. + +Finally, no matter which of the above two options you choose, you will ALSO need to provide these additional values in your `.env` file, or otherwise set them as environment variables when you build: + +```bash +AWS_BUCKET=YOUR_AWS_BUCKET # REQUIRED for S3 deploy +AWS_CDN_URL=YOUR_AWS_CDN_URL # OPTIONAL for S3 deploy ``` -And your in node application or webpack config, those key/value pair will inject into `process.env` ( e.g. `process.env.AWS_ACCESS_KEY` ). +And your in node application or webpack config, those key/value pairs will be injected into `process.env` ( e.g. `process.env.AWS_ACCESS_KEY_ID` ). -__Note__: Using `.env` file is optional, it meant to keep secret and inject information into environment variables, if you are using Jenkin or alike type of tools, you can inject environment variables there. +__Note__: Using the `.env` file is optional, it meant to keep secret and inject information into environment variables, if you are using Jenkins or a like type of tool, you can inject environment variables there. However, with `.env`, you can create a ready to use list of environment variables for your different environment. You can even have another service to generate the `.env` file before building the project, but in terms of how to achieve that, it is out of scope of this documentation. -__Just remember__, `.env` file suppose to keep your secret, and prevent your from saving sensitive secret into source code repository \0/ !! `DO NOT` check in `.env` into your source repo !! +__Just remember__, `.env` file is supposed to keep your secret, and prevent you from saving sensitive secrets into your source code repository \0/ !! **DO NOT** check `.env` into your source repo !! We are using [dotenv](https://github.com/motdotla/dotenv) for the `.env` feature, they have pretty good documentation. @@ -442,37 +460,9 @@ And this boilerplate has a process integrated to upload artifacts ( assets.json * __How to activate S3 support ?__ - * S3 upload is optional here, but if you want to activate that, please go to your config and make `"s3Deploy": true` and fill up the `s3` config ( bucket, accessKey ... etc). Remember that you can put the same config in different environment in case you want each one has different behavior. Below is an `example` in `config/default.json` - - - ``` - ( STEP 1 ) - - // Example in config/default.json - // You can overwrite default using your other config file - // ======================================================== - // default.json - global - // development.json - development ( npm run dev ) - // release.json - test/release ( npm run build:release ) - // production.json - production ( npm run build ) - // ======================================================== - { - "s3Deploy": true, - } - ``` - - And create a `.env` file and put in the following information. Please read [Configuration](#configuration) section for more information. - - - ``` - ( STEP 2 ) - - AWS_ACCESS_KEY=blah... - AWS_SECRET_KEY=blah... - AWS_BUCKET=blah... - AWS_CDN_URL=blah... - ``` - + * S3 upload is optional here + 1. Make sure you have provided your AWS credentials to the project (secret and access key). Please read [Configuration](#configuration) section for more information. + 2. Use the `npm run build:s3` script to build and deploy. * __What is our standard to control our npm module dependencies ?__ * We are using `^version`, it means "Compatible with version". The reason we are using `^version` is simply we want the ability for us to roll back to previous working version together with the source code. @@ -480,7 +470,6 @@ And this boilerplate has a process integrated to upload artifacts ( assets.json * __How to add javascript unit test ?__ * All React JS test are under \__tests__ directory and this tool will find all the test, you don't need to do anything besides putting your test in, but please use a structure that mimic your source location that you are testing, or it will create confusion. - * __What is B.E.M style ?__ * B.E.M is short for `Block, Element, Modifier` and is a naming convention for classes in HTML and CSS. Its goal is to help developers better understand the relationship between the HTML and CSS and make our code base more maintainable. Please read the links below for getting deeper insight of it. diff --git a/config/default.json b/config/default.json index b02564e..c60d4f1 100644 --- a/config/default.json +++ b/config/default.json @@ -5,11 +5,6 @@ "publicPath": "/", "assetPath": "assets", "jsSourcePath": "src/js", - "s3": { - "s3Deploy": false, - "bucket": "if-any", - "defaultCDNBase": "if-any" - }, "optimization": { "analyzeMode": false, "analyze": { diff --git a/package.json b/package.json index dc958ff..4f68ad2 100644 --- a/package.json +++ b/package.json @@ -5,7 +5,9 @@ "scripts": { "dev": "cross-env NODE_ENV=development DASHBOARD_PORT=9901 webpack-dashboard -p 9901 -c red -t dashboard -- node bin/commands.js dev", "build": "cross-env NODE_ENV=production node bin/commands.js build", + "build:s3": "cross-env S3_DEPLOY=true NODE_ENV=production node bin/commands.js build", "build:stage": "cross-env NODE_ENV=stage node bin/commands.js build", + "build:stage:s3": "cross-env S3_DEPLOY=true NODE_ENV=stage node bin/commands.js build", "clean": "rimraf docroot", "test": "jest --no-cache", "lint": "node bin/commands.js lint" diff --git a/webpack.config.build.babel.js b/webpack.config.build.babel.js index f979d42..2c7fe64 100644 --- a/webpack.config.build.babel.js +++ b/webpack.config.build.babel.js @@ -6,6 +6,7 @@ import SaveAssetsJson from 'assets-webpack-plugin'; import MiniCssExtractPlugin from 'mini-css-extract-plugin'; import precss from 'precss'; import postcssPresetEnv from 'postcss-preset-env'; +import AWS from 'aws-sdk'; import webpackConfig, { JS_SOURCE } from './webpack.config.common'; @@ -13,9 +14,7 @@ import webpackConfig, { JS_SOURCE } from './webpack.config.common'; // CONSTANT DECLARATION // ---------------------------------------------------------- -const S3_DEPLOY = config.get('s3.s3Deploy') || 'false'; -const IS_S3_DEPLOY = String(S3_DEPLOY) === 'true'; - +const IS_S3_DEPLOY = Boolean(process.env.S3_DEPLOY); const PUBLIC_PATH = IS_S3_DEPLOY ? process.env.AWS_CDN_URL : config.get('publicPath'); const APP_ENTRY_POINT = `${JS_SOURCE}/router`; @@ -97,14 +96,21 @@ if (IS_S3_DEPLOY) { // Please read README if you have no idea where // `process.env.AWS_ACCESS_KEY` is coming from + let s3Options = {}; + if (process.env.AWS_PROFILE) { + s3Options = new AWS.SharedIniFileCredentials({ profile: process.env.AWS_PROFILE }); + } + if (process.env.AWS_ACCESS_KEY) { + s3Options.accessKeyId = process.env.AWS_ACCESS_KEY_ID; + } + if (process.env.AWS_SECRET_KEY) { + s3Options.secretAccessKey = process.env.AWS_SECRET_ACCESS_KEY; + } const s3Config = new S3Plugin({ // Only upload css and js // include: /.*\.(css|js)/, // s3Options are required - s3Options: { - accessKeyId: process.env.AWS_ACCESS_KEY, - secretAccessKey: process.env.AWS_SECRET_KEY, - }, + ...s3Options, s3UploadOptions: { Bucket: process.env.AWS_BUCKET, }, diff --git a/webpack.config.common.js b/webpack.config.common.js index 64ab948..a01c9e5 100644 --- a/webpack.config.common.js +++ b/webpack.config.common.js @@ -5,6 +5,11 @@ import webpack from 'webpack'; import CaseSensitivePathsPlugin from 'case-sensitive-paths-webpack-plugin'; import config from 'config'; +// Please read the following link if +// you have no idea how to use this feature +// https://github.com/motdotla/dotenv +require('dotenv').config({ silent: true }); + // trace which loader is deprecated // feel free to remove that if you don't need this feature process.traceDeprecation = false; diff --git a/webpack.config.dev-server.babel.js b/webpack.config.dev-server.babel.js index 85e45e4..1887715 100644 --- a/webpack.config.dev-server.babel.js +++ b/webpack.config.dev-server.babel.js @@ -7,11 +7,6 @@ import postcssPresetEnv from 'postcss-preset-env'; import webpackConfig, { JS_SOURCE } from './webpack.config.common'; -// Please read the following link if -// you have no idea how to use this feature -// https://github.com/motdotla/dotenv -require('dotenv').config({ silent: true }); - const HOST = process.env.HOST || config.get('host') || '0.0.0.0' const PORT = process.env.PORT || config.get('port') || '8080' const APP_ENTRY_POINT = `${JS_SOURCE}/router`;