@bitfactory/shared-commerce-frontend-linters

v0.1.20

Published

Frontend linters for Bitfactory's commerce team

Readme

Shared Commerce Frontend Linters

A modular linting and formatting configuration package for Bitfactory's commerce team, supporting multiple tech stacks and frameworks.

Table of Contents

Features

  • Always includes: ESLint + Unicorn plugin, Prettier
  • Modular architecture: Pick and choose what you need
  • Tech stack support: React, Vue, TypeScript, SCSS, Tailwind CSS, Twig, Liquid
  • Common presets: Ready-made combinations for popular setups

Installation

Install the package as a dev dependency:

npm install --save-dev @bitfactory/shared-commerce-frontend-linters

From here you'll want to add configuration files to your project. You can use one of our Tech Stack Configurations as a base, or compose your own as described in Usage.

If you are not following the tech stack guide, you'll also want to configure you package.json scripts to run the linters: eslint, stylelint, prettier, djlint, as well as :fix versions, and combined versions for all linters (lint and lint:fix).

After running the linters and fixing any issues, you'll want to add a Commit Hook to run the linters on every commit. And a Github Action to run the linters on every push.

Due to the unusal nature of the djlint, we don't include it as a peer dependency. You will need to add it as a dev dependency to your project:

npm install --save-dev djlint

And make sure the developers that are working on the project have python and pip installed. You can find the installation instructions here.

Usage

Presets

You can import the presets from the package, and use them as is. See Tech Stack Configurations for more information.

Composition

You can compose the configurations by importing the base configuration and desired module.

From here you can make project specific tweaks, but it is preferred that you add the configuration of your stack to this package, so that it can be used by other projects.

You could also make changes to the extensions, if the team agrees that it is a good idea.

ESLint

ESLint 9 and above use flat configurations, so you can just import the modules you need and compose them together, using the spread operator. It is recommended to always end with prettier, as it will override the eslint rules with prettier rules.

// eslint.config.js
import { baseESLint, typescriptESLint, reactESLint, prettierESLint } from '@bitfactory/shared-commerce-frontend-linters';

export default [
    ...baseESLint,
    ...typescriptESLint,
    ...reactESLint,
    ...prettierESLint,
    {
      // Add your own eslint options here
    }

];

Stylelint

Stylelint has an extendable configuration, so you can import the base configuration and then add the modules you need.

// stylelint.config.js
import { baseStylelint, scssStylelint, tailwindStylelint } from '@bitfactory/shared-commerce-frontend-linters';

export default {
  extends: [
    baseStylelint,
    scssStylelint,
    tailwindStylelint,
    // Add your own extensions here
  ],
  // Add your own stylelint options here
};

Prettier

Prettier is a bit different, it does not have any options for composition, so you need to do that manually.

// prettier.config.js
import { basePrettier, scssPrettier, liquidPrettier, tailwindPrettier } from '@bitfactory/shared-commerce-frontend-linters';

export default {
  ...basePrettier,

  overrides: [
    ...(scssPrettier.overrides || []),
    ...(liquidPrettier.overrides || []),
    // Add your own overrides here
  ],

  plugins: [
    ...(scssPrettier.plugins || []),
    ...(liquidPrettier.plugins || []),
    // Add your own plugins here
  ],
};

DJLint

DJLint is a Python-based tool for linting and formatting HTML templates (including Twig). We provide a setup command that generates a .djlintrc configuration file from our modular configuration.

Quick Setup

Run the setup command in your project root:

npx node_modules/@bitfactory/shared-commerce-frontend-linters/scripts/setup-djlint.mjs

This command will:

  1. Generate a .djlintrc file in your project root
  2. Check if Python and pip are available in your system PATH
  3. Confirm that DJLint can be installed via npm

Alternatively, run directly with:

node node_modules/@bitfactory/shared-commerce-frontend-linters/scripts/setup-djlint.mjs

If Python or pip are not found, the setup script will provide installation links and instructions to install them. After installing Python and pip, reinstall the package:

npm install

Manual Configuration

If you prefer to set up djlint manually, you can create your own .djlintrc file:

{
  "profile": "nunjucks",
  "indent": 4,
  "blank_line_after_tag": "load,extends,include,import,from",
  "max_line_length": 120,
  "format_css": true,
  "format_js": true,
  "close_void_tags": true
}

Programmatic Access

You can also import the configuration object in JavaScript for tooling or custom setup scripts:

import { twigDjlint } from '@bitfactory/shared-commerce-frontend-linters';

// Use this config object to generate your own configuration
console.log(twigDjlint);

Available Modules

Presets

  • shopwarePreset - Shopware 6 preset (eslint, prettier, stylelint, djlint as script setup)
  • shopifyPreset - Shopify preset (eslint, prettier, stylelint)

Base Configurations

  • baseESLint - Core ESLint + Unicorn rules (always included)
  • basePrettier - Core Prettier formatting rules
  • baseStylelint - Core Stylelint formatting rules

ESLint Extensions

  • typescriptESLint - TypeScript support and rules
  • reactESLint - React and JSX support
  • r3fESLint - React Three Fiber support
  • vueESLint - Vue 3 SFC support

