Skip to content

Adding NPM Dependencies

Adding NPM Dependencies

In this guide, you'll learn how to add NPM dependencies to your plugin.

Prerequisites

All you need for this guide is a running Shopware 6 instance and full access to both the files and a running plugin. Of course, you'll have to understand JavaScript, but that's a prerequisite for Shopware as a whole and will not be taught as part of this documentation. Further, a basic understanding of Node and NPM is required.

Installing an npm package

Presuming you have npm installed, run npm init -y in the <plugin root>/src/Resources/app/administration/ folder or the <plugin root>/src/Resources/app/storefront/ folder. This command creates a package.json file in the respective folder, depending on the environment you're working in.

To add a package to the package.json file, run the npm install command. In this example we will be installing missionlog:

bash
npm install missionlog

Administration (Shopware 6.7+ with Vite)

Since Shopware 6.7, the Administration build system has been migrated from Webpack to Vite. With Vite, you no longer need a custom webpack.config.js file to use npm packages. Vite resolves npm packages from your plugin's node_modules directory automatically using standard Node.js module resolution.

You can import npm packages directly in your code without any additional build configuration:

javascript
import { log } from 'missionlog';

// Initializing the logger
log.init({ initializer: 'INFO' }, (level, tag, msg, params) => {
    console.log(`${level}: [${tag}] `, msg, ...params);
});

If you need custom Vite configuration (for example, path aliases), create a vite.config.mts file in the <plugin root>/src/Resources/app/administration/src/ directory (alongside your entry file, e.g., main.js). Note that package.json stays in <plugin root>/src/Resources/app/administration/:

typescript
import { defineConfig } from 'vite';

export default defineConfig({
    resolve: {
        alias: {
            '@my-module': 'src/my-module',
        },
    },
});

Build the Administration using:

bash
composer build:js:admin

For more information on migrating from Webpack to Vite, see the Webpack to Vite migration guide.

Storefront (Webpack)

The Storefront build system continues to use Webpack. To make Webpack aware of the npm packages installed in your plugin, create a webpack.config.js file in the <plugin root>/src/Resources/app/storefront/build/ directory:

javascript
module.exports = (params) => {
    return {
        resolve: {
            modules: [
                `${params.basePath}/Resources/app/storefront/node_modules`,
            ],
        }
    };
}

This tells Webpack to also search for modules in your plugin's node_modules folder, in addition to Shopware's own node_modules.

Using the dependency in the Storefront

Once you have installed all the dependencies and registered the plugin's node_modules path in the build system, you can import and use the package in your code:

javascript
const { PluginBaseClass } = window;

// Import logger
import { log } from 'missionlog';

// Initializing the logger
log.init({ initializer: 'INFO' }, (level, tag, msg, params) => {
    console.log(`${level}: [${tag}] `, msg, ...params);
});

// The plugin skeleton
export default class ExamplePlugin extends PluginBaseClass {
    init() {
        console.log('init');

        // Use logger
        log.info('initializer', 'example plugin got started', this);
    }
}

Register the plugin in your main.js file so it can be loaded by the plugin system:

javascript
import ExamplePlugin from './example.plugin';

PluginManager.register(
    'ExamplePlugin',
    ExamplePlugin
);

Build the Storefront using:

bash
shopware-cli project storefront-build

Using npm packages in a pure-SCSS theme (no JS entry point)

If your plugin is a theme and only consumes npm packages from SCSS (for example @fortawesome/fontawesome-free or any other package referenced via @import in your theme.json style entries), you will run into a chicken-and-egg problem with shopware-cli project storefront-build:

  • shopware-cli only runs npm install for a storefront extension when it has a JavaScript entry point (src/Resources/app/storefront/src/main.js).
  • Even when a main.js is present, shopware-cli runs the asset build (webpack) first and then deletes the storefront-root node_modules directory before theme:compile runs.

The result is that a theme.json/SCSS @import like app/storefront/node_modules/@fortawesome/fontawesome-free/scss/fontawesome cannot be resolved, and theme:compile aborts with:

