Giter Site home page Giter Site logo

redux-injectors's Introduction

react boilerplate banner


Start your next react project in seconds
A highly scalable, offline-first foundation with the best DX and a focus on performance and best practices


Created by Max Stoiber and maintained with ❤️ by an amazing team of developers.

Features

Quick scaffolding
Create components, containers, routes, selectors and sagas - and their tests - right from the CLI!
Instant feedback
Enjoy the best DX (Developer eXperience) and code your app at the speed of thought! Your saved changes to the CSS and JS are reflected instantaneously without refreshing the page. Preserve application state even when you update something in the underlying code!
Predictable state management
Unidirectional data flow allows for change logging and time travel debugging.
Next generation JavaScript
Use template strings, object destructuring, arrow functions, JSX syntax and more.
Next generation CSS
Write composable CSS that's co-located with your components for complete modularity. Unique generated class names keep the specificity low while eliminating style clashes. Ship only the styles that are on the page for the best performance.
Industry-standard routing
It's natural to want to add pages (e.g. `/about`) to your application, and routing makes this possible.
Industry-standard i18n internationalization support
Scalable apps need to support multiple languages, easily add and support multiple languages with `react-intl`.
Offline-first
The next frontier in performant web apps: availability without a network connection from the instant your users load the app.
Static code analysis
Focus on writing new features without worrying about formatting or code quality. With the right editor setup, your code will automatically be formatted and linted as you work.
SEO
We support SEO (document head tags management) for search engines that support indexing of JavaScript content. (eg. Google)

But wait... there's more!

  • The best test setup: Automatically guarantee code quality and non-breaking changes. (Seen a react app with 100% test coverage before?)
  • Native web app: Your app's new home? The home screen of your users' phones.
  • The fastest fonts: Say goodbye to vacant text.
  • Stay fast: Profile your app's performance from the comfort of your command line!
  • Catch problems: AppVeyor and TravisCI setups included by default, so your tests get run automatically on Windows and Unix.

There’s also a fantastic video on how to structure your React.js apps with scalability in mind. It provides rationale for the majority of boilerplate's design decisions.

Keywords: React.js, Redux, Hot Reloading, ESNext, Babel, react-router, Offline First, ServiceWorker, styled-components, redux-saga, FontFaceObserver

Quick start

  1. Make sure that you have Node.js v8.15.1 and npm v5 or above installed.
  2. Clone this repo using git clone --depth=1 https://github.com/react-boilerplate/react-boilerplate.git <YOUR_PROJECT_NAME>
  3. Move to the appropriate directory: cd <YOUR_PROJECT_NAME>.
  4. Run npm run setup in order to install dependencies and clean the git repo.
    At this point you can run npm start to see the example app at http://localhost:3000.
  5. Run npm run clean to delete the example app.

Now you're ready to rumble!

Please note that this boilerplate is production-ready and not meant for beginners! If you're just starting out with react or redux, please refer to https://github.com/petehunt/react-howto instead. If you want a solid, battle-tested base to build your next product upon and have some experience with react, this is the perfect start for you.

Documentation

Contributors

Thanks goes to these wonderful people (emoji key):

Max Stoiber
Max Stoiber

💻 📖 🤔 👀 ⚠️
Julien Benchetrit
Julien Benchetrit

💻 💬 📖 👀 🚧
Sara Federico
Sara Federico

💻 👀 💬 📖 🚧
Justin Greenberg
Justin Greenberg

💻 👀
Jon Winn
Jon Winn

💻 👀
Johan Meester
Johan Meester

💻 ⚠️ 📖
Yaroslav Kiliba
Yaroslav Kiliba

💻
Glen Ihrig
Glen Ihrig

💻
Somasundaram Ayyappan
Somasundaram Ayyappan

💻
Oliver Turner
Oliver Turner

💻
Samuel Sharpe
Samuel Sharpe

💻
Mihir Karandikar
Mihir Karandikar

💻
Vaibhav Verma
Vaibhav Verma

💻
Sébastien Dubois
Sébastien Dubois