Prettier Extensions

  • vuePrettier - Vue SFC formatting
  • scssPrettier - SCSS/CSS formatting
  • liquidPrettier - Liquid template formatting
  • tailwindPrettier - Tailwind CSS class sorting

DJLint Extensions

  • twigDjlint - Twig template linting and formatting configuration

Stylelint Extensions

  • scssStylelint - SCSS linting rules
  • tailwindStylelint - Tailwind CSS compatibility

TypeScript

We provide a tsconfig.json file, that you can use as a base for your project.

// tsconfig.json
{
  "extends": "@bitfactory/shared-commerce-frontend-linters/tsconfig.json",
}

Tech Stack Configurations

Below you will find base setups for our most common tech stacks.

Shopware

Add the following to the root package.json of your Shopware project:

{
  ...
  "type": "module",
  "scripts": {
    "eslint": "eslint ./custom/plugins/[PLUGIN_NAME]/src/Resources/app --ext .js --ignore-pattern '**/dist/*'",
    "eslint:fix": "eslint ./custom/plugins/[PLUGIN_NAME]/src/Resources/app --ext .js --fix --ignore-pattern '**/dist/*'",
    "stylelint": "stylelint ./custom/plugins/[PLUGIN_NAME]/src/Resources/app/**/*.scss",
    "stylelint:fix": "stylelint ./custom/plugins/[PLUGIN_NAME]/src/Resources/app/**/*.scss --fix",
    "djlint": "djlint ./custom/plugins/[PLUGIN_NAME]/**/ --lint",
    "djlint:fix": "djlint ./custom/plugins[/PLUGIN_NAME]/**/ --lint --reformat",
    "prettier": "prettier --check ./custom/plugins[PLUGIN_NAME]/**/*.{js,scss,css,json,md}",
    "prettier:fix": "prettier --write ./custom/plugins[PLUGIN_NAME]/**/*.{js,scss,css,json,md}",
    "lint": "npm run eslint && npm run stylelint && npm run djlint && npm run prettier",
    "lint:fix": "npm run eslint:fix && npm run stylelint:fix && npm run djlint:fix && npm run prettier:fix"
  },
}

If you want to use our default Shopware configurations, you should also add the following config files to your project:

// eslint.config.mjs
import { shopwarePreset } from '@bitfactory/shared-commerce-frontend-linters';

export default shopwarePreset.eslint;
// prettier.config.mjs
import { shopwarePreset } from '@bitfactory/shared-commerce-frontend-linters';

export default shopwarePreset.prettier;
// stylelint.config.js
import { shopwarePreset } from '@bitfactory/shared-commerce-frontend-linters';

export default shopwarePreset.stylelint;

You most likely want to ignore build files for prettier:

// .prettierignore
**/dist/

Regarding stylelint in the administration folder, they use BEM notation and we don't want to make an exception for them. So you should manually ignore the lines that are giving you class name errors:

// example.scss
/* stylelint-disable-next-line selector-class-pattern */
.bem-block--modifier {
  // ...
}

Shopify

TODO: Add Shopify documentation

Commit Hooks

Linters should should run in your pre-commit hook, you can set this up as follows:

npx husky init
npx husky add .husky/pre-commit "npm run lint:fix"

Github Actions

We recommend adding a Github Action that runs the linters on every push. You can use the following configuration:

# .github/workflows/ci.yml
name: CI
on: [push]
jobs:
    codestyle:
        runs-on: ubuntu-latest
        steps:
            - name: Checkout repository
              uses: actions/checkout@v4

            - uses: actions/setup-node@v4
              with:
                  node-version: 22
                  cache: npm

            - name: Install dependencies
              run: npm install

            - name: Run Linters
              run: npm run lint

IDE Plugins

VSCode/Cursor

We recommend using the following plugins:

As well as enabling the following settings in your settings.json:

// .vscode/settings.json
{
  "editor.codeActionsOnSave": {
		"source.fixAll.stylelint": "explicit"
	},
  "editor.formatOnSave": true,
  "[javascript]": {
		"editor.defaultFormatter": "esbenp.prettier-vscode"
	},
  "[typescript]": {
		"editor.defaultFormatter": "esbenp.prettier-vscode"
	},
  "[css]": {
		"editor.defaultFormatter": "esbenp.prettier-vscode"
	},
  "[scss]": {
		"editor.defaultFormatter": "esbenp.prettier-vscode"
	},
  "[json]": {
		"editor.defaultFormatter": "esbenp.prettier-vscode"
	},
  	"[typescriptreact]": {
		"editor.defaultFormatter": "esbenp.prettier-vscode"
	},
  "[javascriptreact]": {
		"editor.defaultFormatter": "esbenp.prettier-vscode"
	},
  "[vue]": {
		"editor.defaultFormatter": "esbenp.prettier-vscode"
	},
  "[twig]": {
		"editor.defaultFormatter": "monosans.djlint"
	},
}

IntelliJ (PHPStorm)

If you are using PHPStorm, please find the equivalent plugins for the VSCode plugins in the JetBrains Marketplace. As well as changes to your settings file and update this section of the README.