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

interaction-player

v5.8.8-SNAPSHOT

Published

Interaction Player

Downloads

3

Readme

Redux-side-effects driven react boilerplate

This is a very simple example to illustrate the usage of redux-side-effects with react. Together with the pre-configured development tools like eslint, webpack, and testing frameworks like karma, mocha, and various other packages, it can be used as a basis for coding new React/Redux projects.

  1. Usage
  2. Development
  3. Using immutable for redux store state
  4. Passing environment variables to client
  5. Server source code
  6. Client source code
  7. Application URL router
  8. Side-effects
  9. URL history
  10. Quest list
  11. Hot reloading
  12. Clean up webpack configuration
  13. Better side-effects example
  14. Server tests
  15. package.json
  16. List of dependencies

Usage

git clone [email protected]:salsita/redux-boilerplate.git
cd redux-boilerplate
npm install
npm start

Navigate your browser to http://localhost:3000/

Development

npm run start:dev

Navigate your browser to http://localhost:3001/

Using immutable for redux store state

Immutable object is used for the store instead of a plain JavaScript object. This is against the redux specification. Because of this the combineReducers function from redux-side-effects can not be used out of the box.

The use of combineReducers is inevitable for instance for the use of redux-form in the project.

Either the developer writes their own combineReducers function (like the hive project does) or use the provided combineReducers function and relax the constraints from for instance this:

import { fromJS } from 'immutable';
export default fromJS({
  appState: {
    history: null
  },
  effects: []
});

to this:

import { fromJS } from 'immutable';
export default {
  main: fromJS({
    appState: {
      history: null
    },
    effects: []
  })
};

Passing environment variables to client

This is an example from the hive project on how an environment variable is passed to the client (browser-side) code. https://github.com/salsita/hive/blob/develop/web/webpack/webpack.frontend.config.js

const plugins = [
  new webpack.DefinePlugin({
    "process.env": {
      HIVE_LOGIN_PAGE: JSON.stringify(process.env.HIVE_LOGIN_PAGE),
      HIVE_LOGOUT_PAGE: JSON.stringify(process.env.HIVE_LOGOUT_PAGE)
    }
  })
];
...
module.exports = {
  ...
  plugins: plugins
};

On the client side, the variables are then accessed the same way as on the server side:

process.env.HIVE_LOGIN_PAGE;
process.env.HIVE_LOGOUT_PAGE;

