Using Vue.js
WordPress MVC (WPMVC) flexibility allows developers to freely add progressive frameworks, like Vue or React, into its assets compilation cycle.
This article will describe shortly how to configure your WordPress MVC project to work with Vue.js.
Step 1: Install dependencies
You will need to add several NPM package dependencies, the first one is webpack
, this package will let you compile .vue
components. The following commands will install webpack
packages in your project and save them as dependencies:
npm install webpack --save npm install webpack-cli --save
The second one will be vue
. The following command will install vue
package in your project and save them as a dependency:
npm install vue --save
The third group of dependencies will be those needed by webpack
to compile .vue
components, compile SASS or SCSS styles, and generate .js
and .css
needed for the browser. The following commands will install the packages in your project and save them as dependencies:
npm install @babel/core --save npm install @babel/preset-env --save npm install babel-loader --save npm install css-loader --save npm install mini-css-extract-plugin --save npm install node-sass --save npm install sass-loader --save npm install vue-loader --save npm install vue-style-loader --save npm install vue-template-compiler --save
Step 2: Create assets folder structure
Vue components and applications are “raw” and need to be included in WPMVC build cycle.
To preserve the structure given in WPMVC, you will create your uncompiled Vue files in the /assets/raw/vue
folder. Inside you will create an empty init.js
file and the following folders /apps
, /components
and /mixins
.
The following example shows the structure described above:
- /apps + /assets + /raw - /css - /js - /sass + /vue - /apps - /components - /mixins - init.js
/apps
: Holds all Vue applications that you might create for your project./components
: Holds all.vue
components that you might create and might want to provide to your applications./mixins
: Holds any vue mixin that you might create for your components.init.js
Is the script used to initialize a global variable and any other global setting needed in your project.
Step 3: Define init.js
Open /assets/raw/vue/init.js
and paste the following code:
/** * Vue init script. * @version 1.0.0 */ /** * myApp will hold all your Vue applications. * @var {object} */ window.myApp = {};
window.myApp
will hold all your Vue applications during execution, meaning that will be able to access them through the browser. You can change myApp
to your namespace or something that suits you and your project better.
Note: init.js
isn’t required to run your applications, the benefit of this script is to help us configure your Vue commons in just one place.
Step 4: Create HelloWorld.vue component
Create a new file named HelloWorld.vue
inside /assets/raw/vue/components
and paste the following code in it:
<template> <div class="hello-world"> {{message}} </div> </template> <style lang="scss"> .hello-world { color: red; } </style> <script> export default { name: 'hello-world', props: { message: { required: true, type: String, }, }, }; </script>
The code above is a simple “Hello world” component that shows the message requested as a property (or HTML attribute).
Step 5: Create a demo.js application
The component created in the step above needs an application in order to be used.
Create a new file named demo.js
inside /assets/raw/vue/apps
and paste the following code in it:
import HelloWorld from './../components/HelloWorld.vue'; /** * Demo application. * @version 1.0.0 */ window.myApp.demo = Vue.createApp( { components: { HelloWorld, }, } ); window.myApp.demo.mount('#demo');
Notice how the example above is creating a new Vue application in window.myApp.demo
, if you changed myApp
in “Step 5” then you will need to change it here as well.
Notice how HelloWorld.vue
is imported and added as a component.
Step 6: Add webpack compilation
Create a new file named webpack.config.js
at the root of your project (same path where package.json
is located) and paste the following code in it:
// webpack.config.js const { VueLoaderPlugin } = require('vue-loader'); const MiniCssExtractPlugin = require( 'mini-css-extract-plugin' ); const webpack = require( 'webpack' ); const path = require( 'path' ); /** * Webpack configuration file. * @version 1.0.0 */ module.exports = { mode: 'production', entry: { 'vue-init': './assets/raw/vue/init.js', 'vue-demo': './assets/raw/vue/apps/demo.js', }, output: { filename: '[name].js', path: path.resolve( __dirname, 'assets/js' ), publicPath: './assets/js', }, module: { rules: [ { test: /\.vue$/, loader: 'vue-loader', }, { test: /\.js$/, loader: 'babel-loader', }, { test: /\.css$/, use: [ 'vue-style-loader', { loader: MiniCssExtractPlugin.loader, options: { filename: '[name].css', chunkFilename: '[id].css', path: path.resolve( __dirname, 'assets/css' ), publicPath: './assets/css', } }, 'css-loader', ] }, { test: /\.scss$/, use: [ 'vue-style-loader', MiniCssExtractPlugin.loader, 'css-loader', 'sass-loader', ] }, ] }, plugins: [ new VueLoaderPlugin(), ], resolve: { alias: { // Vue 2 //'vue$': 'vue/dist/vue.common.js', // Vue 3 'vue$': 'vue/dist/vue.esm-bundler.js', }, }, };
This webpack configuration file will compile your .vue
components, applications, and dependencies into JavaScript and CSS (browser-ready) files.
The compiled files will be put inside /assets/js
and /assets/css
folders, same as what WPMVC does with other asset files.
Entries
The entry
property inside the webpack configuration file indicates which files need compilation.
module.exports = { ... entry: { 'vue-init': './assets/raw/vue/init.js', 'vue-demo': './assets/raw/vue/apps/demo.js', }, ... };
The example above indicates that the files you want webpack to compile are the init.js
file and demo.js
application file.
The expected output would be 1 Javascript file for init.js
(this file does not output any styling), and 1 Javascript file and 1 CSS file for demo.js
:
/assets/js/vue-init.js
/assets/js/vue-demo.js
/assets/css/vue-demo.css
Step 7: Add to WPMVC compilation cycle
You need to add the following entry in the scripts
section of your package.json
file in order for NPM and WPMVC to know that webpack is executable:
{ ..., "scripts": { "webpack": "webpack --hide-modules" } }
WPMVC will detect that the webpack.config.js
file exists and will execute the script line defined above during its compilation cycle.
Step 8: Add Vue dependency and a watch
Step 7 will compile your Vue assets, but the browser will need Vue in order to run them, therefore you will need to include it to your project as an asset.
Paste the following code in your projects gulpfile.js
file (after // START - CUSTOM TASKS
line):
config.prescripts = ['vendor-js']; /** * Vendor JS */ gulp.task('vendor-js', function() { return gulp.src([ // Vue 2 // './node_modules/vue/dist/vue.min.js', // Vue 3 './node_modules/vue/dist/vue.global.prod.js', ]) .pipe(gulp.dest('./assets/js')); });
The task vendor-js
will copy dependencies from NPM’s /node_modules
folder into your project’s /assets
for visibility. The config.prescripts = ['vendor-js']
line adds the task into WPMVC compilation process (before any JavaScript file in /assets/raw
is processed).
Paste the following code in your projects gulpfile.js
file (after the code above):
/** * Vue watch. */ gulp.task('watch-vue', async function () { gulp.watch([ './assets/raw/vue/**/*.vue', './assets/raw/vue/components/**/*.vue', './assets/raw/vue/**/*.js', ], gulp.series('webpack')); });
The task watch-vue
adds a new watch command that will allow gulp
to watch any changes in your Vue code and proceed to compile it automatically.
Run the following command at the root of your project to watch vue:
gulp watch-vue
Step 9: Run WPMVC compilation cycle
Run the following command at the root of your project:
gulp dev
The command above should run the WPMVC compilation process, including your added customizations to support Vue.
The following files should be created as output:
/assets/js/vue.min.js
/assets/js/vue-init.js
/assets/js/vue-demo.js
/assets/css/vue-demo.css
Note: gulp build
and gulp deploy
will also consider these customizations.
Step 10: Enqueue assets
Finally, you need to enqueue the assets into WordPress. You will use WPMVC auto-enqueue system for this.
Add the following to your /app/Config/app.php
configuration file:
return [ ..., 'autoenqueue' => [ 'assets' => [ /* vue 2 [ 'id' => 'vue', 'asset' => 'js/vue.min.js', 'version' => '2.6.14', 'footer' => true, ], */ [ 'id' => 'vue', 'asset' => 'js/vue.global.prod.js', 'version' => '3.2.47', 'footer' => true, ], [ 'id' => 'vue-init', 'asset' => 'js/vue-init.js', 'dep' => ['vue'], 'footer' => true, ], [ 'id' => 'vue-demo', 'asset' => 'js/vue-demo.js', 'dep' => ['vue-init'], 'footer' => true, ], [ 'id' => 'vue-demo', 'asset' => 'css/vue-demo.css', 'footer' => 'all', ], ], ], ];
The configuration above will auto-enqueue all assets, you should be ready to view it in a browser.
UPDATED 2023: Troubleshooting
- If npm is indicating the
gulp
andgulp-wpmvc
are missing, runnpm install
again. - If you run into the error “missing fs/promises” then probably you will need to switch or download the latest version of npm. Make sure to delete the path
/node_modules
as well. - You may require python 3 and
python2
. For python 2, you can download version 2.7 and rename python.exe into python2.exe.