1.0.34 β€’ Published 6 years ago

connected-retail v1.0.34

Weekly downloads
3
License
UNLICENSED
Repository
-
Last release
6 years ago

Fusion Starter

Fusion Starter is a comprehensive starter project for rapid application development using React.

Demo

https://fusion-starter.firebaseapp.com

Quick Start

First time? Do the initial setup.

git clone git@ghe.coxautoinc.com:CoxAuto-UI/fusion.git your-project-name-here
cd your-project-name-here
npm run setup
npm start -s

The setup step will prompt you for basic information on your project and write the relevant information to package.json. npm start will run the automated build process, lint, start up a webserver, and open the application in your default browser. After running the start command, your code is rebuilt every time you hit save. See the full list of commands.

Once you're comfortable with how the example app works, remove the example app: npm run remove-demo and start coding!

Initial Setup

  1. Install Node.js and Git. The defaults are fine.
  2. Request @coxautokc npm access. Register on npmjs.com and email Cory House your npm username. After you've been added, you can continue with the steps below.
  3. Login and save your npm credentials npm adduser --registry=https://registry.npmjs.org --scope=@coxautokc. This will prompt you for your npm username and password and save them to .npmrc so you aren't prompted to log in again.
  4. Configure Git On Windows? Disable line ending conversion in Git.
  5. Configure your Editor for React. Install the appropriate JSX plugin and install the editorconfig plugin for your editor.

Why Use this?

  1. One command to get started - Type npm start to start development in your default browser.
  2. Rapid feedback - Each time you hit save, changes reload and linting and automated tests run.
  3. One command line to check - All feedback is displayed on a single command line.
  4. No more JavaScript fatigue - Uses the most popular and powerful libraries for working with React.
  5. Working example app - The included example app shows how this all works together.
  6. Automated production build - Type npm run build to minify and bundle your app for production.

Who is using Fusion?

These Cox Automotive projects use Fusion:

ProjectBusiness Unit
Service DashboardVinSolutions
BookoutVinsolutions
Customer RecordVinSolutions
Customer AttachmentsVinSolutions
DMS PushVinSolutions
Connection ScoreVinSolutions
Customer-Facing DeskingVinSolutions
GM CustomerVinSolutions
GM Repair Order HistoryVinSolutions
Digital ShowroomF&I

Know of other apps using Fusion? Open an issue on this repository and let us know! 😎

Contributing

This is an inner sourced project, so anyone is free to contribute a pull request. Want to contribute? See CONTRIBUTE.md.

Technologies

Fusion is an opinionated React framework.

Core Technologies and Resources for Learning More

TechDescriptionLearn More
ReactFast, composable client-side componentsThinking in React, Pluralsight Courses, Smart vs Dumb Components, Stateless Functional Components, Using React State Correctly, State shouldn't depend on other state, React Best Practices, React performance measurement, Integrate React with existing apps
React RouterA complete routing library for React.
React-BootstrapMany Fusion-UI components use React-Bootstrap behind the scenes.
ReduxEnforces unidirectional data flows and immutable stores. Useful on larger apps with complex data flows. Alternative to Facebook's Flux.Tutorial Video, Pluralsight Course, Code-based tutorial, Working with data in Redux, The Tao of Redux
BabelCompiles ES6 to ES5. Enjoy the new version of JavaScript todayES6 REPL, ES6 vs ES5, ES6 Katas, Pluralsight course
WebpackBundles npm packages and our JS into a single file. Supports hot reloading.Quick Webpack How-to Pluralsight Course
JestAutomated testingPluralsight Course, Snapshot testing, Snapshot testing video
TrackJSJavaScript error tracking. Reports available at TrackJS.com. Email cory.house@vinsolutions.com to request access.Β 
ESLintLint JS. Reports syntax and style issues. Using eslint-plugin-react for additional React specific linting rules.
SASSCompiled CSS styles with variables, functions, and more.Pluralsight Course
PostCSSA tool for transforming CSS with JavaScript. We're using stylelint to lint styles
Editor ConfigEnforce consistent editor settings (spaces vs tabs, etc).IDE Plugins
npm ScriptsGlues all this together in a handy automated build.Pluralsight course, Why not Gulp?

UI Components

Fusion includes a library of reusable React components.

FAQ

What do the scripts in package.json do?

What command line should I use?

How do I keep my app updated with the latest version of Fusion?

Can you explain the folder structure of the fusion-starter demo app?

Where are the files being served from when I run npm start?

How is Sass being transpiled into CSS and landing in the browser?

