npm package discovery and stats viewer.

Discover Tips

  • General search

    [free text search, go nuts!]

  • Package details

    pkg:[package-name]

  • User packages

    @[username]

Sponsor

Optimize Toolset

I’ve always been into building performant and accessible sites, but lately I’ve been taking it extremely seriously. So much so that I’ve been building a tool to help me optimize and monitor the sites that I build to make sure that I’m making an attempt to offer the best experience to those who visit them. If you’re into performant, accessible and SEO friendly sites, you might like it too! You can check it out at Optimize Toolset.

About

Hi, 👋, I’m Ryan Hefner  and I built this site for me, and you! The goal of this site was to provide an easy way for me to check the stats on my npm packages, both for prioritizing issues and updates, and to give me a little kick in the pants to keep up on stuff.

As I was building it, I realized that I was actually using the tool to build the tool, and figured I might as well put this out there and hopefully others will find it to be a fast and useful way to search and browse npm packages as I have.

If you’re interested in other things I’m working on, follow me on Twitter or check out the open source projects I’ve been publishing on GitHub.

I am also working on a Twitter bot for this site to tweet the most popular, newest, random packages from npm. Please follow that account now and it will start sending out packages soon–ish.

Open Software & Tools

This site wouldn’t be possible without the immense generosity and tireless efforts from the people who make contributions to the world and share their work via open source initiatives. Thank you 🙏

© 2024 – Pkg Stats / Ryan Hefner

vite-plugin-multi-device

v1.0.1

Published

Vite plugin for build application for multiple devices

Downloads

29

Readme

Vite plugin for multiple device builds

Build your application for multiple devices with Vite and eliminate dead codes with rollup.

This plugin builds your project in two different directories, and after that you can serve these directories based on user-agent header, subdomains or etc.

For ease of development, you can run the vmd command that runs multiple vite servers simultaneously and automatically forwards the request to one of them based on user agent.

Features

  • Framework aware (examples added with react, vuejs and svelte)
  • Tree shakable code through rollup
  • Configurable for adding more devices like tablet
  • Separating based on filenames
  • Separating based on If/else branches
  • Testable code through mocking window.DEVICE
  • Dev Server with device auto detection

Installation

This plugin only works with Vite >= 2

$ npm install -D vite-plugin-multi-device
// Or
$ yarn add -D vite-plugin-multi-device

Add to your vite.config.js:

import vue from '@vitejs/plugin-vue';
import multiDevice from 'vite-plugin-multi-device';

export default {
  plugins: [vue(), multiDevice()],
};

Now you should define DEVICE environment variable before running your dev server to specify which device are you willing to target.

For more ease of use, you can use vmd command to run a hybrid dev server to automatically detects the device based on user-agent

// package.json
{
  "scripts": {
    "dev": "vmd", // Run dev server with auto detection feature 
    "build": "vmd build", // Build project per device
    "start": "vmd start" // Run a production-ready node.js server
  }
}

Getting Started

There are two ways to code for different devices

  • Using if/else branches
  • Using separate files

Using if/else branches

Simply use window.DEVICE.mobile or window.DEVICE.desktop variable to detect user device.

You can configure to support more devices in multidevice.config.js. or you can change the identifier to something other than window.DEVICE.mobile (eg: __MOBILE__)

React Example:

// App.jsx
export function App() {
    return (
      <div>This is { window.DEVICE.desktop ? 'Desktop device' : 'Mobile device' }</div>
    )
}

Vuejs Example:

<template>
    <!-- inside vue templates -->
    <div v-if="DEVICE.mobile">This is mobile</div>

    <!-- VNode render branches will be eliminated by rollup and will not exist in final bundle, we explain it later -->
    <div v-if="DEVICE.desktop">This is desktop</div>
</template>

<script>
export default {
    mounted() {
        if (window.DEVICE.mobile) {
           console.log('Hi mobile user!')
        }
    }
}
</script>

Do not use DEVICE directly or dynamically.

window.DEVICE.mobile // ok

const myVar = 'mobile'

window.DEVICE[myVar] // won't work

window.DEVICE['mobile'] // won't work

Object.keys(window.DEVICE) // won't work

Using separate files

All files ending with .{device}.{extension} will take precedence to be used. eg: MyComponent.mobile.js or MyStyle.desktop.css

<!-- App.vue -->
<template>
   <div>
     <AppHeader />
   </div>
</template>

<script>
import AppHeader from './AppHeader.vue'

export default {
    components: {
        AppHeader
    }
}
</script>
<!-- AppHeader.vue -->
<template>
   <div>
     Desktop Header
   </div>
</template>
<!-- AppHeader.mobile.vue -->
<template>
   <div>
     <!-- This takes precendence on mobile build -->
     Mobile Header
   </div>
</template>

Also works with these packages:

Building application

You can change your package.json build commands to something like the example below.

{
    "scripts": {
        "build:desktop": "cross-env NODE_ENV=production DEVICE=desktop vite build --outDir=dist/desktop",
        "build:mobile": "cross-env NODE_ENV=production DEVICE=mobile vite build --outDir=dist/mobile",
        
        "build": "vmd build", // or simply use vmd command to build all devices.

        "start": "vmd start" // production ready node.js server (but you can write your own)
    }
}

Serving website

You could write your own Nodejs http server to serve the outputs to users based on regex, or use a configured nginx server.

There is a simple production ready server based on express, that switches automatically between devices. To use it, simply build your project with this structure: dist/DEVICE then run vmd start command.

Configuration

// multidevice.config.js
module.exports = {
    devices: {
      mobile: /Mobile|iP(hone|od|ad)|Android|BlackBerry|IEMobile|Kindle|NetFront|Silk-Accelerated|(hpw|web)OS|Fennec|Minimo|Opera M(obi|ini)|Blazer|Dolfin|Dolphin|Skyfire|Zune/,
    },
    fallback: 'desktop',

    // returns the identifiers that should be replaced. by default these two are considered
    replacement: (device) => ['DEVICE.' + device, 'window.DEVICE.' + device],

    // specifies how to transform a path to the device version path like: /src/app.js -> /src/app.mobile.js
    resolvePath: (path, device) => path.replace(/\.([^?/\\]+)(\?.*)?$/, `.${device}.$1$2`),

    // Environment variable to detect device (build command)
    env: 'DEVICE'
};