Metnew / suicrux

🚀 Ultimate universal starter with lazy-loading, SSR and i18n. [not maintained]
Apache License 2.0
942 stars 131 forks source link

Big change, including the rename of the project and what else #119

Closed neslinesli93 closed 7 years ago

neslinesli93 commented 7 years ago

Hi, first of all this is not an issue. I've been using this starter for a couple months, and I've been following the development since its early days. I was wondering what new features have been introduced with this new version, which happened to include a project rename as well. Keep up with the good work!

Metnew commented 7 years ago

First of all - thank you @neslinesli93 👍 ❤️ I shortly described changes here - https://github.com/Metnew/suicrux/releases But you're right, so let's describe it deeper.

Changes

Flow. Static typing

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

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.

SUIR in the project

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 in a wild

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?

RSUIR -> SUIcrux

"React-semantic.ui-starter" is too long + it doesn't sound even in short form(RSUIR). + Project was radically changed since I've started it (June 2016 in another repo), since it has been mentioned on Reddit (and was in Github's "Trending" that day) and since it has been mentioned in SUIR repo. So I decided to rename the project. 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".

Tests:

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)._

Redux

Reducers' structure wasn't changed.

Redux code-splitting

Implement Redux code-splitting is one of the most important tasks currently.

Awral. Async action creator.

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!

Lazy-Loading

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

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:

Webpack

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:

  1. Run server
  2. Server runs webpack
  3. Webpack has 2 configs: server and client
  4. Build client
  5. Store client's stats (favicons-stats generated by favicons-webpack-plugin, webpack-stats generated by assets-webpack-plugin) in /dist folder
  6. Get client's stats from /dist folder (using webpack alias)
  7. Build server code
  8. Get built server code
  9. Apply built server code to root server (server from step 1, which started webpack build )

This allows you to have both server and client hot-reloaded with no limitations: your server can have API, any middlewares, and etc.

NOTE:

  1. There is a problem - if code is invalid then webpack can't compile it and at step 8 you have 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 :)

SSR

Shortly:

NOTE: data fetching issue isn't solved completely.

Other libraries

normalizr, reselect and immutable were removed.

Redux-persist

More info here

(Comment may be updated...)

neslinesli93 commented 7 years ago

Woah, this is huge! Hope to get a chance to look through the new stuff asap

Metnew commented 7 years ago

Comment duplicated in "Releases" section