Giter Club home page Giter Club logo

budgeting's Introduction

PRs Welcome MIT Licensed FOSSA Status CircleCI Coverage Status Maintainability Powered by Modus_Create

⚠️ Important Note ⚠️

While this project still fullfills the goal of demonstrating a scalable React architecture, it's now technically obsolete. At Modus Labs we are continuing to show modern best practices via GitHub and our YouTube Channel

Budgeting :: A Scalable React, Redux, React Router 4, Webpack Sample App

React, Redux, Router, Webpack, Sass

Production-ready React + Webpack architecture implemented on consumer web apps of some of the most successful enterprises in the world. Perceived performance and development experience are key factors in this setup. You can use this code base for learning or to scaffold your mission-critical project.

See live demo.

React Budgeting App

Budgeting Application

This is a simple budget management application. It tracks inflow and outflow, shows remaining budget, and interesting reports with charts. As such, it offers more features than the usual Todo App.

Budgeting app is a showcase project that demonstrates important decisions in architecture and development of a modern React application.

Feel free to use it as a reference app or a starter kit.

Key concepts:

Performance

Budgeting App Performance The app loads in 1 second on 3G, cache disabled

Budgeting app is blazing fast, thanks to the smart architecture and Webpack 3 configuration. It takes about 1000ms (1s) to load on 3G (see above).

Alex Russel Test Emerging Markets 3G Filmstrip

The aggressive test above shows the budgeting app loads in under 5 seconds. It's a heavily limited connection that accounts for poor connectivity and limited bandwidth.

Waterfall

All important (aka critical path) assets are loaded as early as possible, while the others (e.g. images or GitHub buttons) will load after the first render.

How did we get that performance?

  1. Minimal application core. We decided to ditch the usual convention of creating a vendor chunk. Instead, it's bundled in the app core. The app core is actually very small, containing just the code needed to bootstrap the app.
  2. Common code is a chunk. We let Webpack figure out which bundles we reuse in chunks and create a common chunk that's also asyncronous.
  3. Redux module injection. Each chunk contains respective views and redux modules. Yes, that means reducers, action creators, actions - are all dynamically injected as we navigate through routes. That adds to the minimal application core concept and PRPL pattern.
  4. H2 Push. The app is hosted on Firebase and we use the magic of HTTP2 Push to push some of the scripts before they are requested.
  5. Pre-caching. Service Workers pre-cache resources so the browser can access them as soon as the user needs to.

Charts

Charts are developed using the awesome D3 library. The idea behind showing charts is not only to show beautiful content, but also to demonstrate keeping heavy content in a chunk that owns it. In other words - we show how applications can run fast even if they use larger libraries.

D3 is used in the /reports route only. Given that major routes are separate chunks (code splitting FTW!), the entire D3 library is bundled with the code that needs it. That makes the /reports route a bit heavier than the initial /budget route, but it also makes routes much faster to load.

Performance Budgets

We are looking to maintain the lightest possible application core (aka entry chunk). Our target is 300kB for the entrypoint and 300kB for all other assets. This is how we set it in webpack configuration:

performance: {
  maxAssetSize: 300000,
  maxEntrypointSize: 300000,
  hints: 'warning',
},

Adding lots of extra code to the entry chunk might cause the build (npm run build) process to show a warning.

Performance Budgets

Simulated size warning

Note that running webpack dev server in production mode (npm run prod) will trigger this warning because of the additional dev server code injected in the app. This code will not show in regular production builds.

Service Workers

Service workers are enabled only when serving static files, not through webpack-dev-server. Here's how you can test service worker functionality:

  1. Run npm run build to build the app
  2. Run npm run prod to serve the app on localhost:3000
  3. Run a new instance of Chrome with disabled security (because localhost is not on https):

OS X

open -a "Google Chrome" --args --user-data-dir=/tmp/unsafe --unsafely-treat-insecure-origin-as-secure=http://localhost

Linux

/path/to/chrome --user-data-dir=/tmp/unsafe --unsafely-treat-insecure-origin-as-secure=http://localhost

