Numerous Panicky Mimes

    vite-plugin-multi-device
    TypeScript icon, indicating that this package has built-in type declarations

    1.0.1 • Public • Published

    vite-plugin-multi-device 🚀

    logo

    One codebase, Multiple outputs


    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'
    };

    Keywords

    none

    Install

    npm i vite-plugin-multi-device

    DownloadsWeekly Downloads

    0

    Version

    1.0.1

    License

    MIT

    Unpacked Size

    632 kB

    Total Files

    13

    Last publish

    Collaborators

    • sasanfarrokh