Browserify transform for single-file Vue components

Related tags

Miscellaneous vueify
Overview

vueify-fork npm version

Browserify transform for Vue.js components, with scoped CSS and component hot-reloading.

NOTE: master branch now hosts version ^9.0, which only works with Vue ^2.0. Vueify 8.x which works with Vue 1.x is in the 8.x branch.

This transform allows you to write your components in this format:

// app.vue
<style>
  .red {
    color: #f00;
  }
</style>

<template>
  <h1 class="red">{{msg}}</h1>
</template>

<script>
export default {
  data () {
    return {
      msg: 'Hello world!'
    }
  }
}
</script>

You can also mix preprocessor languages in the component file:

// app.vue
<style lang="stylus">
.red
  color #f00
</style>

<template lang="jade">
h1(class="red") {{msg}}
</template>

<script lang="coffee">
module.exports =
  data: ->
    msg: 'Hello world!'
</script>

And you can import using the src attribute:

<style lang="stylus" src="style.styl"></style>

Under the hood, the transform will:

  • extract the styles, compile them and insert them with the insert-css module.
  • extract the template, compile it and add it to your exported options.

You can require() other stuff in the <script> as usual. Note that for CSS-preprocessor @imports, the path should be relative to your project root directory. Starting in 7.0.0, @import in LESS, SASS and Stylus files can be either relative to your build tool root working directory, or to the file being edited. Or one can set import paths in options.

Usage

npm install vueify --save-dev
browserify -t vueify -e src/main.js -o build/build.js

And this is all you need to do in your main entry file:

// main.js
var Vue = require('vue')
var App = require('./app.vue')

new Vue({
  el: '#app',
  render: function (createElement) {
    return createElement(App)
  }
})

In your HTML:

<body>
  <div id="app"></div>
  <script src="build.js"></script>
</body>

If you are using vueify in Node:

var fs = require("fs")
var browserify = require('browserify')
var vueify = require('vueify')

browserify('./main.js')
  .transform(vueify)
  .bundle()
  .pipe(fs.createWriteStream("bundle.js"))

Building for Production

Make sure to have the NODE_ENV environment variable set to "production" when building for production! This strips away unnecessary code (e.g. hot-reload) for smaller bundle size.

If you are using Gulp, note that gulp --production does not affect vueify; you still need to explicitly set NODE_ENV=production.

ES2015 with Babel

Vueify is pre-configured to work with Babel. Simply install Babel-related dependencies:

npm install\
  babel-core\
  babel-preset-es2015\
  --save-dev

Then create a .babelrc:

{
  "presets": ["es2015"]
}

And voila! You can now write ES2015 in your *.vue files. Note if you want to use ES2015 on normal *.js files, you will also need babelify.

You can also configure babel with the babel field in vue.config.js, which will take the highest priority.

Enabling Other Pre-Processors

For other pre-processors, you also need to install the corresponding node modules to enable the compilation. e.g. to get stylus compiled in your Vue components, do npm install stylus --save-dev.

These are the preprocessors supported by vueify out of the box:

PostCSS

Vueify uses PostCSS for scoped CSS rewrite. You can also provide your own PostCSS plugins! See config section below for an example.

Configuring Options

Create a vue.config.js file at where your build command is run (usually the root level of your project):

module.exports = {
  // configure a built-in compiler
  sass: {
    includePaths: [...]
  },
  // provide your own postcss plugins
  postcss: [...],
  // register custom compilers
  customCompilers: {
    // for tags with lang="ts"
    ts: function (content, cb, compiler, filePath) {
      // content:  content extracted from lang="ts" blocks
      // cb:       the callback to call when you're done compiling
      // compiler: the vueify compiler instance
      // filePath: the path for the file being compiled
      //
      // compile some TypeScript... and when you're done:
      cb(null, result)
    }
  }
}

Example using custom PostCSS plugin:

var cssnext = require('cssnext')

module.exports = {
  postcss: [cssnext()]
}

