{{announcement.body}}
{{announcement.title}}

Vue JS Application Without Build

DZone 's Guide to

Vue JS Application Without Build

How to build a simple Vue JS web application without pains and complexities of a build process. This proposal shows a way to introduce a modern web framework in a gentle and gradual way, easy to grasp even for an unexperienced developer.

· Web Dev Zone ·
Free Resource

Introduction

People would often say how Vue JS or React are simple, even trivial.

Well... I for one disagree ;-). They're not simple. After all, they're widely used to build massive, often mission-critical systems. There's plenty to learn beyond these wildly optimistic Learn React in a Day courses. Their ecosystems are huge. Tooling is demanding. Documentation is extensive. It takes substantial effort to discover and understand best practices and efficient design patterns.

What's their appeal then? For me, it's their progressive character. Complexity is introduced into the project gradually, only when it becomes necessary. I can start with simple JavaScript, a few prerequisites, and without a complex build setup. Then, as my needs grow, I start adding new concepts and learn how to use them. Things such as modules, components, routing, state management, state propagation, async code, reactivity, server-side rendering — they all eventually come into picture. But only when their time comes, and only when I'm ready for them!

Source code for the article can be found at https://bitbucket.org/letsdebugit/minimalistic-vue

Simple Tools for Simple Projects

When I begin a new project, it's crucial that it's simple to start. Cognitive load of this profession is already hard enough. I don't need any more of it, unless truly necessary.

Equally important is that project setup stays simple, as long as the application remains simple. For many projects, all that I will ever need is a little smart engine behind a web page. Something to wire up a photo gallery. Something to fetch updates from an external source and keep the UI in sync. Why would I introduce TypeScript and webpack just for that? But Vanilla JS comes at a significant cost. I love having things such as state management, reactivity, and data bindings. They save so much time, and they help building a consistent UI.

Luckily, this is possible with progressive web frameworks. In the example below, I want to show how to introduce Vue JS and enjoy its powers in a simplest possible way.

Application Design

The example below is a tiny one-page web application. It has a header, content area and a footer. In the content area there's a message and a button. When user clicks on the button, the message changes:

simplified UI

As a prudent programmer, I want to properly structure my application from the very beginning. There are the following elements in the UI:

  • header
  • main area
  • footer

I'd love to have each of these defined as a separate component. I'd like to keep their code in separate modules, easy to identify and work with.

In a typical Vue JS setup, you'd use single-file .vue components for that. This unfortunately requires a build process based on webpack, rollup, etc. It turns out that you can get nearly the same experience without any build process! It maybe isn's as comprehensive as the original deal, but it's just fine for many simple scenarios. More important, it has none of complexities and dependencies introduced by a regular build process and CLI tools.

Project Structure

The project is structured as follows:

Plain Text


Our logical UI components are clearly reflected in the physical structure of the project.

Bootstrapping

When browser loads index.html, the following happens:

  •  Vue JS library is fetched from CDN repository at https://unpkg.com/vue
  •  Component stylesheets are fetched
  •  Application module is imported from index.js and executed

Notice how we used <script type="module"> to tell the browser that we're loading modern ES6 code with all the bells and whistles!

When index.js is executed, it imports subsequent modules which contain our components:

  • Content from /content/content.js
  • Header from /header/header.js
  • Footer from /footer/footer.js

Components

The components are not much different from regular Vue JS single-file components. They can have all the features and functionality of a Vue JS component, such as:

  • data
  • props
  • methods
  • computed properties
  • lifecycle events
  • slots
  • template with markup
  • etc.

Because there is no build process, our components have to be put together in a different way. Modern JavaScript features will help us here. Instead of bundling, we can simply import the required dependencies wherever needed. After all those years of mindless bundling browsers finally know how to import modules ;-) Then, instead of a <template> block we will use JS template literals.

Component code is structured as follows:

JavaScript


The main application component is defined in the index.js file. Its task is to assign custom HTML tags such as <app-header> or <app-footer> to all our components. 

JavaScript


These custom tags are then used to build our application UI in the index.html file. We ended up with a UI which is trivially simple to read:

HTML

Summary

In the end, we have nearly the full power of Vue JS without any complexities of a build process. To deploy this application we would simply copy the files to a web server. Then just hope that our visitors will use a decent browser ;-)

References

The article is also available at my blog Let's Debug It.

The complete source code can be found at https://bitbucket.org/letsdebugit/minimalistic-vue. Feel free to clone and reuse this code. Any suggestions or questions are most welcome!

All credits and thanks go to the creators of the awesome Vue JS framework.

Topics:
es6, javascript, vue framework, vue js, web application architecture, web development

Published at DZone with permission of Tomasz Waraksa . See the original article here.

Opinions expressed by DZone contributors are their own.

{{ parent.title || parent.header.title}}

{{ parent.tldr }}

{{ parent.urlSource.name }}