I just want an empty starter kit.

Do I have to use Redux?

How do I remove React Router?

How do I deploy this?

Why are test files placed alongside the file under test (instead of centralized)?

How do I debug?

How do I handle images?

How do I kill the process on the command line?

How do I proxy API Requests in Development?

How do I enable CORS on IIS-based Web APIs?

How does the mock API work?

My editor marks my files as edited when I open them!

What do the scripts in package.json do?

Unfortunately, scripts in package.json can't be commented inline because the JSON spec doesn't support comments, so I'm providing info on what each script in package.json does here.

ScriptDescription
remove-demoRemoves the demo application so you can begin development.
startStarts dev webserver, opens the app in your default browser, and lints your code.
buildGenerates a minified build for production and writes it to /build.
testRuns tests (files ending in .spec.js or .test.js) using Jest and outputs results to the command line. Watches all files so tests are re-run upon save.
coverageGenerates a code coverage report
analyzeGenerates an interactive analysis of what's in the production bundle using webpack-bundle-analyzer. This is useful for reducing your bundle size by finding what it's in your bundle.

What command line should I use?

Whatever you like. This kit works on Windows, Mac, and Linux.

How do I keep my app updated with the latest version of Fusion?

Fusion-starter references the Fusion npm package. This package references all other Fusion npm packages inside for convenience. Type npm update to get the latest updates. Here's the list of releases.

Can you explain the folder structure of the fusion-starter demo app?

Note that the files that start with a dot below will be hidden by default in Windows. Here's how to see them. Or type ls -la in Git Bash.

.
β”œβ”€β”€ .editorconfig             # Configures editor rules
β”œβ”€β”€ .gitignore                # Tells git which files to ignore
β”œβ”€β”€ .npmrc                    # Configures npm to save exact by default
β”œβ”€β”€ README.md                 # Project documentation
β”œβ”€β”€ build                     # Folder where the final, production ready compiled version of your app is written (deploy this to production)
β”œβ”€β”€ package.json              # Contains package configuration including a list of 3rd party libraries and utilities and npm scripts
β”œβ”€β”€ public                    # Folder where you will store images, documents, or other other files. Automatically copied to build directory.
β”‚Β Β  β”œβ”€β”€ index.html            # Start page
β”œβ”€β”€ yarn.lock                 # Yarn is an alternative to npm that installs faster and deterministically. This is the config file for Yarn. It's updated each time you run "yarn", which is equivalent to npm install.  
β”œβ”€β”€ src                       # The app's source code
β”‚Β Β  β”œβ”€β”€ actions               # List of distinct actions (called Redux actions) that can occur in the app
β”‚Β Β  β”œβ”€β”€ api                   # Centralized place to make AJAX calls
β”‚Β Β  β”œβ”€β”€ components            # React components
β”‚Β Β  β”œβ”€β”€ index.js              # Entry point for your app
β”‚Β Β  β”œβ”€β”€ reducers              # Redux reducers. Your state is altered here based on actions
β”‚Β Β  β”œβ”€β”€ store                 # Redux store configuration
β”‚Β Β  β”œβ”€β”€ styles                # CSS Styles, typically written in Sass
β”‚Β Β  └── utils                 # Plain old JavaScript (POJOs). Pure logic. No framework specific code here. Think "business layer".

Where are the files being served from when I run npm start?

Webpack serves your app in memory when you run npm start. No physical files are written. However, the web root is /src, so you can reference files under /src in index.html. When the app is built using npm run build, physical files are written to /build.

How is Sass being transpiled into CSS and landing in the browser?

It is handled differently in dev (npm start) vs prod (npm run build)

When you run npm start:

  1. Sass-loader within Webpack uses node-sass to transpile *.scss files CSS.
  2. PostCSS applies Autoprefixer to apply any browser vendor prefixes to the CSS files.
  3. Webpack bundles the compiled CSS into bundle.js.
  4. bundle.js contains code that loads styles into the <head> of index.html via JavaScript. This is why you don't see a stylesheet reference in index.html. In fact, if you disable JavaScript in your browser, you'll see the styles don't load either.

The approach above supports hot reloading, which is great for development. However, it also create a flash of unstyled content on load because you have to wait for the JavaScript to parse and load styles before they're applied. So for the production build, we use a different approach:

When you run npm run build:

  1. Same steps 1 & 2 above as with npm start.
  2. The extract-text-webpack-plugin extracts the compiled CSS into styles.css.
  3. buildHtml.js adds a reference to the stylesheet to the head of index.html.