Alternatively, if you are using vueify in Node and don't want to create a vue.config.js file:

var fs = require("fs")
var browserify = require('browserify')
var vueify = require('vueify')

// apply custom config
vueify.compiler.applyConfig({
  // ...same as in vue.config.js
})

browserify('./main.js')
  .transform(vueify)
  .bundle()
  .pipe(fs.createWriteStream("bundle.js"))

Or simply pass configuration object to vueify (in Node) (for instance to set sass search paths as in the following example):

var fs = require("fs")
var browserify = require('browserify')
var vueify = require('vueify')

browserify('./main.js')
  .transform(vueify, {
    sass: {
      includePaths: [...]
    },
    // ...same as in vue.config.js
  })
  .bundle()
  .pipe(fs.createWriteStream("bundle.js"))

Scoped CSS

When a <style> tag has the scoped attribute, its CSS will apply to elements of the current component only. This is similar to the style encapsulation found in Shadow DOM, but doesn't require any polyfills. It is achieved by transforming the following:

<style scoped>
.example {
  color: red;
}
</style>
<template>
  <div class="example">hi</div>
</template>

Into the following:

<style>
.example[_v-1] {
  color: red;
}
</style>
<template>
  <div class="example" _v-1>hi</div>
</template>

Scoped CSS Notes

  1. You can include both scoped and non-scoped styles in the same component.

  2. The following will be affected by both the parent's scoped CSS and the child's scoped CSS:

  • A child component's root node
  • Content inserted to a child component via <slot>

Hot Reload

To enable hot component reloading, you need to install the browserify-hmr plugin:

npm install browserify-hmr --save-dev
watchify -p browserify-hmr index.js -o bundle.js

You can scaffold a hot-reload enabled project easily using vue-cli and the this template.

CSS Extraction

By default, the CSS in each component is injected into the page using a <style> tag. This works well in most scenarios and enables CSS hot-reloading during development. However, in some cases you may prefer extracting all component CSS into a single file for better performance. To do that, you will need to add the CSS extraction browserify plugin.

Via CLI:

browserify -t vueify -p [ vueify/plugins/extract-css -o dist/bundle.css ] main.js

Via API:

browserify('./main.js')
  .transform('vueify')
  .plugin('vueify/plugins/extract-css', {
    out: 'dist/bundle.css' // can also be a WritableStream
  })
  .bundle()

This only works for vueify 9+. For Vue 1.x / vueify 8.x you can use vueify-extract-css.

Building for Production

When building for production, follow these steps to ensure smaller bundle size:

  1. Make sure process.env.NODE_ENV === "production". This tells vueify to avoid including hot-reload related code.

  2. Apply a global envify transform to your bundle. This allows the minifier to strip out all the warnings in Vue's source code wrapped in env variable conditional blocks.

Compiler API

The compiler API (originally vue-component-compiler) is also exposed:

var compiler = require('vueify').compiler

// filePath should be an absolute path
compiler.compile(fileContent, filePath, function (err, result) {
  // result is a common js module string
})

Syntax Highlighting

Currently there are syntax highlighting support for Sublime Text, Atom, Vim, Visual Studio Code and Brackets. Contributions for other editors/IDEs are highly appreciated! If you are not using any pre-processors in Vue components, you can also get by by treating *.vue files as HTML in your editor.

Changelog

Please see the Releases page for changes in versions ^9.0.0.

License

MIT

You might also like...
Ft transcendence - A single-page website to play pong, with a chat and an account system implemented

Welcome to my ft_transcendence repository 👋 ⭐️ The aim of this project is to bu

Frontend Mentor - Huddle Landing Page with Single Introductory Section Solution

Solution to the Huddle Landing Page Hero Section challenge by Frontend Mentor. Built with Vue+ TypeScript + UnoCSS + Vite.

A wrapper for Google Analytics to be used in web clients, oriented to single page applications

