Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Use resolve.modules instead of explicit aliases when adding NPM packages #1077

Merged
merged 4 commits into from
Jan 29, 2024
Merged
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
Original file line number Diff line number Diff line change
Expand Up @@ -7,18 +7,22 @@

# Adding NPM Dependencies

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

## 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.
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.

## Video

This guide is also available as a video:

<YoutubeRef video="wfBuWdff35c" title="Shopware 6: Your custom NPM dependencies (Developer Tutorial) - YouTube" target="_blank" />

{% hint style="warning" %}
This video shows how to resolve the NPM package name as an alias. We recommend resolving all node_modules instead like shown in the code example below.
{% endhint %}

## Adding a npm package to the Administration or the Storefront

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 simply run the `npm install` command. In this example we will be installing [`missionlog`](https://www.npmjs.com/package/missionlog).
Expand All @@ -29,40 +33,36 @@

Shopware's storefront as well as administration is based on the build system [Webpack](https://webpack.js.org/). Webpack is a source file bundler: In essence it bundles all the source files into a single `bundle.js` to be shipped to a browser. So in order to make Webpack aware of the new dependency, we have to register it and give it an alias/pseudonym so that the package can be bundled correctly.

To do this we create a new folder called "build" under either `Resources/app/storefront` or `Resources/app/administration`. In this build folder we create a new file with the name `webpack.config.js`. We thereby make it possible to extend the Webpack configuration of Shopware.
To do this, we create a new folder called "build" under either `Resources/app/storefront` or `Resources/app/administration`. In this build folder we create a new file with the name `webpack.config.js`. We thereby make it possible to extend the Webpack configuration of Shopware.

```javascript
// <plugin root>/src/Resources/app/storefront/build/webpack.config.js
const { join, resolve } = require('path');
module.exports = () => {
module.exports = (params) => {

Check warning on line 39 in guides/plugins/plugins/plugin-fundamentals/using-npm-dependencies.md

View workflow job for this annotation

GitHub Actions / LanguageTool

[LanguageTool] guides/plugins/plugins/plugin-fundamentals/using-npm-dependencies.md#L39

If a new sentence starts here, add a space and start with an uppercase letter. (LC_AFTER_PERIOD[1]) Suggestions: ` Exports`, ` exports` Rule: https://community.languagetool.org/rule/show/LC_AFTER_PERIOD?lang=en-US&subId=1 Category: CASING
Raw output
guides/plugins/plugins/plugin-fundamentals/using-npm-dependencies.md:39:7: If a new sentence starts here, add a space and start with an uppercase letter. (LC_AFTER_PERIOD[1])
 Suggestions: ` Exports`, ` exports`
 Rule: https://community.languagetool.org/rule/show/LC_AFTER_PERIOD?lang=en-US&subId=1
 Category: CASING
return {
resolve: {
alias: {
'@missionlog': resolve(
join(__dirname, '..', 'node_modules', 'missionlog')
)
}
modules: [
`${params.basePath}/Resources/app/storefront/node_modules`,
],
}
};
}
```

Let us take a closer look at the code. In the first line, we import the two functions `join` and `resolve` for the path module of Node.js. In the second line, we export a so-called arrow function. The build system from Shopware calls this function when either the Administration or Storefront is being built.
{% endcode %}

After that, there comes the exciting part for us: registering the alias. The alias for `missionlog` is given the prefix `@`, so it is possible to recognize later on in the source files. We will use the result of the two functions of the path module previously imported as a value.
Let us take a closer look at the code. In the first line, we export a so-called arrow function. The build system from Shopware calls this function when either the Administration or Storefront is being built.

We proceed from the inside to the outside. We use [`join`](https://nodejs.org/api/path.html#path_path_join_paths) to reflect the path to the package inside the `node_modules` folder. The `node_modules` folder contains all the packages that we have installed via `npm install`. After we identified the relevant path to the package, we use the [`resolve`](https://nodejs.org/api/path.html#path_path_resolve_paths) function to transform this path into an absolute path.
Now we add the `node_modules` folder from our extension. `resolve.modules` tells webpack what directories should be searched when resolving modules. By default, the shopware webpack config only considers the `node_modules` folder of the platform. By accessing `params.basePath` we get the absolute path to our extension. We then add the rest of the path to our extensions `node_modules`. Now webpack will also search for modules in our `node_modules` folder.

## Using the dependency

Once we have installed all the dependencies and registered the package in the build system with an alias, we can use the package in our own code.
Once we have installed all the dependencies and registered the package in the build system, we can use the package in our own code.

```javascript
// <plugin root>/src/Resources/app/storefront/src/main.js
// <plugin root>/src/Resources/app/storefront/src/example.plugin.js
import Plugin from 'src/plugin-system/plugin.class';

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

// Initializing the logger
log.init({ initializer: 'INFO' }, (level, tag, msg, params) => {
Expand All @@ -80,10 +80,29 @@
}
```

We import the function log as well as the constants tag via `destructuring` in the specified code. Through the use of the alias, we keep the paths short and recognize that this is an alias at first glance via the prefix.
We import the function log as well as the constants tag via `destructuring` in the specified code and register our above plugin in our main.js file, so it can be loaded by the plugin system.

```javascript
// <plugin root>/src/Resources/app/storefront/src/main.js
import ExamplePlugin from './example.plugin';

PluginManager.register(
'ExamplePlugin',
ExamplePlugin
);
```

The final step in this process is to build your Storefront or Administration so that your changes are processed by Webpack.

```bash
# Build the Storefront
./bin/build-storefront.sh

# Build the Administration
./bin/build-administration.sh
```


## 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](../administration/add-custom-service)
Expand Down
Loading