Experience building a package from react to svelte
Tags: svelte, react, javascript, frontend
Published: 2020-05-15 21:44:15

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](https://github.com/amarofashion/react-credit-cards), 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](https://github.com/sveltejs/component-template)
A template to create shareables components.



### 2.) Sandbox environment to test the svelte component

My first idea was [Storybook](https://storybook.js.org/docs/guides/guide-svelte).

The new packages:

``` json
    "@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",
```

And a config file:

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

What scenarios should we try with Storybook?

A file answered this question for me, [the unit tests](https://github.com/amarofashion/react-credit-cards/blob/master/test/index.spec.js). 

[So I transformed the test cases into a storybook](https://github.com/CharlyJazz/svelte-credit-card/blob/master/src/CreditCard.stories.js):


``` javascript
import CreditCard from "./";

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

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

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

// Diners, Visa, Maestro, ETC...
});
```


### 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](https://github.com/amarofashion/react-credit-cards/blob/master/src/styles.scss) 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](https://user-images.githubusercontent.com/12489333/82091151-3e8b4c80-96cd-11ea-9811-ff8bf665a318.png)

It worked. Now the JSX

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

![jsx to svelte](https://user-images.githubusercontent.com/12489333/82092305-667baf80-96cf-11ea-8562-1140fdf8670f.png)

it worked again!



## 4.) Javascript, the challenge:

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

``` javascript
 // This will be insane
```

First we had to create the props.

``` javascript
  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;
```

Now we need use[payment](https://www.npmjs.com/package/payment) 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](https://github.com/amarofashion/react-credit-cards/blob/master/src/index.js#L9). The closest thing is `onMount` in Svelte.

``` javascript
onMount(() => {
  // Logic for credit cards
});
```

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](https://github.com/amarofashion/react-credit-cards/blob/master/src/index.js#L71) 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:

``` javascript
 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, '');
...
```

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

[The weird dollar symbol](https://svelte.dev/tutorial/updating-arrays-and-objects). What?

Lets try:

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

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.

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

plugins: [
  svelte(),
  resolve(),
  commonjs() // <-- Our new friend
]
```

Easy, right?

## 6.) Publish NPM Package 

``` bash
npm publish
```

## 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](https://svelte.dev/tutorial/animate) and not `@keyframes`
- Add [unit test](https://dev.to/d_ir/introduction-4cep)


## Contributions

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