npm package: @studyportals/vue-config
Description: Collection of vue-related packages.
Author: Studyportals B.V.
Latest version: 5.0.3

# Vue-Config

## Purpose
This library is a replacement for several common Vue npm packages. The library 
is loaded in on all pages on our portals and pages of UniversityAdmin that contain
one or more Vue microservices, which means that any Vue microservice on our portals
and UniversityAdmin can rely on these packages being there. This way we avoid the
duplication of every microservice loading in the same NPM packages.
 
The library contains only core Vue dependencies (so for instance no `vue-class-component`). At this moment, the library includes:

* vue
* vue-router

## Usage
First uninstall all dependencies which this package provides:

```bash
npm uninstall vue vue-router
```

Then we simply replace these by this library:

Webpack 5:
```bash
npm install @studyportals/vue-config
```

Webpack 4: 
```bash
npm install @studyportals/vue-config@^3.0.0
```

Webpack 3: 
```bash
npm install @studyportals/vue-config@^1.2.1
```

Under the [purpose](#purpose) section, the benefit was mentioned of not having to
load in the same dependencies multiple times. So, webpack needs to take care of
excluding vue-config-related packages when building your project. If you are using
vue-config for a microservice that is deployed using the [webpack-helper package](https://github.com/studyportals/webpack-helper),
no extra webpack configuration is needed for this to be taken care of. Otherwise,
you'll need to add the following plugin to your webpack configuration (for example
in webpack.base.conf.js):

``` javascript
plugins: [
    new webpack.DllReferencePlugin({
        manifest: require("@studyportals/vue-config/dist/vue3_library.json")
    })
],
```

or for prior vue-config versions (v3 or lower) that support vue 2:

``` javascript
plugins: [
    new webpack.DllReferencePlugin({
        manifest: require("@studyportals/vue-config/dist/library.json")
    })
],
```

There is nothing more to do. Your Vue application will now use the packages provided by this package.
Once the dependencies are found, and resolved, they will be excluded from your bundle. Your bundle
file should now be significantly smaller!

## Custom build steps
- **Custom module ids plugin** . This self-made plugin set custom module ids for vue and vue-router. We have gone  for a self-made plugin as the default plugins do not generate the same module ids for a production and development bundle. This makes a production code dll manifest incompatible with the development dll manifest

- **Append to bundle plugin** This self-made plugin makes it possible to append a small piece of code to the end of a bundle. We use this to add the following piece of code: 

```javascript
if (typeof module !== 'undefined'){
    module.exports = vue3_library
}
````

This code exports the vue3_library, so it can be imported in unit tests. This is necessary as some packages are built with this dll dependency. If it's not loaded all unit tests importing this package will fail. By exporting it we can load vue3_library within the unit test setup phase.

## Common issues

### Place of webpack configuration in folder structure
The `vue3_library.json` file that is referenced relies on a certain folder structure to find its dependencies and exclude them from the main application file that it builds. It is recommended to configure webpack with the `@studyportals/webpack-helper` package so that this process is simplified and less error-prone.

### Aliases
It is possible that your webpack configuration contains aliases, like so: 

```javascript
resolve: {
    alias: {
        'vue$': 'vue/dist/vue.esm.js'
    }
}
```
This might break the codesplitting and so far the working solution has been to simply remove the alias.

### no-extraneous-dependencies
Since we now load in this library as a dependency we no longer have Vuex as a direct dependency in our package.json file.
If your Eslint has the 'no-extraneous-dependencies' rule configured it will no longer let you build your project :(. The 
only solution we found until now is to turn off the rule by using the following setting:

```javascript
'import/no-extraneous-dependencies': 0,
```

### "But my application requires a package to run on a different version"

In that case, that specific package can be updated, but you **first** need to
**align with all the other teams that have a Vue application to re-deploy once the
version is changed**, to avoid any conflicts between applications that depend on
the same `vue-config`-based library file.

### How do I run my application standalone?
Open your main index.html file and include the pre-build library.
```html
<script type="text/javascript" src="https://cdn.jsdelivr.net/npm/@studyportals/vue-config@4.0.0/dist/vue3_library.min.js"></script>
```
_Production version_

You can also include the non minified version (which enables the Vue debugger). This is totally fine
as long as you make sure that the non minified version will never be embedded in production. _You shouldn't
even try to embed the library file on our portals since it is already loaded through the CDN so you should be
fine ;-)_
```html
<script type="text/javascript" src="https://cdn.jsdelivr.net/npm/@studyportals/vue-config@4.0.0/dist/vue3_library.js"></script>
```
_Development version_

The vue-config library is by default loaded on every page. Loading this library multiple times will cause the page
to break. It is therefore important to exclude them! There are several ways to embed your resources on our portals. Most of them boil down to parsing the DOM, extracting the javascript and stylesheets and injecting them on the page.

## How does it work?

This package is created with the [DLLPlugin](https://webpack.js.org/plugins/dll-plugin/).
A manifest is created on the side, which is used by the [DllReferencePlugin](https://webpack.js.org/plugins/dll-plugin/#dllreferenceplugin) to map dependencies.