💻
Chainarong Tangsurakit
Chainarong Tangsurakit

💻
Amila Welihinda
Amila Welihinda

💻

This project follows the all-contributors specification. Contributions of any kind welcome!

Supporters

This project would not be possible without the support of these amazing folks. Become a sponsor to get your company in front of thousands of engaged react developers and help us out!


License

This project is licensed under the MIT license, Copyright (c) 2019 Maximilian Stoiber. For more information see LICENSE.md.

redux-injectors's People

Contributors

benlorantfy avatar frozenkiwi avatar goranurukalo avatar julienben avatar mrfratello avatar partounian 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

redux-injectors's Issues

incorrect typing for function `createManager` ?

According to the source code of createManager, we can not pass reducer and saga in the parameter options:

    const isReducerInjected = reducer // <-- check
      ? useInjectReducer({ key, reducer })
      : true;

    const isSagaInjected = saga // <-- check
      ? useInjectSaga({ key, saga }) 
      : true;

But in typing, these properties are required:

export function createManager(options: { name: string, key: string, saga: Saga, /* <- required */ reducer: Reducer  /* <- required */  }): ...;

What is the mistake? in typing or implementation?

[React Testing Library] Integration tests with preloadedState

We are doing integration tests with our react app but couldn't create the store with preloadedState

Unexpected key "injectedSlice" found in preloadedState argument passed to createStore. Expected to find one of the known reducer keys instead: ....

As I understand because we don't initialize the reducer when configure the store so it could not understand in test. Maybe I have to create another version of configureStore for testing only?

Feature Request: useInjectSagas ie useInjectSaga for multiple sagas

Given a functional component, I would like the ability to use multiple sagas.

An example of this may be a settings page where button1 dispatches action1 and button2 dispatches action2. These actions would correspond to different sagas.

Alternatively, what is another way of doing this? Would it be the code below?

export function* settingsPageSaga() {
  yield takeLatest(actions.action1.type, functionForAction1);
  yield takeLatest(actions.action2.type, functionForAction2);
}

Persist state of redux

Using redux-injectors makes it imposible to persist the state because the injectorsEnhancer regularly replaces the rootReducer with a new one - and only the initial one of those is persisted. Am I wrong? How can we persist the state of redux?
image
image

How to create reducer with Immer ?

Hi @BenLorantfy !

When I tried to create a reducer with Immer https://github.com/immerjs/immer.

const reducer = (state = initialState, action) => produce(state, draft => { switch (action.type) { case SIGNUP_REQUEST: draft.isFetching = true; break; } })

I got this error :
injectReducer: Expected reducer to be a reducer function

I think it shouldn't get the error.

Please help, thanks you.

Feature request: reducer ejection

Hi

The problem I am working on is making apps work under micro frontend architecture. One challenge I am working on is I like to completely reject a reducer from the Redux store when users leave the page aka componentWillUnmount

I've done the PoC as following below

// injectReducer.js
const useInjectReducer = ({ key, reducer }) => {
  const store = useStore();
  const [isInjected, setIsInjected] = React.useState(false);

  React.useLayoutEffect(() => {
    getInjectors(store).injectReducer(key, reducer);
    setIsInjected(true);

    return () => {
      // To remove a reducer from Redux store
      getInjectors(store).rejectReducer(key);
    };
  }, []);

  return isInjected;
};
// reducerInjectors.js

export function ejectReducerFactory(store, isValid) {
  return function ejectReducer(key, reducer) {
    if (!isValid) checkStore(store)
    
   if (
      !Reflect.has(store.injectedReducers, key)
    )
      return;
      
     delete store.injectedReducers[key]
     store.replaceReducer(store.createReducer(store.injectedReducers));
  };
}
export default function getInjectors(store) {
  checkStore(store);

  return {
    injectReducer: injectReducerFactory(store, true),
    ejectReducer: ejectReducerFactory(store, true),
  };
}
  

Do you think, does this worth a pull request?

Typescript support?

