Sharing code

If you have multiple projects and are using Frontastic-as-a-Library, you'll notice that within your GitHub customer repositoryGitHub customer repository - Where your code lives in GitHub for all your projects, you can have many project folders within your 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 componentsFrontastic components - A customizable building block that's used together with other components to create a commerce site. Known as `tastic` for short in code..

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 studioFrontastic studio - The interface you use to manage, build, and edit all areas of your project and commerce sites. Previously known as `backstage`., and then the Frontastic componentFrontastic component - A customizable building block that's used together with other components to create a commerce site. Known as `tastic` for short in code. 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.


Did this page help you?