FormidableLabs / redux-little-router

A tiny router for Redux that lets the URL do the talking.
MIT License
1.04k stars 114 forks source link

Usage without React #176

Open eirslett opened 7 years ago

eirslett commented 7 years ago

Believe it or not, some people use Redux without using React. (One example case is with brownfield projects)

Could the setup of this project be refactored a bit, so that the React-specific helpers are optional? I'm using Webpack, and it complains that it needs the react-redux dependency, which is not relevant if you're not using React, so it's just extra bloat. (And then again, maybe React-redux depends on React so suddenly you're sitting there with the whole React dependency just for a little redux router...)

Either

import { littleRouterStuff... } from 'redux-little-router';
import { reactStuff... } from 'redux-little-router/react';

(two entry points in the npm package)

or

import { littleRouterStuff... } from 'redux-little-router';
import { reactStuff... } from 'redux-little-router-react';

(two npm packages)

Also, if the import/export statements aren't compiled, but kept in the output bundle (maybe with a jsnext:main/module flag, Webpack and Rollup might be able to tree-shake away the unneeded code. (I'm not sure whether it would be able to tree-shake away the react-redux dependency though)

tptee commented 7 years ago

Hey @eirslett, I'm actively considering this for the next release–will let you know if/how we decide to make a split 👍

adriaanbalt commented 6 years ago

Same 👍 First off, thank you for building this because it's pretty much exactly what I've been looking for.

I am building a Vanilla JS project with Redux state management; no React view layer is required since my views are Vanilla. I too, like the premise of your article for building this router, would like to remove the router's dependency on the view thereby storing the URL within the Redux state. But since this router requires React I'm back to bundling React into my build to support Fragment and Link, both of which I will not use.

Can you recommend a quick way to decouple these?

husman commented 6 years ago

@tptee is there a timeline for the next release?

stefvhuynh commented 6 years ago

This can be accomplished in the same way we handle immutable here: https://github.com/FormidableLabs/redux-little-router/commit/dee80a7c79e6923414f3c3feb8a9077d71f2cbb6

Ideally, we would remove the recompose dependency so that we don't have to conditionally import that as well (since it relies on react).

axelpale commented 6 years ago

Just emphasizing the issue: The following is not what one wants to see when needing a modern router while avoiding React:

$ npm install --save redux-little-router
npm WARN redux-little-router@15.1.0 requires a peer of react@^0.14.0 || ^15.0.0-0 || ^16.0.0-0 but 
none is installed. You must install peer dependencies yourself.
npm WARN redux-little-router@15.1.0 requires a peer of react-dom@^0.14.0 || ^15.0.0-0 || ^16.0.0-0 
but none is installed. You must install peer dependencies yourself.
npm WARN redux-little-router@15.1.0 requires a peer of react-redux@^4.0.0 || ^5.0.0 but none is 
installed. You must install peer dependencies yourself.
npm WARN recompose@0.26.0 requires a peer of react@^0.14.0 || ^15.0.0 || ^16.0.0 but none is 
installed. You must install peer dependencies yourself.

+ redux-little-router@15.1.0
added 11 packages from 15 contributors in 23.649s

In our case React is out of the question because we depend heavily on another lib that already implements a virtual DOM.

ryan-roemer commented 6 years ago

We would definitely consider a pull request modeled after what we did for immutable. Thanks!

Check out the files in ‘src/immutable’ for something analogous to what I think the end solution would look like.

ryan-roemer commented 6 years ago

Oh, and to the original issue, we do now provide package.json:module entrypoints with native import|exports preserved. See, e.g. https://unpkg.com/redux-little-router@15.1.0/es/

So this issue presently means "you get some warnings" and is not something more serious like "your frontend bundle is bigger than it should be" if you are using a modern bundler like webpack@4+ or rollup.

axelpale commented 6 years ago

For you who are looking for a short-term solution, here is one that builds on the tip about entrypoints by @ryan-roemer... Okay, so first I had:

var redux = require('redux')
var rr = require('redux-little-router')
...
var router = rr.routerForBrowser({
  routes: routes
})
...
var initialLocation = store.getState().router
if (initialLocation) {
  store.dispatch(rr.initializeCurrentLocation(initialLocation))
}

Not working. Without react my webpack build fails with six errors similar to:

ERROR in ./node_modules/recompose/withContext.js
Module not found: Error: Can't resolve 'react' in '/Users/foo/bar/node_modules/recompose'

But when I change the code to use the entrypoints the following works:

var redux = require('redux')
var routerForBrowser = require('redux-little-router/es/environment/browser-router').default
var routerActions = require('redux-little-router/es/actions')
...
var router = routerForBrowser({
  routes: routes
})
...
var initialLocation = store.getState().router
if (initialLocation) {
  store.dispatch(routerActions.initializeCurrentLocation(initialLocation))
}

Not pretty, not intuitive, and will break if the internal file structure of redux-little-router changes. But react is avoided, wohoo \o/