I know RBP isn't a TS project, but there isn't any reason RI couldn't go that route (rather than building types).

I'd be happy to port the code.

Why I care - I'm using RBP on TS monorepo - I'd already split out the injectors similar to this but would prefer to use this project if possible.

useInjectReducer clears the state

I have two slices in my store. Each has one reducer which I inject at the root of my react app.

notificationSlice.ts

import { AnyAction, createSlice, PayloadAction } from '@reduxjs/toolkit';

export interface notificationFormat {
  type: 'system' | 'confirmation' | 'message' | 'chat';
  title: string;
  description: string;
  avatarSrc?: string;
  lessonID?: number;
}

export interface notificationsState {
  notifications: notificationFormat[];
}

const initialState: notificationsState = {
  notifications: [],
};

export const notificationsSlice = createSlice({
  name: 'notifications',
  initialState,
  reducers: {
    addNotification: (state, action: PayloadAction<notificationFormat>) => {
      state.notifications.push(action.payload);
    },
    removeNotification: (state, action: PayloadAction<number>) => {
      delete state.notifications[action.payload];
    },
    clear: (state, action: AnyAction) => {
      state.notifications.length = 0;
    },
    setNotifications: (state, action: PayloadAction<notificationFormat[]>) => {
      state.notifications = action.payload;
    },
  },
});

export const { addNotification, removeNotification, setNotifications, clear } =
  notificationsSlice.actions;

export default notificationsSlice.reducer;

accountSlice.ts

import { AnyAction, createSlice, PayloadAction } from '@reduxjs/toolkit';

export interface accountState {
  email: string;
  password: string;
  checked: boolean;
}

const initialState: accountState = {
  email: '',
  password: '',
  checked: false,
};

export const accountSlice = createSlice({
  name: 'account',
  initialState,
  reducers: {
    setEmail: (state, action: PayloadAction<string>) => {
      state.email = action.payload;
    },
    setPassword: (state, action: PayloadAction<string>) => {
      state.password = action.payload;
    },
    setChecked: (state, action: PayloadAction<boolean>) => {
      state.checked = action.payload;
    },
    logout: (state, action: AnyAction) => {
      state.email = '';
      state.password = '';
      state.checked = false;
    },
  },
});

export const { setEmail, setPassword, setChecked, logout } =
  accountSlice.actions;

export default accountSlice.reducer;

I want my store to be persistent so I save every change to local storage and load it back when the website gets refreshed.

However, every time my website gets refreshed and the reducers get injected again, it clears half of my state.
If I inject the notificationSlice reducer first -> it clears the accountSlice. And vice versa.

When I tried debugging it I found that just after the refresh the state loads just fine (from the local storage) but it breaks when the reducers are injected.

How to fix this?

Not able to get the store value

I am trying to get the initial state values from the Store directly using

const store = createStore(reducer, composeEnhancers(
...
));
store.getState()

I am getting undefined

Change in the order of Hooks when injecting a reducer, calling it, and selector-ing it withing a single component

I suspect this is an issue with react itself rather than with redux-injectors, but posting here first as it's the first link in the chain.

I have a component that injects it's reducers and sagas, calls the saga to fetch from an API, and then uses the returned data all within the same component. When I do this, I get the following error:

Warning; React has detected a change in the order of hooks called by <Component>

The code did look like this:

