DEV Community

loading...
Cover image for Experience building a package from react to svelte

Experience building a package from react to svelte

Carlos Azuaje
・4 min read

The svelte ecosystem grows more and more. New packages appear and people are encouraged to start using it.

I decided to contribute creating a package that perhaps will be useful to some people.

The original react project is this, a component to render a credit card. Very cool.

And this was my experience:


1.) Folder structure:

I had no idea how to create an npm package for svelte. So dig a little. In the github profile of sveltejs i founded this
A template to create shareables components.

2.) Sandbox environment to test the svelte component

My first idea was Storybook.

The new packages:

    "@babel/core": "^7.9.6",
    "@storybook/addon-actions": "^5.3.17",
    "@storybook/addon-links": "^5.3.17",
    "@storybook/addons": "^5.3.17",
    "@storybook/svelte": "^5.3.18",
    "babel-loader": "^8.1.0",
Enter fullscreen mode Exit fullscreen mode

And a config file:

module.exports = {
  stories: ["../src/*.stories.js", "../examples/*.stories.js"],
  addons: ["@storybook/addon-actions", "@storybook/addon-links"]
};
Enter fullscreen mode Exit fullscreen mode

What scenarios should we try with Storybook?

A file answered this question for me, the unit tests.

So I transformed the test cases into a storybook:

import CreditCard from "./";

export default {
  title: "Credit Card",
  component: CreditCard,
};

export const AmericanExpress = () => ({
  ...
});

export const Dankort = () => ({
  ...
});

// Diners, Visa, Maestro, ETC...
});
Enter fullscreen mode Exit fullscreen mode

3.) CSS y JSX:

This stage seemed complex. Since it involved the adaptation of CSS and React JSX to Svelte. I didn't know what bugs was going to find me with.

Browsing the original react package repository i discovered this A good SCSS file with all styles. I didn't think twice and put it inside the style tags in our new svelte component.

Example of scss in svelte

It worked. Now the JSX

Copy and paste the JSX to Svelte and replace className with class.

jsx to svelte

it worked again!

4.) Javascript, the challenge:

The first step was to write the script tags in the svelte component.

 // This will be insane
Enter fullscreen mode Exit fullscreen mode

First we had to create the props.

  export let focused = "number";
  export let acceptedCards = [];
  export let cvc = "";
  export let expiry = "";
  export let issuer = "";
  export let name = "";
  export let number = "";
  export let locale = { valid: "VALID THRU" };
  export let placeholders = { name: "YOUR NAME HERE" };
  export let preview = false;
Enter fullscreen mode Exit fullscreen mode

Now we need usepayment as in the React project to manage credit cards and their validations. And we needed to implement a method in the constructor like in the version de react. The closest thing is onMount in Svelte.

onMount(() => {
  // Logic for credit cards
});
Enter fullscreen mode Exit fullscreen mode

It worked.

Now we need derived data (Format credit number from the text props, format the CVC with the slash MM/YY). As we can see the react component used get to create classes methods that don't need be called like a function call_me_i_am_a_function() and the behavior of this method is like a property. Very common in object oriented programming:

 get number() {
    const { number, preview } = this.props;

    let maxLength = preview ? 19 : this.options.maxLength;
    let nextNumber = typeof number === 'number' ? number.toString() : number.replace(/[A-Za-z]| /g, '');
...
Enter fullscreen mode Exit fullscreen mode

So it seemed impossible to use something like that in Svelte. It is time to research.

The weird dollar symbol. What?

Lets try:

$: expiryDerived = (() => {
    focused = "number";
    const date = typeof expiry === "number" ? expiry.toString() : expiry;
    let month = "";
    // .... bla bla bla
    return value
  })();
Enter fullscreen mode Exit fullscreen mode

it worked, wow. At this time I am not sure if what I am doing is a good practice. If any of you have any ideas please submit a pull request: star:

5.) A bug when compiling.

It seems that payment uses commonjs and we don't have a plugin for this in our rollup configuration that gave us the svelte template.

So I had to add the commonjs plugin for rollup.

import commonjs from '@rollup/plugin-commonjs';

plugins: [
  svelte(),
  resolve(),
  commonjs() // <-- Our new friend
]
Enter fullscreen mode Exit fullscreen mode

Easy, right?

6.) Publish NPM Package

npm publish
Enter fullscreen mode Exit fullscreen mode

Conclusion:

Everything very easy and fun. There was not much stress. Svelte fulfilled all the requirements to create this component.

Enhacements

  • Refactor CSS to make customizable
  • Delete the payment package because it is very old and there is a news alternatives to manage credit card validation
  • Use Svelte animation and not @keyframes
  • Add unit test

Contributions

Send a pull requests to https://github.com/CharlyJazz/svelte-credit-card

Discussion (0)