This is a wrapper for Google Analytics to be used in web clients, oriented to single page applications (something that google doesn't do oob), like automatically reporting requests performance, navigation links, redux plugin etc

Auto compile vue file on save

vue-autocompile package Auto compile vue file on save. Add the parameters on the first line of the vue file. out (string): relative path to html file

Vue Web Component for formatting email message based on CSV file content
Vue Web Component for formatting email message based on CSV file content

Vue Web Component for formatting email message based on CSV file content). Sample backend (Laravel package): laravel-personalised-email-sender

This app is used to record keyboard or mouse events, during which the keyboard or mouse events can be exported as a file with a toca suffix
This app is used to record keyboard or mouse events, during which the keyboard or mouse events can be exported as a file with a toca suffix

This app is used to record keyboard or mouse events, during which the keyboard or mouse events can be exported as a file with a toca suffix. And read this file through the playback function of this app for playback and reproduction.

Composable components for rendering fake (progressive) content like facebook in vue
Composable components for rendering fake (progressive) content like facebook in vue

vue-content-placeholders Vue addon for rendering fake content while data is fetching to provide better UX and lower bounce rate. 💿 Installation via n

tsParticles - Easily create highly customizable particles animations and use them as animated backgrounds for your website. Ready to use components available for React, Vue.js (2.x and 3.x), Angular, Svelte, jQuery, Preact, Inferno. 🎡 A component for rendering Vue components with live editor and preview.
🎡 A component for rendering Vue components with live editor and preview.

Vuep (vue playground) 🎡 A component for rendering Vue components with live editor and preview. Links Docs: https://cinwell.com/vuep/ An online playgo

Owner
Iván
Iván
A require hook for loading single-file vue components in node

A require hook for loading single-file vue components in node. Useful for testing without having to spin up web browsers!

Ken Powers 61 Oct 22, 2021
Adds support to Brunch for pre-compiling single file Vue components

Vue Brunch Adds support to Brunch for pre-compiling single file Vue components. Installation For 2.x support, use the master branch... npm install vue

Nathaniel Blackburn 78 May 29, 2021
A Vue.js 2 component to transform and download a json in csv format

A Vue.js 2 component to transform and download a json in csv format

Nemanja Gajic 0 Oct 10, 2019
📑 Transform texts with RegExp like a Pro.

ReX Transform texts with RegExp like a Pro. Go to App Motivation Sometimes you need to do some clean up or transform for texts in batches. You can eit

Anthony Fu 91 Jul 11, 2022
🌟 DataFormsJS 🌟 A minimal JavaScript Framework and standalone React and Web Components for rapid development of high quality websites and single page applications.

?? Welcome to DataFormsJS! Thanks for visiting! ?? ?? ?? ?? ?? ?? 中文 (简体) 欢迎来到 DataFormsJS Español Bienvenido a DataFormsJS Português (do Brasil) Bem

DataFormsJS 156 Dec 8, 2022
A fullscreen components for vue2, supports single page applications

Quick start @hyhello/vue-fullscreen The @hyhello/vue-fullscreen component for vue2, supports single page applications.

Hyhello 2 Mar 28, 2022
A single Vue 3 hook which can be used to communicate between an iFrame and its parent via postMessage IPC

Embedded iFrame IPC for Vue 3 @evilkiwi/embed provides a single Vue 3 hook which can be used to communicate between an iFrame and its parent via postM

Evil Kiwi 29 Dec 17, 2022
Simple Trivia Service - a Serverless Single- and Multi-player Trivia Game

Simple Trivia Service - a Serverless Single- and Multi-player Trivia Game This example application shows how to build both single and multiplayer game

AWS Samples 110 Jan 3, 2023
🚀 Install and update Among Us mods with a single click

English • Deutsch Among Us Mod Manager Install and update 6 Among Us mods with a single click* *on PC. Only the Steam version is tested, but other one

Moritz Ruth 12 Feb 21, 2022
OSI helps you to track your all open-source Internships and Program in a single place ⚡

OSI helps you to track your all open-source Internships and Program in a single place ⚡

Rohan kumar 39 Jan 2, 2023