Windows

chrome.exe --user-data-dir=c:\temp --unsafely-treat-insecure-origin-as-secure=http://localhost
  1. Now you can observe network traffic in the Network tab or SW activity in Application > Service Workers in Developer Tools

Stack

The app was built using these aweseome technologies

NPM Scripts

  • npm install - install dependencies
  • npm start - run development server
  • npm run prod - run production server
  • npm run build - build app for deployment
  • npm run serve - serve previously built app using pushstate server
  • npm run lint - lint check
  • npm run lint:fix - lint check + autofixes + prettify code with prettier
  • npm test - run test suite
  • npm run test:fix - run test suite watching files for changes
  • npm run flow - run flow type checking
  • npm run update-types - update flow library definitions

Honorary Mentions

Want more?

This project is maintained by Modus Create. Fantastic React apps are in our DNA so give us a buzz if we can help with your awesome project.

License

MIT

FOSSA Status

budgeting's People

Contributors

borlov avatar bricemason avatar easingthemes avatar ecris87 avatar elas7 avatar ernestor avatar fossabot avatar grgur avatar ikovic avatar jamesallenuk avatar jlangevin avatar jmalfatto avatar jontonsoup4 avatar nelsonomuto avatar obscurerichard avatar rafaelquintanilha avatar sulfurious avatar ugarz avatar

Stargazers

 avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar

Watchers

 avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar

budgeting's Issues

`screw_ie8` is not a supported option

On the current master branch, I end up with this error when I run npm run build.

ERROR in main-ee2fb0ea.js from UglifyJs
DefaultsError: `screw_ie8` is not a supported option

404 when accessing /budget directly

Steps to reproduce

Observed Behavior

  • This results in a 404 Page not found error.

Expected Behavior

  • Content corresponding to the given route is displayed.

Screenshots

image

Potential solution:

  • Now that the app has switched from HashRouter to BrowserRouter the server could be configured to redirect 404s to /, essentially letting the client handle them.

Create a tag/branch with a clean boilerplate

Description

I've wanted to use this project to bootstrap another React app, so I've just spent some short time removing the business logic, branding and config related to budgeting app.
Maybe it would be useful to keep a branch or a tag with a clean boilerplate in this repo?

These are the changes I've made to my fork: link.

If you think this might be a good idea, I can do another sweep and write better docs on this.

Tree-shaking doesn't work

Seems like three-shaking doesn't work. I see it with webpack-bundle-analyzer. React-route, react-router-dom and history libs are in full codebase.
2017-08-03 15 38 03

Cannot find module './dll/libs-manifest.json'

Description

Error when trying to do npm start

Error:
Cannot find module './dll/libs-manifest.json'

Steps to reproduce

  1. git clone this repo, cd into budgeting folder
  2. ran npm install and then npm start

Observed Behavior

Expected Behavior

I expect webpack dev server to start.

Additional Details

Screen Shot 2020-05-22 at 7 55 41 AM

Screen Shot 2020-05-22 at 7 55 58 AM

is tree shaking done properly?

How does one know the tree shaking is done properly. In the webpack-visualizer, it seems like all of the npm packages were imported in full.

Missing example for multiple query definitions for new loader syntax

It's common to see loaders like this in Webpack 1:

loaders: [
    'isomorphic-style'
    'css?sourceMap'
    'postcss?sourceMap'
    'sass?sourceMap'
]

This example isn't represented in this Webpack's config file.
Is that out of the scope of this sample project or is it something you're considering adding?

source maps

I noticed that .map files are present even when you build source for production. Is it be design or a mistake? I always thought that you do not want to have maps on your production but just uglified/minified code for speed.

Bundling Issue

It appears that this code has some of the issues discussed on this thread:

webpack/webpack#2537

Specifically, I had to remove the -p option or the Uglify plugin ran twice. Also, -p was not setting the NODE_ENV variable, so the production parts of the webpack.config were never being run. If I manually set the NODE_ENV at the command line to 'production', it would run the production sections of the webpack.config.

