npm package discovery and stats viewer.

Discover Tips

  • General search

    [free text search, go nuts!]

  • Package details

    pkg:[package-name]

  • User packages

    @[username]

Sponsor

Optimize Toolset

I’ve always been into building performant and accessible sites, but lately I’ve been taking it extremely seriously. So much so that I’ve been building a tool to help me optimize and monitor the sites that I build to make sure that I’m making an attempt to offer the best experience to those who visit them. If you’re into performant, accessible and SEO friendly sites, you might like it too! You can check it out at Optimize Toolset.

About

Hi, 👋, I’m Ryan Hefner  and I built this site for me, and you! The goal of this site was to provide an easy way for me to check the stats on my npm packages, both for prioritizing issues and updates, and to give me a little kick in the pants to keep up on stuff.

As I was building it, I realized that I was actually using the tool to build the tool, and figured I might as well put this out there and hopefully others will find it to be a fast and useful way to search and browse npm packages as I have.

If you’re interested in other things I’m working on, follow me on Twitter or check out the open source projects I’ve been publishing on GitHub.

I am also working on a Twitter bot for this site to tweet the most popular, newest, random packages from npm. Please follow that account now and it will start sending out packages soon–ish.

Open Software & Tools

This site wouldn’t be possible without the immense generosity and tireless efforts from the people who make contributions to the world and share their work via open source initiatives. Thank you 🙏

© 2024 – Pkg Stats / Ryan Hefner

create-sbspa

v1.0.0-alpha.2

Published

Scripts for creating Single-page application with React and Spring Boot

Downloads

10

Readme

(React-GraphQL-Spring-boot) Single-page generator

Single-page generator with React frontend and Spring-boot backend supports options to separately generate parts of an application. It uses plop to generate source code from templates. The generator provides boilerplate for creating PWA applications.

This boilerplate provides an array of features that make it different from other frameworks:

  • Webpack configuration - development and production build
  • Jest, Tslint and TypeScript configuration
  • DockerFile for build automation
  • Redux, Saga configuration - async Saga and Reducer injection
  • GraphQL configuration
  • Checkstyle and FindBugs configuration
  • Gradle build configuration for both frontend and backend
  • Interactive generator console with variety of options
  • Iterative updates with "modify" option
  • PWA configuration
  • Sample components and examples of usage
  • Plug&Play configuration

Tool is build for easy generation of single-page applications with usage of best practices in web development. Provides better maintenance, testing, cooperation and deployment.

Getting Started

Install yarn.

npm install -g yarn

Install create-sbspa tool.

npm install -g create-sbspa

Prerequisites

Generating

After installing create-sbspa tool run

create-sbspa

Options:

  • All - Generates Frontend and Backend with Docker, GraphQL configuration.
  • Frontend - Generates Frontend.
  • Backend - Generates Backend without GraphQL configuration.
  • Docker configuration - Generates Docker configuration for Frontend and Backend.
  • GraphQL configuration - Generates GraphQL configuration with example

Build and Run application

Application uses gradle automation build and deployment tool. Project modules are defined in settings.gradle and in build.gradle files.

Frontend (in <frontend_folder> folder)

Build application DEV

yarn install && yarn build:dev

Build application PROD

yarn install && yarn build

Gradle:

gradle build

Run application in DEV mode

yarn start:dev

Run application in PROD mode

yarn start

Gradle:

gradle runWeb

Available at localhost:3000.

Backend (in <backend_folder> folder)

Build application

gradle build

Run application

gradle runApi

Available at localhost:8080.

GraphQL console is available at localhost:8080/graphiql.

Running the tests

Frontend

Run tests with yarn

yarn run test

Run tests on changed files

yarn run test:changed

Run tests with coverage

yarn run test:coverage

Update tests

yarn run test:update

Backend

Run checkstyle (build/reports/checkstyle.html)

gradle checkstyleMain

Run findbugs (build/reports/findbugs.html)

gradle findbugsMain

Coding style tests

  • Coding styles for Backend are defined in <backend_folder>/config
  • Coding styles for Frontend are defined in <fronted_folder>/tslint.json

Check tests for backend and frontend for more information.

Hooks

Frontend application uses prepush and precommit hooks.

  • Prepush is invoked before push to central repository with command:
