@cross-platform-tools/vite-plugin
TypeScript icon, indicating that this package has built-in type declarations

0.1.4 • Public • Published

✨ Cross Platform Tools ✨

Set of tools to help you build cross-platform libraries from a single codebase

@cross-platform-tools/vite-plugin

Vite plugin that abstracts out module resolutions so you can build for multiple platforms from a single codebase.

Button.potato.tsx, Button.tomato.tsx ---> dist/potato/Button.js, dist/tomato/Button.js, dist/types/Button.d.ts

Getting Started

Open in Stackblitz

or scaffold locally -

  • Scaffold an example node-edge-library

    npx degit saurabhdaware/node-edge-library node-edge-library
  • Install Dependencies

    pnpm install
  • Run the example of the library usage

    cd packages/node-edge-app
    node run.js # Runs the example with node bundle
    node --conditions=edge run.js # Runs the example with edge bundle

[!note]

The example is kept simple for better understanding of code. If your usecase requires you to build final bundles of app, you can also pass these conditions from resolve.conditions method in vite.

How does it work?

Module Resolutions in Build

@cross-platform-tools/vite-plugin package takes care of resolving extensions such as .node.ts, .client.ts, .xyz.ts and creates final bundles such as dist/node/, dist/client/, or dist/xyz.

Module Resolutions in Tests

It also takes care of resolving extensions for tests when used with vitest. So you can define your platform-specific tests with .client.test.ts, .node.test.ts, etc.

Base Library Setup

This plugin also takes care of basic things required to build a library such as type file generations for all platforms, base library configuration setup with vite, etc.

Manual Setup

This section explains the steps required to set up a library from scratch. Check out the Getting Started for Quick Start guide.

Step 1: Install the Vite Plugin

npm i --save-dev @cross-platform-tools/vite-plugin

Step 2: Add Vite Plugin to your configuration

// vite.config.ts
import { defineConfig } from "vite";
import { viteCrossPlatform } from '@cross-platform-tools/vite-plugin';

export default defineConfig({
  plugins: [
    viteCrossPlatform({ 
      // We call `vite build` multiple times for each platform
      platform: process.env.PLATFORM,
      // This can be any string that is used in filenames. 
      // E.g. something.node.ts and something.client.ts in this example
      supportedPlatforms: ['node', 'client'],
      lib: {
        entryDir: 'src',
        outDir: 'dist'
      } 
    }),
  ]
});

Step 2: Create files with extensions used in supportedPlatforms above

// src/getData.node.ts
export const getData = () => 1234;
// src/getData.client.ts
export const getData = () => 4321;
// src/index.ts
export { getData } from './getData';

Step 3: Add build scripts and exports to your package.json

{
  "scripts": "PLATFORM=node vite build && PLATFORM=client vite build",
  "exports": {
    "node": {
      "default": "./dist/node/production/index.js",
      "types": "./dist/node/types/index.d.ts"
    },
    "default": {
      "default": "./dist/client/production/index.js",
      "types": "./dist/client/types/index.d.ts"
    }
  }
}

You can follow the package.json exports documentation of node.js and export as per your use case.

Bundlers and tools have their own defined namespaces in exports from which they pick bundles. Such as React Native has react-native namespace, while most bundlers use the browser namespace for client bundling.

You can also define your custom namespace such as "xyz": "./path/to/bundle" and use it with node --condition=xyz ./file.js on consumer end or define it in your bundler (e.g. using resolve.conditions)


Thanks for checking this out! Do drop your feedback on Twitter (@saurabhdawaree).

Like my work? You can sponsor me from GitHub Sponsors @saurabhdaware

Package Sidebar

Install

npm i @cross-platform-tools/vite-plugin

Weekly Downloads

1

Version

0.1.4

License

MIT

Unpacked Size

9.12 kB

Total Files

6

Last publish

Collaborators

  • saurabhdaware