text
Unable to compile the theme "MyTheme". Unable to resolve file
"Resources/app/storefront/node_modules/@fortawesome/fontawesome-free/scss/fontawesome.scss".

Workaround: copy required assets out via postinstall

Because the postinstall script of a storefront extension's package.json runs before the root node_modules directory is deleted, you can copy the parts of the package that theme:compile needs into a persistent (git-ignored) folder inside the theme. After that, the SCSS imports and theme.json style entries must point at that folder instead of node_modules.

The nested folder must contain a node_modules path segment, because shopware-cli project format / validate only ignore the storefront-root node_modules and shopware-cli only deletes that one level. A nested copy survives both steps.

1. Provide an empty JS entry point

Add an empty src/Resources/app/storefront/src/main.js so shopware-cli installs the theme's npm dependencies and runs its lifecycle scripts:

javascript
// Intentionally empty. Present so shopware-cli installs this theme's npm
// dependencies and runs the package.json "postinstall" below.

2. Copy the necessary files out of node_modules in postinstall

json
{
    "dependencies": {
        "@fortawesome/fontawesome-free": "^6.1.1"
    },
    "scripts": {
        "postinstall": "rm -rf .vendor && mkdir -p .vendor/node_modules/@fortawesome/fontawesome-free && cp -R node_modules/@fortawesome/fontawesome-free/scss .vendor/node_modules/@fortawesome/fontawesome-free/ && mkdir -p ../../public/static/fonts && cp node_modules/@fortawesome/fontawesome-free/webfonts/fa-* ../../public/static/fonts/"
    }
}

The script does three things:

  • Copies the package's SCSS into .vendor/node_modules/@fortawesome/fontawesome-free/scss/ so theme:compile can still resolve it after the root node_modules is removed.
  • Copies the package's webfonts into public/static/fonts/ so the compiled theme can serve the font files at runtime.
  • Keeps the copy nested under a node_modules path segment so the format/validate check does not flag the copied files.

3. Update the theme to reference the copied files

json
{
    "style": [
        "app/storefront/.vendor/node_modules/@fortawesome/fontawesome-free/scss/fontawesome.scss",
        "app/storefront/src/scss/base.scss"
    ]
}
scss
$fa-font-path: "../static/fonts";
@import '../../.vendor/node_modules/@fortawesome/fontawesome-free/scss/fontawesome';

If the package ships runtime assets (webfonts, images, …) that you previously exposed through the asset block in theme.json via a node_modules/... path, point those entries at the public/static/... copy instead.

4. Ignore the generated files

Add the generated folders to your .gitignore:

gitignore
/.vendor/
/public/static/fonts/fa-*

Why this works and what to expect

  • shopware-cli project storefront-build runs npm install for the theme (because main.js exists), which triggers postinstall and copies the files into .vendor/ and public/static/fonts/.
  • The webpack build runs, the storefront-root node_modules is deleted, and then theme:compile runs against the persistent .vendor/node_modules/... copy. The build exits 0.
  • shopware-cli project format / validate do not flag the copied files because they live under a nested node_modules/ path.
  • The webfonts end up under public/bundles/<theme>/static/fonts/ after compilation, which is what the SCSS expects at runtime.

This workaround is known to be fragile: it depends on shopware-cli running npm lifecycle scripts and on the cleanup deleting only the storefront-root node_modules. If you do not need npm packages in your theme, prefer keeping the theme free of node_modules imports. A longer-term fix (installing npm dependencies for a JS-less theme and deferring the node_modules cleanup until after theme:compile) is being discussed in shopware/shopware-cli#1466.

Next steps

Now that you know how to include new npm dependencies you might want to create a service with them. Learn how to do that in this guide: How to add a custom-service

If you want to add Composer dependencies, or even other plugin dependencies, we've got you covered as well.

Was this page helpful?
UnsatisfiedSatisfied
Be the first to vote!
0.0 / 5  (0 votes)