@alexander.k/vite-plugin-for-shopify

1.2.0 • Public • Published

vite-plugin-for-shopify

Vite plugin to generate a Shopify Liquid snippet with all Vite build entries.

Features

  • Generates a Liquid snippet (default: vite.liquid) in your theme's snippets directory
  • Cleans up old asset files in the output directory if they no longer exist in the new build (optional)
  • Supports dynamic imports in Shopify themes via a helper function

Installation

Add the plugin to your project:

npm install @alexander.k/vite-plugin-for-shopify --save-dev

Usage

Add the plugin to your vite.config.js

All options are optional:

import shopifyVitePlugin from '@alexander.k/vite-plugin-for-shopify'

export default {
  plugins: [
    shopifyVitePlugin({
      // Root path to your Shopify theme (default: './')
      themeRoot: './',
      // Name of the snippet file to generate (default: 'vite.liquid')
      snippetFilename: 'vite.liquid',
      cleanup: {
        // Regex to match files in the assets folder generated by Vite.
        // Old files matching this pattern will be removed after each build.
        // If not set, old files will not be deleted.
        fileNameRegex: /.*\.min\.(js|css)$/m
      }
    })
  ]
}

Note: The fileNameRegex option can also be provided at the root level for backward compatibility, but it is recommended to use the cleanup object.

Add the snippet to <head></head> once (no params)

This will add the helper function for dynamic imports to your code. For example, add to your theme.liquid file:

<html>
  <head>
    ...
    {% render 'vite' %}
  </head>
  <body>
    ...
  </body>
</html>

Use the snippet with entry name as in your Vite inputs

Example Vite config:

export default defineConfig({
  plugins: [
    shopifyVitePlugin()
  ],
  build: {
    rollupOptions: {
      input: {
        theme: './some-path/theme.js',
        coolSection: './some-path/coolSection.js',
        utils: './some-path/utils.js',
        pageStyles: './some-path/pageStyles.css'
      }
    }
  }
})

Default usage

{% liquid
  # You can also preload styles
  render 'vite', entry: 'theme', preload_stylesheet: true
  render 'vite', entry: 'pageStyles'
  render 'vite', entry: 'coolSection'
%}

Only styles or only JS

{% liquid
  # Only styles
  render 'vite', entry: 'theme', only_css: true
  # Only JS
  render 'vite', entry: 'coolSection', only_js: true
%}

Import mode for styles

<template class="component-template">
  <style>
    {% render 'vite', entry: 'theme', only_css: true, import_mode: true %}
    :root {
      display: block;
    }
    .wrapper {
      padding: 10px;
    }
  </style>
  <div class="wrapper">
    <button class="global-class-from-theme">Button</button>
  </div>
</template>

==> result:

<template class="component-template">
  <style>
    @import url("//www.your-store.com/cdn/shop/t/111/assets/theme.C0CJB5x1.min.css");
    :root {
      display: block;
    }
    .wrapper {
      padding: 10px;
    }
  </style>
  <div class="wrapper">
    <button class="global-class-from-theme">Button</button>
  </div>
</template>

Import mode for JS

<script type="module">
  {% render 'vite', entry: 'utils', only_js: true, import_mode: true %}
</script>

==> result:

<script type="module">
  import "//www.your-store.com/cdn/shop/t/111/assets/utils.C0CJB5x1.min.js";
</script>

Or named import:

<script type="module">
  {% render 'vite', entry: 'utils', only_js: true, import_mode: true, import_name: '{ getCart }' %}

  const cart = getCart()
</script>

==> result:

<script type="module">
  import { getCart } from "//www.your-store.com/cdn/shop/t/111/assets/utils.C0CJB5x1.min.js";

  const cart = getCart()
</script>

Or dynamic way:

<script type="module">
  const addClickHandler = async (items) => {
    {% render 'vite', entry: 'utils', only_js: true, import_mode: true, dynamic_import: true, import_name: '{ addToCart }' %}

    return await addToCart(items)
  }
</script>

==> result:

<script type="module">
  const addClickHandler = async (items) => {
    const { addToCart } = await import("//www.your-store.com/cdn/shop/t/111/assets/utils.C0CJB5x1.min.js");

    return await addToCart(items)
  }
</script>

How it works

  • The plugin generates a snippet file (default: vite.liquid) in your theme's snippets directory after each build.
  • The snippet contains all entry points from your Vite config and supports various usage modes (see above).
  • If the cleanup.fileNameRegex option is set, the plugin will remove old files in the output directory that do not exist in the new build.
  • The plugin automatically removes the manifest file after build (except in development mode).
  • For dynamic imports, a helper function is injected into the global scope to resolve asset URLs correctly.

Notes

  • The snippet is auto-generated. Do not edit it manually.
  • Make sure to commit the snippet file if you want to keep it in version control.
  • For more details, see the comments in the generated snippet or the plugin source code.

Package Sidebar

Install

npm i @alexander.k/vite-plugin-for-shopify

Weekly Downloads

6

Version

1.2.0

License

MIT

Unpacked Size

17 kB

Total Files

3

Last publish

Collaborators

  • alexander.k