const HelpDocs = () => {
   // useReducer & useSaga work together to populate state.documents
  usePrismic();
  // dispatcher to trigger saga
  const actions = usePrismicActions(); 
   // fetch said documents from redux
  const docs = useSelector((s: ApplicationRootState) => s.documents);
  // onLoad, trigger the actions to fetch the doc's from API
  useEffect(() => {
    actions.fetchFaqs();
  }, []);

I fixed it by pulling the useReducer etc bit out into a wrapping component:

export const HelpDocs = (props: RouteComponentProps) => {
  usePrismic();
  return <HelpDocsInternal {...props} /> // The rest of the code
}

As I said, I suspect this isn't in your domain, but you know this project better than I do so perhaps it might ring some bells before posting in react itself.

installing redux-injectors without --force or --legacy-peer-deps

I am trying to work with redux saga (React 18.2.0), I configured the store, the reducer and the request, so to do the API call I decided to inject the reducer and saga using useInjectReducer and useInjectSaga from redux-injectors :

import { useInjectReducer, useInjectSaga } from 'redux-injectors';

the problem is that when I try to install redux-injectors I got this error:

npm install redux-injectors
npm WARN config global `--global`, `--local` are deprecated. Use `--location=global` instead.
npm ERR! code ERESOLVE
npm ERR! ERESOLVE unable to resolve dependency tree
npm ERR!
npm ERR! While resolving: [email protected]
npm ERR! Found: [email protected]
npm ERR! node_modules/react
npm ERR!   react@"^18.2.0" from the root project
npm ERR!
npm ERR! Could not resolve dependency:
npm ERR! peer react@"^16.6.0 || ^17.0.0" from [email protected]
npm ERR! node_modules/redux-injectors
npm ERR!   redux-injectors@"*" from the root project
npm ERR!
npm ERR! Fix the upstream dependency conflict, or retry
npm ERR! this command with --force, or --legacy-peer-deps
npm ERR! to accept an incorrect (and potentially broken) dependency resolution.
npm ERR!
npm ERR! See C:\Users\Admin\AppData\Local\npm-cache\eresolve-report.txt for a full report.

npm ERR! A complete log of this run can be found in:
npm ERR!     C:\Users\Admin\AppData\Local\npm-cache\_logs\2022-09-25T09_19_46_303Z-debug-0.log

I locked up for the solution, and I found that I need to add --legacy-peer-deps or --force while installing, this solution works fine in my local machine, but it will not work at the dev environment because at this environment we install dependencies only using npm install

Typing issues with latest @reduxjs/toolkit

Updating to @reduxjs/toolkit 1.6.0 gives the following type errors with the following code :

import { configureStore, getDefaultMiddleware } from '@reduxjs/toolkit'
import { createInjectorsEnhancer } from 'redux-injectors'

// ...

  const enhancers = [
    createInjectorsEnhancer({
      createReducer,
      runSaga,
    }),
  ]

  const store = configureStore({
    reducer: createReducer(),
    middleware: [...getDefaultMiddleware(), ...middlewares],
    devTools:
      /* istanbul ignore next line */
      process.env.NODE_ENV !== 'production' || process.env.PUBLIC_URL.length > 0,
    enhancers,
    preloadedState: state,
  })
Type 'StoreEnhancer<{}, {}>[]' is not assignable to type 'StoreEnhancer<{}, {}>[] | ConfigureEnhancersCallback | undefined'.
  Type 'import("/home/esya/Git/oasis-wallet/node_modules/redux/index").StoreEnhancer<{}, {}>[]' is not assignable to type 'import("/home/esya/Git/oasis-wallet/node_modules/@reduxjs/toolkit/node_modules/redux/index").StoreEnhancer<{}, {}>[]'.
    Type 'import("/home/esya/Git/oasis-wallet/node_modules/redux/index").StoreEnhancer<{}, {}>' is not assignable to type 'import("/home/esya/Git/oasis-wallet/node_modules/@reduxjs/toolkit/node_modules/redux/index").StoreEnhancer<{}, {}>'.
      Types of parameters 'next' and 'next' are incompatible.
        Types of parameters 'preloadedState' and 'preloadedState' are incompatible.
          Type 'import("/home/esya/Git/oasis-wallet/node_modules/redux/index").PreloadedState<S> | undefined' is not assignable to type 'import("/home/esya/Git/oasis-wallet/node_modules/@reduxjs/toolkit/node_modules/redux/index").PreloadedState<S> | undefined'.
            Type 'PreloadedState<S>' is not assignable to type 'PreloadedState<S> | undefined'.
              Type '(S extends CombinedState<infer S1> ? { [K in keyof S1]?: (S1[K] extends object ? PreloadedState<S1[K]> : S1[K]) | undefined; } : never) | { [K in keyof S]: S[K] extends object ? PreloadedState<...> : S[K]; }' is not assignable to type 'PreloadedState<S> | undefined'.
                Type 'S extends CombinedState<infer S1> ? { [K in keyof S1]?: (S1[K] extends object ? PreloadedState<S1[K]> : S1[K]) | undefined; } : never' is not assignable to type 'PreloadedState<S> | undefined'.
                  Type '{}' is not assignable to type 'PreloadedState<S>'.
                    Type 'S extends CombinedState<infer S1> ? { [K in keyof S1]?: (S1[K] extends object ? PreloadedState<S1[K]> : S1[K]) | undefined; } : never' is not assignable to type 'PreloadedState<S>'.
                      Type 'import("/home/esya/Git/oasis-wallet/node_modules/redux/index").PreloadedState<S>' is not assignable to type 'import("/home/esya/Git/oasis-wallet/node_modules/@reduxjs/toolkit/node_modules/redux/index").PreloadedState<S>'.
                        Type '(S extends CombinedState<infer S1> ? { [K in keyof S1]?: (S1[K] extends object ? PreloadedState<S1[K]> : S1[K]) | undefined; } : never) | { [K in keyof S]: S[K] extends object ? PreloadedState<...> : S[K]; }' is not assignable to type 'PreloadedState<S>'.
                          Type 'S extends CombinedState<infer S1> ? { [K in keyof S1]?: (S1[K] extends object ? PreloadedState<S1[K]> : S1[K]) | undefined; } : never' is not assignable to type 'PreloadedState<S>'.
                            Type '{}' is not assignable to type 'PreloadedState<S>'.ts(2322)

Feature Request: Ability to change the saga registered on a component using Hooks

This one is probably bit of an edge case, so let me know if you're not interested in supporting it.

I store a dynamic map of user accounts in Redux, and the user has the ability to switch between accounts. The accounts might have long-running actions, and they should keep running when the user switches away. My components are written to be agnostic to all this - from the POV of a component there is only one account, the one they are acting on. When I switch to a new account, I want a component to be able to start the saga's associated with that account.

My hook looks like this:

export const useAccountApi = (address: string) => {
  const { actions } = getAccountReducer(address);
  useInjectSaga({ key: address, saga: buildSagas(address) });
  const dispatch = useDispatch();
  return bindActions(actions, dispatch);
}

This works the first time a user loads an account, however if the user switches accounts no new saga is injected, because useInjectSaga does not test the key, it uses a boolean to test whether this has been registered already:

const isInjected = React.useRef(false);

If you have a static list of saga's, this works fine. However, in my case I needed to test the key to see if the saga had been previously injected:

FrozenKiwi@9efd162

So... I feel like this request may be counter to the philosophy of hooks in general, but I haven't been able to figure out how to do it cleaner. I have a constant number of hooks, but I may start a different saga if I switch account (and remain on the same page).

If it is (counter to your philosophy) do you have any advice on how to do it cleaner? Ideally, without re-architecting my application? If not, would you accept this as a PR?

update to react 17

npm ERR! Could not resolve dependency:
npm ERR! peer react@"^16.6.0" from [email protected]
npm ERR! node_modules/redux-injectors
npm ERR! redux-injectors@"*" from the root project

had to do this.. also react-boilerplate-cra still on version 16
npm i redux-injectors --force

React 16.13 throws a warning when "nesting" useInjectReducer calls

After upgrading to React 16.13, we started getting this warning in many places:

image

More info about it in the 16.13 announcement post.

Here's how it happens in our case:

  • Have ParentContainer with useInjectReducer
  • Have ChildContainer with useInjectReducer
  • When ChildContainer's useInjectReducer is called, the warning appears.

This happens because calling useInjectReducer calls store.replaceReducer synchronously during the render of the ChildContainer.

From what I understand, we're not technically updating the state of a component during the render of another component but we are updating the ReactReduxContext - which contains the store and is also consumed by ParentContainer via useStore inside useInjectReducer - so that must be enough to trigger the warning.

The suggestion by the React team is to "wrap the setState call into useEffect".

Up until September of last year, this is exactly how useInjectReducer worked: injection happened inside an effect. However, doing the injection inside an effect caused a different issue: we couldn't guarantee that the reducer or saga was always injected before a relevant action is dispatched. (Discussed in RBP here.)

Does anyone have any thoughts or suggestions regarding how we could fix this?

Typescript error: implicit "any"

ERROR in C:/src/TheCoin/node_modules/redux-injectors/index.d.ts(16,17):
TS7010: 'forceReducerReload', which lacks return-type annotation, implicitly has an 'any' return type.

Sure enough, what I have is:
export function forceReducerReload(store: {});

I'd really like to have this compiler option turned on, as it can catch quite a few genuine bugs, but this issue is preventing me at the moment.

I'd be happy to open a PR, but I don't see where your TS types come from (only JS in this repo?)

How do I clear state on logout

I have the same problem as addressed in the following question.
https://stackoverflow.com/questions/35622588/how-to-reset-the-state-of-a-redux-store

I need to clear all the redux state on logout, but since my logout is on a separate global slice it can only affect the global slice and not other redux states. How do I clear all other states calling an action from global state?

Here's how I combine reducers:

import { combineReducers } from '@reduxjs/toolkit';

export function createReducer(injectedReducers = {}) {
  if (Object.keys(injectedReducers).length === 0) {
    return state => state;
  }
  return combineReducers({
    ...injectedReducers
  });
}

my globalReducer:

import { createSlice } from '@reduxjs/toolkit';

const initialState = {
  loading: false
};

const globalSlice = createSlice({
  name: 'global',
  initialState,
  reducers: {
    logout(state) {
      return state;
    }
  }
});

export const { actions, reducer, name: sliceKey } = globalSlice;

my store/index.js

import { configureStore, getDefaultMiddleware } from '@reduxjs/toolkit';
import { createInjectorsEnhancer, forceReducerReload } from 'redux-injectors';
import createSagaMiddleware from 'redux-saga';
import { createReducer } from './reducers';

function configureAppStore() {
  const reduxSagaMonitorOptions = {
    onError: (error, { sagaStack }) => {
      // console.log(error, sagaStack);
    }
  };
  const sagaMiddleware = createSagaMiddleware(reduxSagaMonitorOptions);
  const { run: runSaga } = sagaMiddleware;

  // Create the store with saga middleware
  const middlewares = [sagaMiddleware];

  const enhancers = [
    createInjectorsEnhancer({
      createReducer,
      runSaga
    })
  ];

  const store = configureStore({
    reducer: createReducer(),
    middleware: [
      ...getDefaultMiddleware({
        serializableCheck: {
          ignoredActionPaths: ['payload.history']
        },
        immutableCheck: false
      }),
      ...middlewares
    ],
    devTools:
      process.env.NODE_ENV !== 'production'
      || process.env.PUBLIC_URL.length > 0,
    enhancers
  });

  // Make reducers hot reloadable, see http://mxs.is/googmo
  if (module.hot) {
    module.hot.accept('./reducers', () => {
      forceReducerReload(store);
    });
  }

  return store;
}

export const store = configureAppStore();

Unmet peer dependencies with Redux 8

When trying to create a new app with redux v8 installed I get the following error:

npm ERR! Found: react-redux@8.0.4
npm ERR! node_modules/react-redux
npm ERR!   react-redux@"8.0.4" from the root project
npm ERR!
npm ERR! Could not resolve dependency:
npm ERR! peer react-redux@"^7.1.0" from redux-injectors@2.1.0
npm ERR! node_modules/redux-injectors
npm ERR!   redux-injectors@"2.1.0" from the root project

I'm wondering if this is tangentially related to #34 - If I use --force or --legacy-peer-deps the install does finish, and the app does run and work without issue.

I think this could easily be fixed by adding redux 8 as a peer dep, but i know v7 to v8 is a major version bump

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.