Quest list

  • autoprefixer-loader is deprecated. postcss-loader should be used instead.
  • In npm run build-artefacts, the including of the node_modules directory should not be necessary because webpack tracks dependencies via require() statements and it is therefore suppossed to deliver them.
  • In router src/client/Routes.jsx, the default action should be to redirect to the root path (/) instead of displaying the not found page (via the NotFound component. Either check if the router allows it, or perhaps implement the component to dispatch an action (at some point) that will redirect to the root path.

Hot reloading

Hot reloading is not working properly (or at all). It may have to do with the use of devRunner.js, and maybe that the client does not connect back to the webpack-dev-server to listen for refresh events due to not being passed the port number.

Also react-hot-loader is going to be phased out so react-transform-hmr should be used instead. For instance the book SurviveJS - Webpack and React presents a working example.

Clean up webpack configuration

There are currently four webpack configuration files which is way to many. There is a separate configuration file for frontend (the client), the backend (the server), and the development and production environment.

The webpack.backend.config.js and webpack.frontend.config.js are utilized by webpack which is started by the babel-node in the start:dev package.json command (done via devRunner.js).

There should be a common file for both backend and frontend to get rid of the duplicate configuration. Then instead of having four webpack files, use the process.env.npm_lifecycle_event to make selection between a production and a development build.

For instance use this in webpack.conf:

var webpack = require('webpack');
var merge = require('webpack-merge');
const TARGET = process.env.npm_lifecycle_event;
const common = { // shared configuration for production and development builds };
// ...
if (TARGET === 'start') {
  module.exports = merge(common, { // production but not development configuration });  
}
if (TARGET === 'start:dev') {
  module.exports = merge(common, { // development but not production configuration });
}

Where the start and start:dev commands come from package.json

{
  "scripts": {
    "start":     // command to start the production build
    "start:dev": // command start the development build
  }
}

For example it usefull to have the webpack configuration to enable source maps for the development builds but not for the production builds. And also to have the production build source code minified (see -d and -p options) to decrease the network traffic and the browser application load time.

Better side-effects example

Better side-effects example is needed. Something to show handling of success and failure using store reducers when exchanging data with the server.

Server source code

The server src/server/main.js source code listens for http requests on port 3000, or port number configured by the environment variable PORT. It serves static files from the dist/client directory under url path /. It returns JSON data for http get request on path /hello. For every other url path, the server returns the default index.html page.

Client source code

Application URL router

The client router src/client/Router.jsx shows which React component implements which url path. For instance when the user types into a browser a url path that the server does not know and replies with the default index.html file content, the client NotFound React component will render the 404 Page Not Found in the browser.

Side-effects

This a simple example of a side effect from src/client/reducers/testingReducer.js. The side-effect here is the dispatch of the routerBootstrapped action.

export function* applicationMounting(state) {
  yield (dispatch) => {
    dispatch(TestingActions.routerBootstrapped(history));
  };

  return state;
}

export function* routerBootstrapped(state, _history) {
  return state.setIn(['appState', 'history'], _history);
}

URL history

Sometimes it is needed to be able to navigate to different url path from a current one. Regardless of how the url path is constructed, the pushState function of the history object can be used to instruct the browser to change to the given url path. The application router then gets to select the component to render the page based on the new url path. No request to the server is made.

Example from src/client/reducers/testingReducer.js:

import createBrowserHistory from 'history/lib/createBrowserHistory';
const history = createBrowserHistory();

export function* fooClicked(state) {
  history.pushState({}, '/foo');
  return state;
}

export function* barClicked(state) {
  history.pushState({}, '/bar');
  return state;
}

Favicon

Favicon did not always function properly. The trick that made the favicon to be picked up by the browser was to add the graphics in png format src/client/static-resources/favicon.png and to modify the src/client/static-resources/index.html to let the browser to choose from multiple formats. Like this:

<head>
  <link rel="icon" href="favicon.ico" type="image/x-icon" />
  <link rel="icon" href="favicon.png" type="image/png" /> ...
</head>

Server tests

There are two commands to run the same set of backend tests: npm run test_backend and npm run test_backend_cci. The reason is that mocha only allows for one test reporter. The test reporter nyan produces test reports readable by the user. The test reporter mocha-junit-reporter produces test reports for CircleCI (Circle Continuous Integration, hence the _cci suffix). The test reports are written to file test-results.xml.

package.json

If npm install command is to succeed on Windows (without cygwin), then the command must not use any syntax or programs specific to the Unix environment.

The npm run build-artifacts command produces production tarball for CircleCI which deploys it. Therefore it has to be named artifacts, not artefacts (interesting note).

Be prepared to do some configuration tinkering when placing shared source code outside the package.json directory, in order to make the eslint and babel to correctly work with these files.

List of dependencies

This is the list of dependencies taken from the package.json file with some short descriptions.

Development dependencies | Synopsis ------------------------ | -------- autoprefixer-loader | Makes require('./file.css'); to compile and add the CSS to your page. babel, babel-core | Latest (ES2015 and beyond) JavaScript transpiler/compiler. babel-eslint | Allows to lint all valid Babel code with ESLlint. babel-loader | Allows transpiling JavaScript files using Babel and webpack. css-loader | CSS loader for webpack. eslint | Pluggable linting utility for JavaScript and JSX. eslint-config-airbnb | Airbnb JavaScript Style Guide. eslint-loader | ESLint loader for webpack eslint-plugin-import | ESLint plugin with support for linting of ES2015+ (ES6+) import/export syntax. eslint-plugin-react | React specific linting rules for ESLint. file-loader | var url = require("file!./file.png"); // => emits file.png as file in the output directory and returns the public url font-awesome | Scalable vector icons that can instantly be customized with CSS. font-awesome-webpack | Font awesome configuration and loading package for webpack, using font-awesome (Less). karma | Testing environment to make test-driven development easy. karma-chai | Make the Chai assertion library available in Karma. karma-chrome-launcher | x karma-cli | x karma-junit-reporter | x karma-mocha | x karma-nyan-reporter | Nyan Cat style test results reporter. karma-phantomjs-launcher | x karma-webpack | x mocha | JavaScript test framework for Node.js and the browser. mocha-junit-reporter | Produces JUnit-style XML test results. phantomjs | Scripted, headless browser used for automating web page interaction. phantomjs-polyfill | This is a polyfill for function.prototype.bind which is missing from PhantomJS. raw-loader | var fileContent = require("raw!./file.txt"); // => returns file.txt content as string react-hot-loader | Re-render the source code changes automatically in the browser. request | Simple way to make http calls with https and redirect support. single-child | Spawn a single child process which kills itself on restart. sinon | Standalone test spies, stubs and mocks for JavaScript. sinon-chai | Provide sinon for use with the Chai assertion library. source-map-support | Source map support for stack traces in node via the V8 stack trace API. style-loader | Style loader for webpack. url-loader | Url loader for webpack. webpack | Module bundler. The main purpose is to bundle JavaScript files for usage in a browser. webpack-dev-server | Serves a webpack application. Updates the browser on changes.

Dependencies | Synopsis ----------------------- | -------- babel-runtime | Self-contained babel runtime. bluebird | JavaScript promise library. express | Web application framework for Node.js. history | JavaScript library to manage session history in browsers (and testing environments). immutable | Immutable collections for JavaScript. Immutable data cannot be changed once created. invariant | Throw exception if condition is false. less, less-loader | CSS pre-processor. Adds variables, mixins, functions and other techniques. react | JavaScript library for user interfaces. react-document-meta | HTML meta tags for React-based applications. react-dom | Entry point of the DOM-related rendering paths (ReactDOM.render()). react-redux | React bindings for Redux. react-router | Router directs URLs in a single page application to specific handlers. redux | Predictable state container for JavaScript applications. redux-router | Library to keep the router state (current pathname, query, and params) inside the Redux store. redux-side-effects | Redux store implementation with proper interface for asynchronous store operations. serve-favicon | Node.js middleware for serving a favicon. serve-static | Node.js middleware to serve static files from withing a given root directory.