Sharing code

If you have multiple projects and are using Frontastic-as-a-Library, you'll notice that within your GitHub customer repository you'll have a folder with your customer name along with the folders for each project. For example:

  • <customer>
    • <customer>
    • <customer_project1>
    • <customer_project2>

Within the folder with your customer name, you'll find:

  • <customer>
    • <customer>
      • automation folder
      • src folder
      • build.xml
      • composer.json
      • package.json
      • packer.json

Any code you add into these files and folders can be referenced in the code of your project repositories, which means that if you want the code to be the same in multiple projects you only have to write the code once.

We recommend to place all your shared code in the <customer>/<customer>/src folder and all configuration files for that shared code, including package.json or tsconfig.json should go in the <customer>/<customer> folder.

Within the src folder you can add what you'd like to share within your code but we recommend that you keep a similar structure to:

  • icons
  • js
  • layout
  • php
  • scss

Let's look at an example where we have a customer name of awesomecustomer and 2 projects (shopuk and supershop).

In our awesomecustomer repository, we'd have 3 folders:

  • awesomecustomer
  • awesomecustomer_shopuk
  • awesomecustomer_supershop

Within each of these folders, we'd have a composer.json, so:

  • awesomecustomer
    • composer.json
  • awesomecustomer_shopuk
    • composer.json
  • awesomecustomer_supershop
    • composer.json

We could update composer.json in our awesomecustomer folder as:

{
    "name": "frontastic-catwalk/awesomecustomer",
    "license": "None",
    "config": {
        "platform": {
            "php": "7.4"
        },
        "discard-changes": true
    },
    "require": {
        "frontastic/catwalk": "*",
        "frontastic/common": "*"
    },
    "require-dev":  {
    },
    "autoload": {
        "psr-4": {
            "awesomecustomer\\": "src/php"
        }
    },
    "autoload-dev": {
        "psr-4": {
            "awesomecustomer\\": "test/php"
        }
    }
}

Then for both shopuk and supershop we'd update the name and use:

{
    "name": "frontastic-catwalk/<projectname>",
    "license": "None",
    "config": {
        "platform": {
            "php": "7.4"
        },
        "discard-changes": true
    },
    "require": {
        "frontastic/catwalk": "*",
        "frontastic/common": "*"
    },
    "require-dev":  {
    },
    "autoload": {
        "psr-4": {
            "awesomecustomer\\": ["src/php", "../awesomecustomer/src/php"]
        }
    },
    "autoload-dev": {
        "psr-4": {
            "awesomecustomer\\": ["test/php", "../awesomecustomer/test/php"]
        }
    }
}

Or if you wanted the dependencies to be different, you can do that too.

If you're not using synchronization between projects (see the setting up a project article for more info), you can use this feature to share code between your Frontastic components.

For example, we can create a schema.json and a tastic.jsx, then add to our awesomecustomer folder, so:

awesomecustomer/src/js/tastic/awesome-tastic/awesome-tastic-schema.json
awesomecustomer/src/js/tastic/awesome-tastic/awesome-tastic.jsx

Then we'd need to upload the schema.json to each project in the Frontastic studio, and then the Frontastic component can be used in both projects with the same fields, and the same functionality.

You can even use the same schema.json but have a different jsx within each project. You'd need to register them differently within the tastics.js file but other than that, they can be separate.

Enable code sharing

To make sure your code sharing is set up correctly, you can follow the steps below.

  1. Open the package.json file in the root folder of your GitHub repository

  2. Add a new workspaces package if it's not there:

...
    "workspaces": {
        "packages": [  
            "awesomecustomer_shopuk",
            "awesomecustomer_supershop",
            "awesomecustomer"
        ],  
    },
...
  1. Make sure the name in each package.json with the project folders are the same as the packages in step 2
...
    "name": "awesomecustomer",
...
...
    "name": "awesomecustomer_shopuk",
...
...
    "name": "awesomecustomer_supershop",
...

That's the initial setup done!

But, with a setup like this, your imports will look like:

import MyAwesomeTastic from "../../../../../../../awesomecustomer/src/js/tastic/awesometastic.jsx

And that doesn't look great. So to avoid this, we recommend extending the webpack.js config and the tsconfig.json.

  1. Open the tsconfig.json in your shared code project, for example, awesomecustomer/awesomecustomer/tsconfig.json

  2. Add an alias under paths

...
    "compilerOptions": {
        ...
        "paths": {
            "@srcDS/*": ["src/*"]
        },
        ...
    }
...
  1. In each project folder, edit or create the tsconfig.json and the webpack.js files to include the alias you created in the step 2
{
    "compilerOptions": {
    ...
        "paths": {
            "@srcDS/*": ["../awesomecustomer/src/*"]
        }
    },
    "include": ["./src/js/**/*", "../awesomecustomer/src/**/*"],
    "exclude": ["./vendor/**/*"]
}
const merge = require('webpack-merge')
const path = require('path')


module.exports = (config, PRODUCTION, SERVER) => {
  // https://docs.frontastic.cloud/docs/extending-the-webpack-configuration

  const newConfig = merge.smart(
    config,
    {
      resolve: {
        alias: {
          "@srcDS": path.resolve(__dirname, '../../awesomecustomer/src'),
        },
      },
    }
  );
  return newConfig;
}

🚧

Ensure you do this step in each project folder where you want to use the shared code.

You can now use imports for the code you want to share like:

import MyAwesomeTastic from "@srcDS/tastic/awesometastic"

👍

Tip

With this setup, you'll be able to use TypeScript in your Frontastic components, as well as running Storybook in parallel with Frontastic CLI.