DEV Community

Cover image for Omatsuri – your everyday app
Vitaly Rtishchev
Vitaly Rtishchev

Posted on

Omatsuri – your everyday app

This week I've release Omatsuriopen source browser only application with 9 frontend and design focused tools. In this post I'll go through some technical challenges that I've faced during development.

Omatsuri main

About application

Omatsuri translates to «festival» from Japanese (お祭り) and includes a festival of 9 tools:

  • CSS Triangle Generator
  • Color Shades Generator
  • Curved Page Dividers Generator
  • SVG compressor
  • SVG to JSX converter
  • Base64 encoder
  • Realistic Fake Data Generator
  • HTML/CSS Symbols Collection
  • Lorem/Samuel/Poke Ipsum Generator

Some technical details

My initial purpose was to make Omatsuri a browser only application. This approach allows to reduce costs for hosting server that does heavy jobs, like svg compression, prettier transformations and other heavy things.

SVG compression

Did you know that there is actually only one good library for svg compression (svgo) written in JavaScript? And it does not have browser support, only node.js. I found it very strange as svg compression is based entirely on string parsing and does not include any node specific logic.

So my first task was to migrate svgo to browser. It was pretty easy, since all core logic did not require any modifications. And now you can use svgo-browser library in your projects if you ever need svg compression in browser.

Web workers

As I said before, some task are very heavy and can block your browser for several seconds. To fix this, we can put them in separate thread using web workers so that they run in background without blocking the main thread.

I was surprised how easy it is to work with web workers in webpack. All you need is worker-loader that will handle all worker bundling for you.

Here is an example of web worker usage for transforming svg to jsx with prettier and svg compression:

// svg-to-jsx.worker.js

import prettier from 'prettier/standalone';
import prettierBabel from 'prettier/parser-babel';
import svg2jsx from 'svg-to-jsx';
import optimize from 'svgo-browser/lib/optimize';

function generateComponent(svg) {
  return `import React from 'react';\n\nexport default function SvgComponent() { return ${svg} }`;
}

onmessage = (event) => {
  const { payload } = event.data;

  optimize(event.data.content)
    .then((content) => svg2jsx(content))
    .then((svg) =>
      prettier.format(generateComponent(svg), { parser: 'babel', plugins: [prettierBabel] })
    )
    .then((code) => postMessage({ error: null, payload, code }))
    .catch((error) => postMessage({ error, payload, content: null }));
};
// react component

import React, { useState, useLayoutEffect } from 'react';
import Svg2jsxWorker from '../../workers/svg-to-jsx.worker';

const svg2jsx = new Svg2jsxWorker();

export default function SvgToJsx() {
  const [result, setResult] = useState({ loading: false, error: null, content: null });

  const handleMessage = (event) => {
    setResult({ loading: false, error: event.data.error, content: event.data.code });
  };

  const postMessage = (text) => svg2jsx.postMessage({ content: text });

  useLayoutEffect(() => {
    svg2jsx.addEventListener('message', handleMessage);
    return () => svg2jsx.removeEventListener('message', handleMessage);
  }, []);

  return (/* ... */);
}

SPA prerendering

As app does not have any server logic it can be fully prerendered. To make that happen there is a webpack pugin that automatically prerenders all app routes on production builds. You can view my configuration for this plugin here.

Contributing

If you've been waiting to contribute to open source project, now is your chance! There are lots of features that can be added to the app, here is some of them:

  • Offline support with service workers
  • Dark theme support (automatically detected from user os)
  • New application – e.g. gradient generator

If you decide to contribute don't forget to add yourself to hall of fame on the About page.

What do you think?

Do you like this project? Will you use it? Don't be shy, comment about anything, I'll be happy to receive any feedback.

Top comments (0)