Running an existing Vue app on Liferay DXP makes the app available as a
widget for using on site pages. You can adapt your existing Vue app,
but this doesn’t give you access to the bundler and its various loaders to
develop your project further in Liferay DXP. To have access to all of Liferay DXP’s
features, you must use the Liferay JS Generator and Liferay npm Bundler to merge
your files into a portlet bundle, update your static resource paths, and deploy
your bundle. The steps below demonstrate how to prepare a Vue app that uses
single file components (.vue
files) with multiple views.
Follow these steps:
-
Using npm, install the Liferay JS Generator:
npm install -g yo generator-liferay-js
-
Generate a Vue based portlet bundle project:
yo liferay-js
Select
Vue based portlet
and opt for generating sample code. Here’s the bundle’s structure:my-vue-portlet-bundle
assets/
→ CSS and resourcescss/
→ CSS not included in.vue
files.
features/
→ Liferay DXP bundle featureslocalization/
→ Resource bundlesLanguage.properties
→ Default language keys
settings.json
→ Placeholder System Settings
src/
→ JavaScript and Vue filesindex.js
→ Main module used to initialize the portlet
.babelrc
→ Babel configuration.npmbuildrc
→ Build configuration.npmbundlerrc
→ Bundler configurationpackage.json
→ npm bundle configurationREADME.md
-
Copy your app files, matching the types listed below, into your new project.
File type Destination Comments CSS assets/css/
Overwrite styles.css
.Static resources assets
Include resources such as image files here VUE and JS src
Merge your main component with the existing index.js
. More info on that below. -
Update your bundle to use portlet-level styling.
-
If you have internal CSS included with
<style>
tags in your.vue
files, import.index.css
in/assets/styles.css
. This is generated by the modified build script further down:@import '../index.css';
-
Import all custom CSS files (i.e. CSS not included in
.vue
files) through the CSS file (default isstyles.css
) your bundle’spackage.json
file sets for your portlet. Here’s the default setting:"portlet": { "com.liferay.portlet.header-portlet-css": "/css/styles.css", ... }
-
-
Update any static resource references to use the
web-context
value declared in your project’s.npmbundlerrc
file. Here’s the format:/o/[web-context]/[resource]
Here’s an example image resource:
<img alt="Vue logo" src="/o/vue-guestbook-migrated/logo.png">
-
Merge your entry module with
src/index.js
, following these steps to dynamically load components.-
Use Vue’s runtime + compiler module (
import Vue from 'vue/dist/vue.common';
) so you don’t have to process templates during build time. This is imported by default at the top of the file. -
Remove the sample content from the
main()
function (i.e. thenode
constant and its use), and replace it with your router code. -
Make these updates to the
new Vue
instance:- Remove the default data properties (the ones you just removed in the
sample content), and set the render element to
portletElementId
. This is required and ensures that your app is rendered inside the portlet. - Add the router.
- Add a render function that mounts your component wrapper to the Vue instance and displays it.
Your updated configuration should look like this:
new Vue({ el: `#${portletElementId}`, render: h => h(App), router })
- Remove the default data properties (the ones you just removed in the
sample content), and set the render element to
Your entry module
index.js
should look like this.import Vue from 'vue/dist/vue.common'; import App from './App.vue' import VueRouter from 'vue-router' //Component imports export default function main({portletNamespace, contextPath, portletElementId}) { Vue.config.productionTip = false Vue.use(VueRouter) const router = new VueRouter({ routes: [ { ... } ] }) new Vue({ el: `#${portletElementId}`, render: h => h(App), router }) }
-
-
Merge your app
package.json
file’sdependencies
anddevDependencies
into the project’spackage.json
, and replace thebabel-cli
andbabel-preset-env
dev dependencies with the newer"@babel/cli": "^7.0.0"
and"@babel/preset-env": "^7.4.2"
packages instead. Also include the"vueify": "9.4.1"
dev dependency. -
Update the
.babelrc
file to use@babel/preset-env
instead ofenv
:"presets": ["@babel/preset-env"]
-
If you’re using
.vue
files, replace the build script in thepackage.json
with the one below to usevue-cli-service
. The updated build script uses vue-cli to access the main entrypoint for the app (index.js
in the example below) and combines all the Vue templates and JS files into one single file namedindex.common.js
and generates anindex.css
file for any internal CSS included with<style>
tags in.vue
files:"scripts": { "build": "babel --source-maps -d build src && vue-cli-service build --dest build/ --formats commonjs --target lib --name index ./src/index.js && npm run copy-assets && liferay-npm-bundler", "copy-assets": "lnbs-copy-assets", "deploy": "npm run build && lnbs-deploy", "start": "lnbs-start" }
-
Update the
main
entry of thepackage.json
to match the new CommonJS file name specified in the previous step:"main": "index.common"
-
Finally, deploy your portlet bundle:
npm run deploy
Congratulations! Your Vue app is deployed and now available as a widget that you can add to site pages.
The liferay-npm-bundler confirms the deployment:
Report written to liferay-npm-bundler-report.html
Deployed my-vue-guestbook-1.0.0.jar to c:\git\bundles
The Liferay DXP console confirms your bundle started:
2019-03-22 20:17:53.181 INFO
[fileinstall-C:/git/bundles/osgi/modules][BundleStartStopLogger:39]
STARTED my-vue-guestbook_1.0.0 [1695]
Find your widget by selecting the Add icon () and navigating to Widgets and the category you specified to the Liferay Bundle Generator (Sample is the default category).