Clearing the NODE_ENV (set NODE_ENV=) and running webpack (no -p) result in a 1 meg package. Even if I manually set NODE_ENV, I get a 56k (gzip/min package), which is different than your size, so I am wondering what's wrong.

[Question] Why core module is on low priority?

Does it make sense to pre-load resources with higher priority than main module?
It should affect on time to interactive.. isn't it?

image

And the second question is - It seems like 'reports.js' is downloaded twice:

image

Can you help me to figure it out, please?

PS I'm using chrome with cache enabled; yarn run prod

Lint Task does not work

Hello,

The Lint Task does not seem to work, when I run "yarn run lint" I get the following error:

/Users/markpaul/Documents/Source/Research/testagain/node_modules/eslint-config-airbnb-base/rules/style.js:
	Configuration for rule "no-restricted-syntax" is invalid:
	Value "[object Object]" must be an enum value.

Referenced from: /Users/markpaul/Documents/Source/Research/testagain/node_modules/eslint-config-airbnb-base/index.js
Referenced from: eslint-config-airbnb
Referenced from: /Users/markpaul/Documents/Source/Research/testagain/.eslintrc
Error: /Users/markpaul/Documents/Source/Research/testagain/node_modules/eslint-config-airbnb-base/rules/style.js:
	Configuration for rule "no-restricted-syntax" is invalid:
	Value "[object Object]" must be an enum value.

Referenced from: /Users/markpaul/Documents/Source/Research/testagain/node_modules/eslint-config-airbnb-base/index.js
Referenced from: eslint-config-airbnb
Referenced from: /Users/markpaul/Documents/Source/Research/testagain/.eslintrc
    at validateRuleOptions (/Users/markpaul/Documents/Source/Research/testagain/node_modules/eslint/lib/config/config-validator.js:109:15)
    at Object.keys.forEach.id (/Users/markpaul/Documents/Source/Research/testagain/node_modules/eslint/lib/config/config-validator.js:156:13)
    at Array.forEach (native)
    at Object.validate (/Users/markpaul/Documents/Source/Research/testagain/node_modules/eslint/lib/config/config-validator.js:155:35)
    at load (/Users/markpaul/Documents/Source/Research/testagain/node_modules/eslint/lib/config/config-file.js:529:19)
    at configExtends.reduceRight.e (/Users/markpaul/Documents/Source/Research/testagain/node_modules/eslint/lib/config/config-file.js:391:36)
    at Array.reduceRight (native)
    at applyExtends (/Users/markpaul/Documents/Source/Research/testagain/node_modules/eslint/lib/config/config-file.js:362:28)
    at load (/Users/markpaul/Documents/Source/Research/testagain/node_modules/eslint/lib/config/config-file.js:536:22)
    at configExtends.reduceRight.e (/Users/markpaul/Documents/Source/Research/testagain/node_modules/eslint/lib/config/config-file.js:391:36)
✨  Done in 1.46s.

Inconsistent Behaviour - Getting Uncaught ReferenceError: libs_dll is not defined

Description

  1. I am getting Uncaught ReferenceError: libs_dll is not defined on browser console sometimes when I do command + shift + r.
  2. The error is not consistent.
  3. Also compile time has been increased drastically after this commit. 25e0d40 (This is the commit I am using).

Steps to reproduce

  1. git clone https://github.com/ModusCreateOrg/budgeting-sample-app-webpack2.git
  2. yarn install
  3. yarn start
  4. Open chrome and console panel
  5. Access localhost:3000
  6. command + shift + r multiple times after each reload
  7. You will see the error.

Expected Behaviour

  1. App should run all the time even on hard refresh
  2. Sub sequent compile time should be less.

Additional Details

  1. node : v6.11.1
  2. yarn version : 1.0.0
  3. npm : 3.10.10
  4. Chrome : Version 60.0.3112.113 (Official Build) (64-bit)

screen shot 2017-09-15 at 12 19 23 pm