For both of the above methods, a separate sourcemap is generated for debugging in compatible browsers.

I just want an empty starter kit.

This starter kit includes an example app so you can see how everything hangs together on a real app. When you're done reviewing it, run this to remove the demo app:

npm run remove-demo

Don't want to use Redux? See the next question for some steps on removing Redux.

Do I have to use Redux?

Nope. Redux is useful for applications with more complex data flows. If your app is simple, Redux is overkill. Remove Redux like this:

  1. Run npm run remove-demo
  2. Create a new empty component in /components.
  3. Open src/index.js and call render on the new top level component you created in step 2.

How do I remove React Router?

  1. Delete the following files: src/routes.js
  2. Remove import { Link, IndexLink } from 'react-router'; from top of src/components/App.js, add a reference to src/components/FuelSavingsForm.js, and replace body of (implicit) render with this: <FuelSavingsPage />.

How do I deploy this?

Type npm run build. This will setup the project for production. It does the following:

  • Minifies all JS.
  • Sets NODE_ENV to prod so that React is built in production mode.
  • Places the resulting built project files into /build. (This is the folder you'll deploy and expose to the world).
  • Files in /public are copied to /build automatically. This is a great spot to place index.html, images, etc.
  • Note that by default, Fusion produces a build assuming your app is hosted at the server root. To override this, specify the homepage in your package.json, for example:

"homepage": "http://mywebsite.com/relativepath", Fusion will use this setting to set the proper root path in the generated HTML file.

Why are test files placed alongside the file under test (instead of centralized)?

Streamlined automated testing is a core feature of this starter kit. All tests are placed in files that end in .spec.js. Spec files are placed in the same directory as the file under test. Why?

  • The existence of tests is highly visible. If a corresponding .spec file hasn't been created, it's obvious.
  • Easy to open since they're in the same folder as the file being tested.
  • Easy to create new test files when creating new source files.
  • Short import paths are easy to type and less brittle.
  • As files are moved, it's easy to move tests alongside.

How do I debug?

Since browsers don't currently support all of ES6, Fusion uses Babel to compile ES6 down to ES5. This means the code that runs in the browser looks different than what we wrote. But good news, a sourcemap is generated to enable easy debugging. This means your original JS source will be displayed in your browser's dev console. πŸ‘

Note: When you run npm start, no JS is minified. Why? Because minifying slows the build. So JS is only minified when you run the npm run build script. See more on building for production below.

Also note that no actual physical files are written to the filesystem during the dev build. For performance, all files exist in memory when served from the webpack server.. Physical files are only written when you run npm run build.

Tips for debugging via sourcemaps:

  1. Browsers vary in the way they allow you to view the original source. Chrome automatically shows the original source if a sourcemap is available. Safari, in contrast, will display the minified source and you'll have to cmd+click on a given line to be taken to the original source.
  2. Do not enable serving files from your filesystem in Chrome dev tools. If you do, Chrome (and perhaps other browsers) may not show you the latest version of your code after you make a source code change. Instead you must close the source view tab you were using and reopen it to see the updated source code. It appears Chrome clings to the old sourcemap until you close and reopen the source view tab. To clarify, you don't have to close the actual tab that is displaying the app, just the tab in the console that's displaying the source file that you just changed.
  3. If the latest source isn't displaying the console, force a refresh. Sometimes Chrome seems to hold onto a previous version of the sourcemap which will cause you to see stale code.

How do I handle images?

Via Webpack's file loader. Example:

<img src={require('./assets/images/myImage.jpg')} />

Webpack will then intelligently handle your image for you. For the production build, it will copy the physical file to /build and insert the appropriate path in your image tag.

How do I kill the process on the command line?

Hit Ctrl+C. Or, if you're in Webstorm, click the red X next to the terminal and then hit Alt+F12 to reopen the terminal.

How do I proxy API Requests in Development?

People often serve the front-end React app from the same host and port as their backend implementation. For example, a production setup might look like this after the app is deployed:

/             - static server returns index.html with React app
/todos        - static server returns index.html with React app
/api/todos    - server handles any /api/* requests using the backend implementation

Such setup is not required. However, if you do have a setup like this, it is convenient to write requests like fetch('/api/todos') without worrying about redirecting them to another host or port during development.

To tell the development server to proxy any unknown requests to your API server in development, add a proxy field to your package.json, for example:

  "proxy": "http://localhost:4000",

This way, when you fetch('/api/todos') in development, the development server will recognize that it’s not a static asset, and will proxy your request to http://localhost:4000/api/todos as a fallback. The development server will only attempt to send requests without a text/html accept header to the proxy.

Conveniently, this avoids CORS issues and error messages like this in development:

Fetch API cannot load http://localhost:4000/api/todos. No 'Access-Control-Allow-Origin' header is present on the requested resource. Origin 'http://localhost:3000' is therefore not allowed access. If an opaque response serves your needs, set the request's mode to 'no-cors' to fetch the resource with CORS disabled.

Keep in mind that proxy only has effect in development (with npm start), and it is up to you to ensure that URLs like /api/todos point to the right thing in production. You don’t have to use the /api prefix. Any unrecognized request without a text/html accept header will be redirected to the specified proxy.

Currently the proxy option only handles HTTP requests, and it won’t proxy WebSocket connections. If the proxy option is not flexible enough for you, alternatively you can:

How do I enable CORS on IIS-based Web APIs?

Fusion uses a Node webserver for serving the app on your local machine. This means you need to enable either: 1. Enable a proxy (see above)

or

  1. Enable Cross-origin Resource Sharing (CORS) on any existing IIS hosted APIs so that you can call them from this kit's dev web server.

Here's how to enable CORS:

Create an appSetting called "EnableCors" that is set to "true" for Local and Dev but "false" for all other environments.

<?xml version="1.0" encoding="utf-8"?>
<appSettings>
  <!--Other app settings...-->
  <add key="EnableCors" value="true" />
</appSettings>

You can create a convenience class to reference it:

public static class ConfigurationSettings
{
    public static bool EnableCors = bool.TrueString.Equals(ConfigurationManager.AppSettings["EnableCors"], StringComparison.OrdinalIgnoreCase);
}

Then add this to your API's Global.asax:

protected void Application_BeginRequest(object sender, EventArgs e)
{
    if (ConfigurationSettings.EnableCors)
    {
        EnableCrossOriginRequests(HttpContext.Current.Request);
    }
}

/// <summary>
/// Enables cross-origin requests.
/// </summary>
/// <param name="request">The HTTP request</param>
private void EnableCrossOriginRequests(HttpRequest request)
{
    var origin = request.Headers.Get("Origin");
    
    // Can't set Access-Control-Allow-Origin header without the origin so just return.
    if (origin == null) return;

    var response = HttpContext.Current.Response;
    response.AddHeader("Access-Control-Allow-Origin", origin);
    response.AddHeader("Access-Control-Allow-Credentials", "true");
    if (request.HttpMethod == "OPTIONS")
    {
        response.AddHeader("Access-Control-Allow-Methods", "POST, PUT, DELETE");
        
        // Allow all headers that are requested so that you can use custom headers.
        var requestedHeaders = request.Headers.Get("Access-Control-Request-Headers");
        if (requestedHeaders != null)
        {
            response.AddHeader("Access-Control-Allow-Headers",  requestedHeaders);
        }
        response.AddHeader("Access-Control-Max-Age", "1728000");
        response.End();
    }
}

The example project includes /api/api.js. This file uses Axios to make AJAX calls. It's recommended to centralize your API calls there. See the example in api.js. api.js properly sets the base url based on whether it's running locally, but be sure to add a hosts entry for vinconnect.com (as outlined in the initial machine setup) to assure it works properly.

How does the mock API work?

Here's a blog post that summarizes our mock API set up.

Here's how to get rolling: 1. Create a schema using the JSON Schema Faker format. Save the schema in /src/api/mockDataSchema.js. 2. Fusion will look for the mockDataSchema.js file in src/api. If it finds it, it will generate a mock API using json-server when you run npm start. 3. The mock API will be spun up on localhost:3002, so set the baseUrl in your API calls (located in api.js) accordingly.

An example mockDataSchema.js is included in Fusion-starter. So after running npm start, you can hit the mock api endpoint and see one of the mocks generated by loading localhost:3002/customer in your browser. Every top level object you define in mockDataSchema.js will become its own endpoint and be exposed at localhost:3002/objectName.

My editor marks my files as edited when I open them!

This is the intended behavior of the EditorConfig VS Code plugin when end_of_line is set to lf (as it is in Fusion) and the file is opened in a Windows OS. To fix this behavior in an existing Git repository, run the following commands (warning: this will discard all current changes and revert to the last commit):

git config core.autocrlf false
git rm --cached -r .
git reset --hard

The above commands prevent Git from converting the line endings to the Windows CR/LF on checkout so that EditorConfig's expectation of Unix line endings is met. More info here.