Workflow tip: How to use Vuejs in a Laravel Package

damilola jolayemi
4 min readFeb 25, 2018

--

At least a basic knowledge of Laravel package development is needed. This post is about how to give users full customization control of the vuejs part of your Laravel package. Let me explain.

The Challenge

Because it is impossible to make complete design decisions for everyone that is going to use your package, it’s better to build in a way that would give users opportunity to adjust the design you made to fit whatever need they have. Laravel provides this feature by allowing packages to publish their assets. These includes the view, assets, config, database. etc. So the user can have access to make changes as required.

You could also publish the vue files too. Publishing the vue files is a step in the right direction but then what? What about the modules required by the package and compiling them? I share my working solution in this post.

Lets assume we have a package with the folder structure below:

your-name/
package-name/
config/
database/
public/
resources
assets
components
example-component1.vue
example-component2.vue
app.js
admin.js
web.php
src
...
PackageServiceProvider.php
...
tests/
composer.json

Our vuejs files can be published to our application’s resources/assets/vendor/package-name with an execution of the publish command below:

php artisan vendor:publish --provider="YourName\PackageName\PackageServiceProvider" --tag="vue-components"

This is possible because of these lines in our PackageServiceProvider.php file

$this->publishes([    __DIR__ . '/../resources/assets' =>
resource_path('assets/vendor/package-name'
)], 'vue-components');

The code snippet above copies everything in our package resources/assets folder to our applications resources/assets/vendor/package-name. What next? Let’s take a look at the content of our package’s app.js file, it could help us determine what to do next.

//package-name app.js import VueSweetAlert from 'vue-sweetalert';
Vue.use(VueSweetAlert);
Vue.component('example-component1', require('./components/example-component1.vue'));
Vue.component('example-component2', require('./components/example-component2.vue'));
window.packageNameEvent = new Vue();

In the app.js above, we import all the modules we require, which is just one i.e. the vue-sweetalert plugin, register our vue components( example-component1 and example-component2 ) and we also have an event bus for our package. But its still not useful in our application yet if it’s not compiled down.

Compiling

This is first thing we need to do, compile it down. Laravel comes with just the thing we need, Laravel-mix. Laravel mix will help us compile everything in our application’s app.js file to something usable by the browser. So to compile our package’s vue assets, all we need to do is require our package’s app.js in our application’s app.js file and runnpm run dev

//application's app.jsrequire(‘./../vendor/package-name/app’)

Dependencies

The asset compilation we attempted above will be terminated because it won’t be able to find the vue sweealert plugin, this is a dependency required for our package to work. Lets fix that. The solution is to install the vue-sweetalert plugin. It’s obvious we are importing only one plugin, your own package can use as many modules as required. Just install all the npm modules your package requires into your application. And with that, our compilation should work now and our package users have full access to all our vue files to make customizations, meaning if any of the plugins we use is not okay it can be swapped for something else.

Admin Section

It’s possible your package has an admin section that uses different or additional modules and you even have some methods specific to the admin. Because of this you’ve decided to separate the front-end from the back-end assets. Well with this configuration it won’t we be as straightforward as requiring admin.js in your application’s app.js file. Our fictional package comes with an admin.js file. The snippet below is it’s content.

//admin.js window.axios = require('axios');
window.axios.defaults.headers.common['X-Requested-With'] = 'XMLHttpRequest';
let token = document.head.querySelector('meta[name="csrf-token"]');
if (token) {
window.axios.defaults.headers.common['X-CSRF-TOKEN'] = token.content;
} else {
console.error('CSRF token not found');
}
import VueSweetAlert from 'vue-sweetalert';window.Vue = require('vue');
Vue.use(VueSweetAlert);
Vue.prototype.$http = axios;
Vue.component('component-one', require('./components/component-one.vue'));
Vue.component('component-two', require('./components/component-two.vue'));
const app = new Vue({
el: '#app',
data () {
return {

}
}
methods: { }
})

What we would do here is link to it directly in our application's webpack.mix.js file. For the admin.js from our fictional package this will mean updating our application’s webpack.mix.js file to this:

//webpack.mix.jsmix.js('resources/assets/vendor/pakage-name/admin.js',
'public/vendor/package-name/js')

And of course you must link to it in your package blade files.

<script src=”{{ asset(‘vendor/package-name/js/admin.js’) }}”></script>

That’s the final step. Since the views are publishable, your user also has control here and therefore can decide to change things around.

Thanks for reading this. I hope you’ll find it helpful.

--

--