🚀 Ultimate universal starter with lazy-loading, SSR and i18n. [not maintained]
/docs
folder. Docs live only in README.md
.chokidar
watcher closing, when it's unnecessary to continue watchingchokidar
from server/i18n
. Import i18n locals directly in server-side code.<Root>
dispatches APPLICATION_INIT
only once. Fix react-tree-walker
's side-effect with multiple APPLICATION_INIT
dispatching.Removed anything related to auth:
copy-webpack-plugin
webpack-node-externals
favicons-webpack-plugin
. It's a great, but unmaintained plugin.INSPECT_ENABLED
, HOST
/components
dir. Remove nested dirs from /components
.styled-components
for `<App />: "CSS classes over new styled components".<Sidebar>
is opened according to the state; then it should be opened for a user.". The previous reducer didn't follow this logic as required.(
Awral
is deprecated. "Composition over configuration.")
The project's Webpack config now is slightly close to Razzle's config. Next step - full integration with Razzle. But currently, it's not possible. Razzle doesn't have a good plugin system to accomplish that, and Razzle still isn't stable enough. Next.js integration seems more likely.
Other features/bugs in CHANGELOG.md
react-async-component
master
But there is one problem: tiny-universal-skeleton
is experimental and not so stable as I've thought before. So it's recommended to clean eslint errors (i.e. remove all eslint errors before quit from npm run dev
)
Yes, flow was added, because static typing is everywhere now and it's a good trend. As you know there are only 2 leaders: TypeScript and Flow. At first, Flow is easier for integration. TypeScript requires some additional changes. Secondly, when you write js with flow - you still write js. When you write TypeScript - you write in another language, not in js. TypeScript has own ecosystem and it can make project unattractive for some developers. Thirdly, flow is optional, so if you don't want flow - you can remove/ignore flow code and still work with a project.
Versioning is important, especially for a starter, because It's always hard to migrate especially when code evolves fast. standard-version
was added and now the project is following semver.
Bundle size was reduced using direct imports of CSS in src/client/index.jsx
.
From 545 kb to 312 KB.
Only some elements are imported. If your app uses other components then you need to import more CSS files. Honestly, this bundle size reduction is better to be named "artificial".
SUIR introduced some new components since a previous major update of the starter + semantic-ui-theme
(SUIT) was created. SUIT is a good idea because it aims to bring CSS-in-JS in SUI, but repo currently is empty. Only some notes in issues.
Also, I'm still waiting on <Datepicker>
in SUIR. Does anyone know when will it be released?
The first variant was "Noir", but later I've found that package with name "noir" had already existed. So, I decided to pick another name. And it was really hard :)
SUIR mentioned this project in a readme, starter always has been using SUIR, so I decided to name it SUIcrux
. I don't know what it can mean and how can it be translated, because English isn't my native language, but hope that it sounds better than "RSUIR".
Reducers tests weren't changed.
Actions tests now use nock
.
Jest snapshots were added.
Jest now resolves webpack aliases using babel-plugin-module-resolver
.
Jest can resolve files (files were ignored in prev release if I remember correctly).
Jest can test styled-components
, but this feature was turned off.
Test coverage increased from 81% to 89%.
It could be made even higher because xhr_wrapper
util doesn't have own tests (but it'll have and probably will be separated in own repo).
Reducers' structure wasn't changed.
Implement Redux code-splitting is one of the most important tasks currently.
I have a project with >250 async actions. And one I realized that duplicating this code pattern across app is terrible:
export const GET_USER = id => async dispatch => {
dispatch({type: 'GET_USER_PENDING'})
const payload = await getUserFromServer(id)
if (resultOK(payload)) {
dispatch({type: 'GET_USER_SUCCESS', payload})
} else {
dispatch({type: 'GET_USER_FAIL', payload, error:true})
}
dispatch({type: 'GET_USER_FINALLY', payload})
}
So I've written Awral some time ago. It's a tiny util for async actions creation. And it allows to write async actions like:
export const GET_USERS = awral(getUsers)('GET_USERS')
Awral was added in the starter, but it can be easily replaced/removed. Awral actions follow common action structure:
{
error?: boolean,
payload: any, // most commonly - API request result
meta: any, // I propose to store arguments in this field
type: string
}
Awral has smart API and it's only 910KB. It's highly recommended to check Awral sources before using it!
Custom LazyLoad
component was removed and replaced by react-async-component
+ react-async-bootstrapper
. I check sources of these libs. Almost everything ok, except it forces root component to fires componentWillMount
twice on the first render (If I remember correctly).
i18n-webpack-plugin
forces you to make as many builds as many languages you have, so it was replaced with react-intl
which allows making dynamic internationalisation.
i18n process is connected with SSR:
Accept-Language
header./locals
window[variable]
with localization data (only for this language!)ru
and en
available.Added AutoDLLPlugin
which makes builds significantly faster.
There is no spoon, Neo .html
template. src/server/ssr/HTMLComponent.jsx
creates html.
Many plugins like preload-webpack-plugin
, html-webpack-plugin
and other plugins were removed.
Complicated development/building cycle from tiny-universal-skeleton
(more info in repo) was introduced here.
npm run dev
shortly:
favicons-webpack-plugin
, webpack-stats generated by assets-webpack-plugin
) in /dist
folder/dist
folder (using webpack alias)This allows you to have both server and client hot-reloaded with no limitations: your server can have API, any middlewares, and etc.
NOTE:
undefined
. Your code should always be valid else server may not start or/and may throw errors. This bug isn't so horrible as described and very rarely occurs, but keep in mind.
Run npm run lint:scripts
to lint scripts and detects eslint errors/warns.Limitation probably will be fixed soon. Give me some time :)
Shortly:
auth
middleware:
request.user = {
isLoggedIn: boolean,
token: string | void,
username?: string,
language: string
}
NOTE: data fetching issue isn't solved completely.
normalizr
, reselect
and immutable
were removed.
react-ga
included.
More info here
Problems:
LazyLoad
component doesn't work properly with React 16)Wins:
For more info check Changelog
/users/
and Dashboard routes./links
route with links to docs./
route with a description(empty now) of the project."expect is not defined"
On the way to stabilize app. Dev mode and production build work, but still have some problems with react-intl and server push (HTTP2 feature).