Migrating from v2.x to v3.x

RxJS imports

All RxJS modules are now imported individually, resulting in smaller bundle sizes in your applications.

This also means, the observables returned by FrintJS packages will not have the operators (like map, filter, etc) built in any more, and they need to be imported manually too if you need them.

Before

We can take an example from frint-store:

const todos$ = store.getState$()
  .filter(state => state.showTodos === true)
  .map(state => state.todos);

todos$.subscribe(todos => console.log(todos));

After

import { filter } from 'rxjs/operator/filter';
import { map } from 'rxjs/operator/map';

const todos$ = store.getState$()
  ::filter(state => state.showTodos === true)
  ::map(state => state.todos);

todos$.subscribe(todos => console.log(todos));

The syntax above is written using the bind-operator.

It could also have been written like this:

import { filter } from 'rxjs/operator/filter';
import { map } from 'rxjs/operator/map';

const todos$ = map.call(
  filter.call(
    store.getState$(),
    state => state.showTodos === true
  ),
  state => state.todos
);

todos$.subscribe(todos => console.log(todos));

Lodash imports

All lodash imports have also been updated to import only the modules that are needed.

If you want to take benefit of reduced bundle size in your applications, then you can follow the same approach.

Before

import _ from 'lodash';

_.isPlainObject({});

After

import isPlainObject from 'lodash/isPlainObject';

isPlainObject({});

Webpack builds

If your application is set up in a way like this:

  • vendors.js: All third party libraries (RxJS, Lodash, Frint, etc)
  • app.js: Your custom code for Frint App(s)

Or you are loading the vendors directly from CDN via <script> tags, then you risk loading some RxJS and Lodash modules twice.

To help avoid that, we are shipping a new frint-config package that has information about the list of external dependencies, that you can map accordingly.

Before

// webpack.config.js
module.exports = {
  entry: __dirname + '/src/index.js',
  output: {
    path: __dirname + '/build'
  },
  externals: {
    'lodash': '_', // window._
    'rxjs': 'Rx', // window.Rx

    // other libraries
    'react': 'React',
    'react-dom': 'ReactDOM',
  },
}

After

// webpack.js

// all RxJS and Lodash imports
// are mapped to global `window._` and `window.Rx`
const externals = require('frint-config').externals;

module.exports = {
  entry: __dirname + '/src/index.js',
  output: {
    path: __dirname + '/build'
  },
  externals: Object.assign(
    {},

    // RxJS and Lodash
    externals,

    // other libraries
    {
      'react': 'React',
      'react-dom': 'ReactDOM',
    }
  ),
}

frint-store

thunkArgument option has been renamed to deps.

Before

import { createStore } from 'frint-store';

const Store = createStore({
  thunkArgument: {},
});

After

import { createStore } from 'frint-store';

const Store = createStore({
  deps: {},
});

frint-model

Deprecated and will be completely removed when v4.0 gets released. Use frint-data instead.

Before

import { createModel } from 'frint-model';

const Todo = createModel({
  getTitle() {
    return this.get('title');
  },
  setTitle(newTitle) {
    this.set('title', newTitle);
  },
});

const todo = new Todo({
  title: 'Hello World',
  completed: false,
});

const title = todo.getTitle();
todo.setTitle('Updated title');

After

import { Types, createModel } from 'frint-data';

const Todo = createModel({
  schema: {
    title: Types.string, // or, Types.string.required
    completed: Types.bool, // or, Types.bool.defaults(false),
  },
  setTitle(newTitle) {
    this.title = newTitle;
  },
});

const todo = new Todo({
  title: 'Hello World',
  completed: false,
});

const title = todo.title;
todo.setTitle('Updated title');

frint-compat

Completely emptied, and v0.x is no longer supported in any way.