How can I set max-size for all the chunk files and entry file main.js by 205kb

Description

  1. How can I set max-size for all the chunk files.
  2. How can I reduce or split main.js file.

Steps to reproduce

  1. npm run build > after build my chunk files and main.js will get bigger(more then 300kb).

Expected Behavior

  1. I don't want to my chunk file size more then 250kb
  2. I don't want to my entry point file(main.js) size more then 250kb

Additional Details

Please see attached file.
issue

npm install does not work

I can't run npm install, beause of peerDependencies:

npm ERR! Linux 3.13.0-83-generic
npm ERR! argv "/usr/bin/node" "/usr/bin/npm" "i"
npm ERR! node v0.12.12
npm ERR! npm  v2.14.9
npm ERR! code EPEERINVALID

npm ERR! peerinvalid The package [email protected] does not satisfy its siblings' peerDependencies requirements!
npm ERR! peerinvalid Peer [email protected] wants webpack@1 || ^2.1.0-beta
npm ERR! peerinvalid Peer [email protected] wants webpack@>=2.0.3-beta <3

npm ERR! Please include the following file with any support request:
npm ERR!     /home/.../budgeting-sample-app-webpack2/npm-debug.lo

start error

After npm i , npm start:

npm ERR! Linux 3.16.0-4-amd64
npm ERR! argv "/usr/bin/nodejs" "/usr/bin/npm" "start"
npm ERR! node v6.8.1
npm ERR! npm  v3.10.8
npm ERR! code ELIFECYCLE
npm ERR! webpack2-react-redux-budget-app-sample@1.0.0 start: `webpack-dev-server --history-api-fallback --progress --port 3000`
npm ERR! Exit status 1
npm ERR! 
npm ERR! Failed at the webpack2-react-redux-budget-app-sample@1.0.0 start script 'webpack-dev-server --history-api-fallback --progress --port 3000'.
npm ERR! Make sure you have the latest version of node.js and npm installed.
npm ERR! If you do, this is most likely a problem with the webpack2-react-redux-budget-app-sample package,
npm ERR! not with npm itself.
npm ERR! Tell the author that this fails on your system:
npm ERR!     webpack-dev-server --history-api-fallback --progress --port 3000
npm ERR! You can get information on how to open an issue for this project with:
npm ERR!     npm bugs webpack2-react-redux-budget-app-sample
npm ERR! Or if that isn't available, you can get their info via:
npm ERR!     npm owner ls webpack2-react-redux-budget-app-sample
npm ERR! There is likely additional logging output above.

npm ERR! Please include the following file with any support request:
npm ERR!     /home/lex93ushakov/lab/budgeting-sample-app-webpack2/npm-debug.log

Feedback

Great work so far! When profiling the app on an EM connection (pretty real world 3G with accountability for spottiness) we don't see first meaningful paint until about 9 seconds in:

image

https://www.webpagetest.org/video/compare.php?tests=170501_97_ba8c5bf5efc877719f267f8011498293-r:2-c:0

If we dig into the waterfall we can see that quite a few of your critical path requests are taking a while to get fetched, pushing out the point when all of the JS gets fetched, parsed and executed.

image

Looking at the source you're using prefetch instead of preload here:

image

This will actually force your scripts to be loaded with a lower priority than if you use preload. I would strongly reco trying to use preload for these here.

Your total amount of JS in the app is relatively small. Still way under 100KB from what I can see.

Cannot run npm start

C:\Projekty\budgeting-sample-app-webpack2-master\node_modules\webpack-dev-server\bin\webpack-dev-server.js:385
                throw e;
                ^