yarn run test:coverage

Coverage threshold can be set in jest.config.js.

  • Precommit is invoked before commit. Calls lint (static analyzer) to check coding styles.
yarn run lint-staged

Static analyzer can be modified in tslint.json.

Deployment

Deploy frontend or backend with provided docker configuration. In root frontend or backend directory run

docker build . -t <name>:<version>

Modules

Root container .tsx (<frontend_folder>/src/modules)

Main application class with Async route definition. Each page (container/component) can be asynchronously loaded with support of Webpack chunks.

Route definition: SamplePage route with root component in "./shared/components/ReplaceMeComponent".

Important: path is made from Router.tsx component.

export const routes = {
  samplePage: () =>
    // @ts-ignore
    lazy(() =>
      import(/* webpackChunkName: "SamplePage" */ "./shared/components/ReplaceMeComponent"),
    ),
};

Routes are evaluated in Router.tsx class (modules/shared/components/Router.tsx).

You can freely change loading component and other properties of the DynamicRouter component.

Redux and Sagas

Generator provides support for redux and sagas with async injection feature.

Store

Store is defined in common/store/store.tsx. It containes store setup with reducers and sagas. Also includes Redux devtools extension for development.

You can add your reducer directly to store or inject it asynchronously.

Adding directly to store

Create your reducer myReducer.tsx


import {combineActions, handleActions} from "redux-actions";

const defaultState = "";

const reducer = handleActions(
  {
    ["MY_REDUCER_ACTION"]:
      (state, {payload: {value}}) => value,
  },
  defaultState,
);
export default reducer;

Add it to reducerRegistry reducerRegistry.tsx


import myReducer from "./reducers/myReducer"

...

 public getReducers() {
    return {
      myReducer: myReducer,
      ...this._reducers};
  }
  
...

Adding asynchronously to store

Reducers and sagas can by injected asynchronously with implemented helper function in common/store/helpers.tsx.

Example usage of async reducer and saga

Create an app container

import {compose} from "redux";
import * as React from "react";
import {connect} from "react-redux";
import reducer from "./reducers/myReducer";
import {withInjectedReducersAndSagas} from "../../common/store/helpers";
import saga from "./sagas/mySaga";
import {myReducerAction} from "./actions/myActions";

const ExampleContainer = ({value, myReducerAction}) =><div onClick={()=>myReducerAction("click")}>{value}My container!</div>

export default compose(
	withInjectedReducersAndSagas({
		reducers:[
			{
				key: "MY_REDUCER",
				value: reducer
			}
		],
		sagas:[
			{
				key: "MY_SAGA",
				value: saga
			}
		]
	}),
	// after async injection u can easily connect to store
	connect(
		(state)=>({
				value: state["MY_REDUCER"].value
			}), 
		(dispatch)=>({
				myReducerAction: value => dispatch(myReducerAction(value))
			})
        )
	)(ExampleContainer);

Reducer definition ./reducers/myReducer

import {combineActions, handleActions} from "redux-actions";

const defaultState = "";

const reducer = handleActions(
    {
        ["MY_REDUCER/MY_REDUCER_ACTION"]:
            (state, {payload: {value}}) => value,
    },
    defaultState,
);
export default reducer;

Saga definition ./sagas/mySaga

import {takeEvery} from "redux-saga/effects";

const watchAction = function* watchAction() {
  yield;
};

function* rootSaga() {
  yield takeEvery("MY_REDUCER/MY_REDUCER_ACTION", watchAction);
}

export default rootSaga;

Actions definition ./actions/myActions

export const {
  myReducer: {myReducerAction},
} = createActions({
  ["MY_REDUCER"]: {
    [`MY_REDUCER_ACTION`]: value => ({value}),
  },
});

GraphQL modules (<backend_folder>/)

Resolvers (/resolver)

Resolvers are used for postprocessing of model fields. For blog we can acquire data, which is postprocessing of author object.

DAO (/dao)

Each DAO object contains functions called from Query.

Schema (/resources/graphql/*.graphqls)

Schema definition with supporoted queries.

Built With

Authors

License

This project is licensed under the MIT License.

Examples

Toreator - Single-page application with GraphQL proxy for searching IP addresses in TOR network.