Error: options/query provided without loader (use loader + options) in {
  "test": {},
  "exclude": {},
  "use": "file-loader",
  "query": {
    "name": "[name].[ext]"
  }
}
    at Function.RuleSet.normalizeRule (C:\Projekty\budgeting-sample-app-webpack2-master\node_modules\webpack\lib\RuleSet.js:168:9)
    at C:\Projekty\budgeting-sample-app-webpack2-master\node_modules\webpack\lib\RuleSet.js:83:19
    at Array.map (native)
    at Function.RuleSet.normalizeRules (C:\Projekty\budgeting-sample-app-webpack2-master\node_modules\webpack\lib\RuleSet.js:82:16)
    at new RuleSet (C:\Projekty\budgeting-sample-app-webpack2-master\node_modules\webpack\lib\RuleSet.js:75:23)
    at new NormalModuleFactory (C:\Projekty\budgeting-sample-app-webpack2-master\node_modules\webpack\lib\NormalModuleFactory.js:47:17)
    at Compiler.createNormalModuleFactory (C:\Projekty\budgeting-sample-app-webpack2-master\node_modules\webpack\lib\Compiler.js:438:28)
    at Compiler.newCompilationParams (C:\Projekty\budgeting-sample-app-webpack2-master\node_modules\webpack\lib\Compiler.js:451:29)
    at Compiler.compile (C:\Projekty\budgeting-sample-app-webpack2-master\node_modules\webpack\lib\Compiler.js:460:20)
    at C:\Projekty\budgeting-sample-app-webpack2-master\node_modules\webpack\lib\Compiler.js:47:17

npm ERR! [email protected] start: `webpack-dev-server`
npm ERR! Exit status 1
npm ERR!
npm ERR! Failed at the [email protected] start script.
npm ERR! This is most likely a problem with the webpack2-react-redux-budget-app-sample package,
npm ERR! not with npm itself.
npm ERR! Tell the author that this fails on your system:
npm ERR!     webpack-dev-server
npm ERR! You can get their info via:
npm ERR!     npm owner ls webpack2-react-redux-budget-app-sample
npm ERR! There is likely additional logging output above.
npm ERR! System Windows_NT 10.0.14393
npm ERR! command "C:\\Program Files\\nodejs\\node.exe" "C:\\ProgramData\\chocolatey\\lib\\npm\\tools\\node_modules\\npm\\bin\\npm-cli.js" "start"
npm ERR! cwd C:\Projekty\budgeting-sample-app-webpack2-master
npm ERR! node -v v7.2.1
npm ERR! npm -v 1.4.9
npm ERR! code ELIFECYCLE
npm ERR!
npm ERR! Additional logging details can be found in:
npm ERR!     C:\Projekty\budgeting-sample-app-webpack2-master\npm-debug.log
npm ERR! not ok code 0

Cannot find module './dll/d3-manifest.json'

After cloning the project and installing the dependencies, when I run "npm start" I get:

Cannot find module './dll/d3-manifest.json'

is this a problem on my end or the project?
Thank you in advance!

Recommend Projects

  • React photo React

    A declarative, efficient, and flexible JavaScript library for building user interfaces.

  • Vue.js photo Vue.js

    🖖 Vue.js is a progressive, incrementally-adoptable JavaScript framework for building UI on the web.

  • Typescript photo Typescript

    TypeScript is a superset of JavaScript that compiles to clean JavaScript output.

  • TensorFlow photo TensorFlow

    An Open Source Machine Learning Framework for Everyone

  • Django photo Django

    The Web framework for perfectionists with deadlines.

  • D3 photo D3

    Bring data to life with SVG, Canvas and HTML. 📊📈🎉

Recommend Topics

  • javascript

    JavaScript (JS) is a lightweight interpreted programming language with first-class functions.

  • web

    Some thing interesting about web. New door for the world.

  • server

    A server is a program made to process requests and deliver data to clients.

  • Machine learning

    Machine learning is a way of modeling and interpreting data that allows a piece of software to respond intelligently.

  • Game

    Some thing interesting about game, make everyone happy.

Recommend Org

  • Facebook photo Facebook

    We are working to build community through open source technology. NB: members must have two-factor auth.

  • Microsoft photo Microsoft

    Open source projects and samples from Microsoft.

  • Google photo Google

    Google ❤️ Open Source for everyone.

  • D3 photo D3

    Data-Driven Documents codes.