Coder Social home page Coder Social logo

barrel / shopify-vite Goto Github PK

View Code? Open in Web Editor NEW
210.0 20.0 34.0 7.1 MB

Modern frontend tooling for Shopify theme development using Vite for a best-in-class DX.

Home Page: https://shopify-vite.barrelny.com/

License: MIT License

TypeScript 74.24% CSS 0.25% JavaScript 4.07% HTML 21.44%
frontend-tooling integration shopify theme vite vite-plugin

shopify-vite's People

Contributors

montalvomiguelo avatar scottpolhemus avatar tuanpham-barrel avatar tuanpham-dev avatar wturnerharris avatar

Stargazers

 avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar

Watchers

 avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar

shopify-vite's Issues

Vite-Tag Path Delimiter Issue on Windows

I noticed that when running vite-plugin-shopify on Windows, the generated vite-tag.liquid includes the wrong path delimiter.
On windows it generates
{% assign path = vite-tag | replace: '~/', '../' | replace: '@/', '../' | replace: '@modules/', '..\..\modules/' | replace: '~modules/', '..\..\modules/' %}
while on macOS it generates
{% assign path = vite-tag | replace: '~/', '../' | replace: '@/', '../' | replace: '@modules/', '../../modules/' | replace: '~modules/', '../../modules/' %}
The usages of the windows path delimiter \ breaks the matching here and it seems instead always the unix path delimiter / should be used.

For Example vite-tag gets rendered like this: {% render 'vite-tag' with '@modules/hero-slider/hero-slider.js' %}
And the vite-tag replaces '@modules/' with '....\modules/' and then tries to match it below with '....\modules\hero-slider\hero-slider.js'

I've attached the example vite-tag.liquid here:
vite-tag.txt

Problem with build.manifest option

vite-tag.liquid is not generated if build.manifest option is false or string

  • manifest.json is required for generating vite-tag.liquid properly so the option build.manifest can not be false.
  • When build.manifest is string (custom file), the plugin cannot find it because the file is hardcoded to assets/.vite/manifest.json

HMR not working as expected

Hi there,

Whenever I save a file, Vite will reload the page. This breaks the HMR of Shopify. HMR does work, but Vite reloads the whole page after this has been done. After the reload it falls back to the state before saving the file.

Shopify CLI only reloads the full page if you save a JS file. I can imagine that we have to reload the page, since the frontend files are hosted on another IP. But this is not really a workable solution...

f0daf6c4-df6e-4a64-bd9b-67a126a3b1c1.mp4

Additional attribute in render

How can I render such strings?

<script id="EnableZoomOnHover-featured" src="{{ 'magnify.js' | asset_url }}" defer="defer"></script>
<link rel="stylesheet" href="{{ 'component-list-menu.css' | asset_url }}" media="print" onload="this.media='all'">

I think it's important feature

Adding `import shopifyModules from "vite-plugin-shopify-modules";` cause vite to failed

Adding import shopifyModules from "vite-plugin-shopify-modules"; cause an error on the vite/dev command.

The issue is also there if shopifyModules() is not declare in the plugin prop. and modules directory is not added to additionalEntrypoints (meaning that only add the import cause vite to failed.

Trace :

failed to load config from /../project/vite.config.js
error when starting dev server:
file:///../project/node_modules/vite-plugin-shopify-modules/dist/index.mjs:4
import { throttle } from "lodash";
         ^^^^^^^^
SyntaxError: Named export 'throttle' not found. The requested module 'lodash' is a CommonJS module, which may not support all module.exports as named exports.
CommonJS modules can always be imported via the default export, for example using:

import pkg from 'lodash';
const { throttle } = pkg;

Node v16.14.2

Part of my package.json:

  "type": "module",
  "engines": {
    "node": ">=16.14.2",
    "yarn": ">=1.22.17",
    "npm": ">=9.4.0"
  },
  "dependencies": {
    "@vitejs/plugin-legacy": "^4.0.1",
    "vue": "^3.2.45"
  },
  "devDependencies": {
    "@vitejs/plugin-vue": "^4.0.0",
    "env-cmd": "^10.1.0",
    "npm-run-all": "^4.1.5",
    "sass": "^1.44.0",
    "terser": "^5.16.3",
    "vite": "^4.1.0",
    "vite-plugin-shopify": "^0.0.12",
    "vite-plugin-shopify-modules": "^0.0.6"
  }

Running shopify and vite servers in parallel does not work following guide

package.json:

{
    "dev": "run-p -sr \"shopify:dev -- {@}\" \"vite:dev\" --",

    "build": "vite build",

    "deploy": "run-s \"build\" \"shopify:push -- {@}\" --",

    "shopify:dev": "shopify theme dev",

    "shopify:push": "shopify theme push",

    "vite:dev": "vite",

    "prettier": "prettier --write"
  }

If I try to run 'npm run dev' as outlined here the vite server successfully comes online, but the shopify server does not. Removing the "vite:dev" part of the command will successfully launch the shopify server when ran. I suspect I may just have a misunderstanding of how I should be using the npm run all command with argument passthrough... everything works fine when using 2 seperate terminals to run 'shopify theme dev' and 'vite' simultaneously.

image

Issue for theme app extensions

Hello!

Basically we are working on a theme app extension and when deploying, shopify complains that we can't have a json file in the assets folder because of the manifest.js file. Also we'd prefer to have a single js file that gets overwritten when we build instead of having a hash in the name with a new file every time.

Our plugin config is like that:

plugins: [
  shopify({
    entrypointsDir: dirname(fileURLToPath(import.meta.url)) + "/storefront",
    themeRoot: dirname(fileURLToPath(import.meta.url)) + "/../../extensions/theme-extension-name"
  })
]

It all works fine until we add the config for the manifest and the file name:

build: {
  manifest: false,
  rollupOptions: {
    output: {
      entryFileNames: "[name].js"
    }
  }
},

Whenever we add a build config the vite-tag.liquid snippet stops updating. Anything we can do about that? :)

Also, is it possible to have the script with a defer attribute in vite-tag.liquid?

Thanks!

Handling 3rd party app assets

I had to spend a little time reading documentation and figuring it out however there could also be better ways of doing this so I wanted to share and get feedback.

When using shopify's github integration the integration will sync back files created by other 3rd party apps into the sync folder. The problem was that the assets folder gets deleted and recreated with the frontend/entrypoints as well as public contents.

My Solution:

  1. Add build configuration for rollupOptions which will add an identifier to the generated filenames
  2. Copy all of the contents from the assets folder while excluding anything fitting our pattern into frontend/assets before the folder is deleted
  3. Update config to use the new frontend/assets folder as the public folder

For step 2, I used rollup-plugin-copy which supports negation patterns to excluded the automatically generated files which will be recreated by the shopify-vite plugin

Here is the example configuration:

import shopify from 'vite-plugin-shopify'
import copy from 'rollup-plugin-copy'

const namespace = 'vite'
export default {
  build: {
    rollupOptions: {
      output: {
        entryFileNames: `[name]-${namespace}-[hash].js`,
        chunkFileNames: `[name]-${namespace}-[hash].js`,
        assetFileNames: `[name]-${namespace}-[hash].[ext]`
      },
    }
  },
  publicDir: 'frontend/assets',
  plugins: [
    copy({
      targets: [
        {
          src: ['assets/*', `!**/*${namespace}*.*`], dest: "frontend/assets"
        }
      ]
    }),
    shopify()
  ]
}

Any feedback would be appreciated.

Style preloading not working

The project mentions to use:
{% render 'vite-tag' with 'theme.scss', preload_stylesheet: true %}

But the file vite-tag.liquid doesn't use the preload_stylesheet variable
{{ file_url | stylesheet_tag }}

Shouldn't it be something like that instead?
{{ file_url | stylesheet_tag: preload: preload_stylesheet }}
Shopify docs: https://shopify.dev/docs/api/liquid/filters/stylesheet_tag

Can you do something similar for the scripts as well?
https://shopify.dev/docs/api/liquid/filters/preload_tag
https://shopify.dev/docs/api/liquid/filters/script_tag

ERR_CERTIFICATE_AUTHORITY_INVALID with vite-plugin-basicssl

import { resolve } from 'node:path'
import shopify from 'vite-plugin-shopify'
import pageReload from 'vite-plugin-page-reload'
import basicSsl from '@vitejs/plugin-basic-ssl'
import fs from 'fs'

export default {
  clearScreen: false,
  server: {
    host: true,
    https: true,
    port: 3000
  },
  publicDir: resolve(__dirname, '../public'),
  plugins: [
    basicSsl(),
    shopify({
      // Root path to your Shopify theme directory (location of snippets, sections, templates, etc.)
      themeRoot: resolve(__dirname, '../shopify'),
      sourceCodeDir: resolve(__dirname, '../src'),
      // Additional files to use as entry points (accepts an array of file paths or glob patterns)
      entrypointsDir: resolve(__dirname, '../src/entrypoints'),
      // additionalEntrypoints: [],
      // Specifies the file name of the snippet that loads your assets
      snippetFile: 'vite-tag.liquid'
    }),
    pageReload('/tmp/theme.update', {
      delay: 1600
    })
  ],
  css: {
    postcss: resolve(__dirname, '../.config/postcss.config.js'),
  },
  build: {
    sourcemap: true
  }
}

npm run dev

image

Visiting https://localhost:3000 asks to approve unsigned certificate and advance. I can then see the shopify-vite landing page.

Visiting http://127.0.0.1:9292 fails to import my assets showing

image

Should I be viewing the shopify theme dev server on https? If so, how?

UPDATE:

I got things working by just changing my vite server host to localhost

  server: {
    host: 'localhost',
    https: true,
    port: 3000
  },

On initial load of the shopify dev server things would load properly, but after navigating anywhere it would just hang while attempting to fetch

http://my-store.myshopify.com/cdn/shopifycloud/shopify/assets/storefront/features-1c0b396bd4d054b94abae1eb6a1bd6ba47beb35525c57a217c77a862ff06d83f.js

I figured out that if I just block the requested URL things load properly, page reloads and everything. Not sure why this hangs but i'll investigate.

UPDATE: Closing and reopening my terminal per a suggestion I found seemed to fix the storefront request hanging. TLS related? What an adventure.

Shopify CDN Cache issues with CSS assets

Hi guys, again thanks for the amazing work on the vite-plugin-shopify.

I had css cache issues on production, and it seems it's due the changes introduced via 45a3e28 (Remove querystring from asset URLs).

https://github.com/barrel/barrel-shopify/blob/8619c4a8bb73fec3bda132e8e68d214ff3eff98d/packages/vite-plugin-shopify/src/html.ts#L162

I believe this was a fix for a Vue issue (#13), but maybe there's a way to solve both the cache and the Vue problems.

At the moment I'm using patch-package to work around this issue, but I imagine other people will have problems.

Issue with Hot Reload in Vite Plugin

I've been using your plugin for my theme app extension project recently, and overall, the HRM functionality has been working smoothly, greatly supporting the development of my application.

However, in the past few weeks, I have encountered some issues with HRM as hot reload is no longer functioning when I save my code. The browser console is displaying the following errors:

DOMException: Failed to execute 'define' on 'CustomElementRegistry': the name "x-counter" has already been used with this registry
    at preact_custom_element_esm_default (http://localhost:5173/node_modules/.vite/deps/preact-custom-element.js?v=5faff5d0:87:22)
    at http://localhost:5173/frontend/entrypoints/counter.jsx?t=1706782470620:48:1
client.ts:117 [hmr] Failed to reload /frontend/entrypoints/counter.jsx. This could be due to syntax errors or importing non-existent modules. (see errors above)

Here is my vite.config.js file:

import { defineConfig } from 'vite';
import shopify from 'vite-plugin-shopify';
import preact from '@preact/preset-vite';
import pageReload from 'vite-plugin-page-reload';

export default defineConfig({
  plugins: [
    shopify(),
    preact(),
    pageReload('/tmp/extension.update', {
      delay: 1800,
    }),
  ],
});

counter.jsx

import 'vite/modulepreload-polyfill';
import register from 'preact-custom-element';
import { useSignal } from '@preact/signals';
import Button from '@/components/Button.jsx';

const Counter = ({ start = 0 }) => {
  const count = useSignal(start);

  return (
    <div class='x-counter'>
      <p class='x-counter__count'>{count}</p>
      <Button onClick={() => count.value--}>-1</Button>
      <Button onClick={() => count.value++}>+1</Button>
    </div>
  );
};

register(Counter, 'x-counter', ['start'], { shadow: false });

package.json

{
  "name": "theme-extension",
  "private": true,
  "version": "1.0.0",
  "license": "UNLICENSED",
  "type": "module",
  "scripts": {
    "dev": "concurrently -r -k -P \"pnpm run shopify:dev {@}\" \"pnpm run vite:dev\" --",
    "build": "pnpm run vite:build && pnpm run shopify:build",
    "deploy": "pnpm run vite:build && pnpm run shopify:deploy",
    "vite:dev": "vite",
    "vite:build": "vite build",
    "shopify": "pnpm exec shopify",
    "shopify:dev": "shopify app dev --path ../../",
    "shopify:build": "pnpm exec shopify app build --path ../../",
    "shopify:deploy": "pnpm exec shopify app deploy --path ../../"
  },
  "dependencies": {
    "@preact/signals": "^1.2.1",
    "preact": "^10.17.1",
    "preact-custom-element": "^4.2.1"
  },
  "devDependencies": {
    "@preact/preset-vite": "^2.5.0",
    "concurrently": "^8.2.1",
    "vite": "^4.4.9",
    "vite-plugin-page-reload": "^0.1.0",
    "vite-plugin-shopify": "^2.2.0"
  }
}

I attempted to upgrade vite-plugin-shopify to version 3.0.0 and vite to version 5, but unfortunately, the issue persists.

I appreciate your assistance in resolving this matter. Wishing you a wonderful day, and thank you for your help.

server.host

  • The config for server.host can be string | boolean
  • When it's using a true value
    • The html should not output "true" as the name of the host
    • The html should output the address that the Vite server is using server.httpServer?.address()
  • When developers enter a custom address
    • The html should use that address e.g. 2a00:1450:4007:81a::2003, ::1

Screen Shot 2023-03-05 at 8 19 26 PM

SCSS Variables [vite:css] [sass] Undefined variable.

Hi,

I am struggling to get SCSS compilation to work when running the vite build command. SCSS files with global variables work great when running npm run dev. npm run build errors with [vite:css] [sass] Undefined variable.`

import shopify from 'vite-plugin-shopify';

export default {
  plugins: [
    /* Plugin options are not required, defaults shown */
    shopify({
      // Root path to your Shopify theme directory (location of snippets, sections, templates, etc.)
      themeRoot: './',
      // Front-end source code directory
      sourceCodeDir: 'frontend',
      // Front-end entry points directory
      entrypointsDir: 'frontend/entrypoints',
      // Additional files to use as entry points (accepts an array of file paths or glob patterns)
      additionalEntrypoints: [],
    }),
  ],
};

Screenshot 2023-03-07 at 3 32 11 PM

I appreciate any recommendations or advise.

Wrong CSS imports order in build mode

Hi everyone,

I have set up the plugin and almost everything works well, but I have faced an issue that I don't know how to solve in build mode (dev-mode works fine).

I have a Vue app on the order page that uses my own Vue component (Modal.vue).

My root component imports Modal.vue and then overwrites some styles of it. But the build is divided into chunks and the stylesheet of root component is being imported first (string 37 on screenshot). But it should have highest priority over other stylesheets. I don't know how to solve it.

image

Styles inside the red border have to be on top (they have higher priority):

image

My vite config:

import path from 'path';

// vite plugins
import vue from '@vitejs/plugin-vue';
import shopify from 'vite-plugin-shopify';
import cleanup from '@by-association-only/vite-plugin-shopify-clean';
import checker from 'vite-plugin-checker';

export default {
  base: '',
  resolve: {
    alias: {
      '@es': path.resolve(__dirname, 'src/widgets/sections/email-signature-editor'),
      '@bc': path.resolve(__dirname, 'src/widgets/sections/app--business-card-generator'),
      '@vuc': path.resolve(__dirname, 'src/shared/ui/vue-ui-components'),
      '@artlogo-design': path.resolve(__dirname, 'src/shared/ui/artlogo-design'),
    },
  },
  build: {
    emptyOutDir: false,
  },
  plugins: [
    checker({
      typescript: true,
    }),
    cleanup(),
    shopify({
      sourceCodeDir: 'src',
      entrypointsDir: 'src/app',
      additionalEntrypoints: ['**/*.build.ts', '**/*.build.js', '**/*.build.scss'],
    }),
    vue(),
  ],
};

Will appreciate any help.

Shopfiy HotReload not working with plugin

Hello,

Amazing plugin, but here is an issue:

When serving a shopify theme with the CLI:
shopify theme serve

Together with Vite + your plugin:
vite dev

And running on localhost:
http://127.0.0.1:9292

Then the HotReload SSE connection returns 404 - not found.

The changes made through css/scss or js is reloaded. But when changing liquid files such as sections it needs to be manually refreshed inorder to kick in. And with some delay.

If i don't run vite dev, the shopify HotReload works perfectly fine.

--

Update: Currently it's only happening in FireFox

vite liquid snippet always refer to localhost

Basically, when I run npm run build, which just run vite build, everything seems to work great in development but when I build, vite-tag.liquid still looks like:

{% comment %}
  IMPORTANT: This snippet is automatically generated by vite-plugin-shopify.
  Do not attempt to modify this file directly, as any changes will be overwritten by the next build.
{% endcomment %}
{% assign path = vite | replace: 'SRC/', '../' | replace: 'SCRIPTS/', '../assets/scripts/' | replace: 'STYLES/', '../assets/styles/' | replace: 'PARTIALS/', '../assets/styles/partials/' | replace: 'ENTRYPOINTS/', '../assets/scripts/entrypoints/' | replace: 'NM/', '../../node_modules/' | replace: '~/', '../' | replace: '@/', '../' %}
{% liquid
  assign path_prefix = path | slice: 0
  if path_prefix == '/'
    assign file_url_prefix = 'http://localhost:5173'
  else
    assign file_url_prefix = 'http://localhost:5173/src/entrypoints/'
  endif
  assign file_url = path | prepend: file_url_prefix
  assign file_name = path | split: '/' | last
  if file_name contains '.'
    assign file_extension = file_name | split: '.' | last
  endif
  assign css_extensions = 'css|less|sass|scss|styl|stylus|pcss|postcss' | split: '|'
  assign is_css = false
  if css_extensions contains file_extension
    assign is_css = true
  endif
%}
<script src="http://localhost:5173/@vite/client" type="module"></script>
{% if is_css == true %}
  {{ file_url | stylesheet_tag }}
{% else %}
  <script src="{{ file_url }}" type="module"></script>
{% endif %}

When I push the built files to github, and connect the store to that repository, I get no styling or anything really. The network tab indicates that it couldn't find the addressed source code because the snippet was saying to look at localhost

Here is my vite.config.js:

import shopify from 'vite-plugin-shopify'
import path from "path";

export default {
  css: {
    postcss: {
      plugins: [
        require('postcss-import'),
        require('autoprefixer'),
        require('postcss-nested'),
      ]
    }
  },
  resolve: {
    alias: {
      "SRC": path.resolve(__dirname, 'src'),
      "SCRIPTS": path.resolve(__dirname, 'src/assets/scripts'),
      "STYLES": path.resolve(__dirname, 'src/assets/styles'),
      "PARTIALS": path.resolve(__dirname, 'src/assets/styles/partials'),
      "ENTRYPOINTS": path.resolve(__dirname, 'src/assets/scripts/entrypoints'),
      "NM": path.resolve(__dirname, './node_modules'),
    }
  },
  plugins: [
    shopify({
      themeRoot: './',
      sourceCodeDir: 'src',
      entrypointsDir: 'src/entrypoints',
      additionalEntrypoints: [],
      snippetFile: 'vite.liquid'
    })
  ]
}

I would expect the liquid snippet to be updated with correct references to the assets. See anything I am doing wrong?

modulepreload for dynamic imports

If an additional entrypoint (vite.config.js: additionalEntrypoints: ['src/js/sections/**/*.js'],) has dynamic imports, is there a way to generate a modulepreload link for them?
For example in sections/hero.liquid:

{%- render 'vite-tag' with '@sections/hero.js' -%}

hero.js has a dynamic import: const { default: Splide } = await import('@splidejs/splide'); which Lighthouse is flagging as a candidate for preloading.

It seems like the entrypoint / module itself gets taken care of by the preload helper that is injected with the the vite-tag snippet, but dynamic imports aren't covered by the helper. I could be mistaken though! Any advice appreciated.

import.meta.glob + defineAsyncComponent not working build

✅ This works on development as it is fetched on dev server.
❌ Doesn't work on Production. ( Produces chunks per component as desired but ) No 404 files resource but stays blank

const components = import.meta.glob('./../components/*.vue')
for ( const path  in components) {
  const result = 'App'+_.upperFirst(_.camelCase(path.split('/').pop().replace(/\.\w+$/, '')))
  const modulesContent = components[path]
  app.component(result,  defineAsyncComponent(modulesContent))
}

✅ This 👇 works on both dev and production mode ( Produces single file with all components with it )

const componentFiles = import.meta.glob('./../components/*.vue',{ eager:true });
Object.entries(componentFiles).forEach(([path, m]) => {

  const componentName = 'App'+_.upperFirst(
    _.camelCase(path.split('/').pop().replace(/\.\w+$/, ''))
  );
  app.component(componentName, m.default)
})

I don't want to load all components at once since some components are not being used on specific pages.
Is there any configurations I missed? or?

I am using Vue 3.

Tailwind CSS styles not updating during Hot Module Reloading

Hi All,

First of all, awesome package!

I seem to be having an issue where the Tailwind CSS styles I am applying to HTML elements are not updating during hot module reloading. I believe I have all the requirements, however I am stuck on figuring out what may be missing.

In my /frontend/entrypoints directory i have the following inside main.css:

@tailwind base;
@tailwind components;
@tailwind utilities;

I've updated my dev command to the following:

{
    "version": "0.0.0",
    "private": true,
    "type": "module",
    "scripts": {
      "dev": "run-p -sr \"shopify:dev -- {@}\" \"vite:dev\" --", 
      "deploy": "run-s \"build\" \"shopify:push -- {@}\" --", 
      "shopify:dev": "shopify theme dev --live-reload full-page", 
      "vite:dev": "vite", 
      "shopify:push": "shopify theme push", 
      "build": "vite build"
    },
    "devDependencies": {
      "npm-run-all": "^4.1.5", 
      "vite": "^4.2.1",
      "vite-plugin-shopify": "^2.0.2"
    }
  }

vite.config.js:

import { defineConfig } from 'vite'
import shopify from 'vite-plugin-shopify'

export default defineConfig({
  plugins: [
    shopify()
  ],
  build: {
    emptyOutDir: false
  }
})

Attached is a quick loom recording: https://www.loom.com/share/aac1c4ea848646e3a5e4f88f63cb9b21?sid=fb82e0b3-895f-45cd-8a29-c48129b2cc50

Appreciate any help!

Tailwind & Vite Hot Reload Not working on the first hot reload

Hello,

I'm using tailwind on my boilerplate with "vite-plugin-shopify": "^2.2.1"

To reproduce :

  • I write a plein text in a liquid file,
  • I write a tailwind class that do not exist in my entire code yet (so not generated in the main tailwind css file yet),
  • I save in my IDE, launching the reload.

As a result :

  • My tw class doesn't "appear" on the screen,
  • My plain text is successfully loaded,

I re-hit the save key on my IDE => My tw class get loaded.

Edge cases

  • When I remove the tw class, the first load will correctly remove it,
  • When I re-add this same tw class, the first load will correctly add it,

Thus, the issue seems to appear when tailwind first init its class.

vite.config.ts

import { defineConfig } from 'vite';
import checker from 'vite-plugin-checker';
import shopify from 'vite-plugin-shopify';
import pageReload from 'vite-plugin-page-reload';
import postcss from './postcss.config';

// https://vitejs.dev/config/
export default defineConfig({
  css: {
    postcss
  },
  plugins: [
    checker({
      typescript: true
    }),
    shopify({
      // Root path to your Shopify theme directory (location of snippets, sections, templates, etc.)
      themeRoot: './',
      // Front-end source code directory
      sourceCodeDir: 'src',
      // Front-end entry points directory
      entrypointsDir: 'src/entrypoints',
      // Additional files to use as entry points (accepts an array of file paths or glob patterns)
      additionalEntrypoints: [],
      // Specifies the file name of the snippet that loads your assets
      snippetFile: 'vite-tag.liquid'
    }),
    pageReload(
      [
        './assets/**/*',
        './config/**/*',
        './layout/**/*',
        './locales/**/*',
        './public/**/*',
        './sections/**/*',
        './snippets/**/*',
        './templates/**/*'
      ],
      { delay: 3000 }
    )
  ],
  publicDir: 'public',
  build: {
    emptyOutDir: true,
    outDir: './assets',
    assetsDir: './'
  }
});

postcss.config.ts

import postcssImport from 'postcss-import';
import tailwindcssNesting from 'tailwindcss/nesting/index.js';
import tailwindcss from 'tailwindcss';
import autoprefixer from 'autoprefixer';
import tailwindConfig from './tailwind.config';

const config = {
  plugins: [
    postcssImport(),
    tailwindcssNesting,
    tailwindcss(tailwindConfig),
    autoprefixer
  ]
};

export default config;

Ideally, when saving a liquid file I would need to "wait" until the tailwind css file finish to load on the local vite server.

I was hopping vite-plugin-page-reload to solve the issue with the newly added debounce function, but I might have misunderstood the goal of this package.

Vue 3 Example

Hi,
Could you please create an example of your plugin using Vue.js 3?
I'm having a hard time figuring out how to configure it

I really like your plugin! great job!

thanks!

What could be causing slow reloads

Hi there! it's me again. I was wondering if their is any reason reloads are pretty slow? 20seconds>? Have uninstalled - installed and updated the cli.

issue

React support

Hi, is there support for React? We saw the Vue example branch, and we're trying to recreate that with React, but it doesn't seems to work. Do you have any example for that?

Possible CORS errors in Console

When running the server, I get a bunch of CORS errors, both for my own files and Shopify files.

For my files, I find I need to open the link, accept the security notice and then reload to get rid of those CORS errors.

Is this expected?

CleanShot 2023-10-25 at 9  46 28@2x

vite-tag path resolution

  • For internal aliasses
    • It should resolve aliases for the frontend directory: @, ~
    • It should resolve the alias created by vite-plugin-shopify-modules: @modules, ~modules
    • It should resolve / to themeRoot #11
  • It should not resolve any other alias

See the vue example in #13

Update docs and add more in depth example

Hey guys, absolutely amazing work on this plugin I am blown away.

I'm doing a proof of concept right now and I'm working through an example with the dawn theme. I noticed your example scripts are still using the serve command which no longer exists, replaced with dev.

If you guys ever need help with shopify apps I built a shopify app boilerplate called OSB. So that should be a fair trade for this amazing package haha

https://michaelgibbons.info/OSB/#/

version 0.0.6 and up of vite-plugin-shopify-modules no longer creating symlinks

Firstly, this set of vite plugins, the seed theme, and the support you're offering on issues is fantastic - thank you so much!

I've been using version 0.0.4 of vite-plugin-shopify-modules for the last few months to great success. I've just updated vite-plugin-shopify to the latest version with no issues, I but I've found that each version after 0.0.5 of the modules plugin breaks the functionality for me.

What happens in 0.0.5

With vite running, I do the following in vscode:

  • create a section called test.liquid
  • create a directory within the modules directory called test

Result: Near instantly there is a test.section.liquid file showing in the modules/test dir

in versions > = 0.0.6

  • steps as above

Result: test.section.liquid is NOT created

by running npx vite -d I see output like this:

vite:hmr [file change] sections/test7.liquid +6s
vite:hmr [no modules matched] sections/test7.liquid +0ms

I've briefly tested with snippets, and with creating the test.section.liquid in the module first but neither working as expected.

my setup

I simplified by setup down when testing, and the issue presents with this setup

import { defineConfig } from 'vite';
import viteShopify from 'vite-plugin-shopify';
import viteShopifyModules from 'vite-plugin-shopify-modules';

export default defineConfig({
  plugins: [
    viteShopify({
      themeRoot: './',
      sourceCodeDir: 'src',
      entrypointsDir: 'src/entrypoints',
      additionalEntrypoints: ['modules/**/*.(js|scss)']
    }),
    viteShopifyModules()
  ]
});
`

other module versions
"vite": "^4.0.4",
"vite-plugin-shopify": "^1.0.2"

node version 18.15.0
OSX 13.2.1


Basic setup with `vite-plugin-page-reload` not working - ESM error

Hi,

So I saw your (new package) [https://github.com/barrel/shopify-vite/tree/vite-plugin-page-reload%400.1.0/packages/vite-plugin-page-reload] about page-reload and wanted to give it a try as it looks like targeting my issue about refreshing pages.

My setup is simple :

...
    "vite": "^4.4.11",
    "vite-plugin-page-reload": "^0.1.0",
    "vite-plugin-shopify": "^2.2.1"
...

And my config too :

import { defineConfig } from 'vite';
import checker from 'vite-plugin-checker';
import shopify from 'vite-plugin-shopify';
import pageReload from 'vite-plugin-page-reload';

// https://vitejs.dev/config/
export default defineConfig({
  plugins: [
    checker({
      typescript: true
    }),
    shopify({
      // Root path to your Shopify theme directory (location of snippets, sections, templates, etc.)
      themeRoot: './',
      // Front-end source code directory
      sourceCodeDir: 'src',
      // Front-end entry points directory
      entrypointsDir: 'src/entrypoints',
      // Additional files to use as entry points (accepts an array of file paths or glob patterns)
      additionalEntrypoints: [],
      // Specifies the file name of the snippet that loads your assets
      snippetFile: 'vite-tag.liquid'
    }),
    pageReload(
      [
        './assets',
        './config',
        './layout',
        './locales',
        './public',
        './sections',
        './snippets',
        './templates'
      ],
      {
        delay: 1600
      }
    )
  ],
  publicDir: 'public',
  build: {
    emptyOutDir: true,
    outDir: './assets',
    assetsDir: './'
  }
});

After running yarn dev, aka :

  • "dev": "run-p vite:serve shopify:serve",
    • "vite:serve": "vite"
    • "shopify:serve": "shopify theme dev --store=***.myshopify.com",

I'm getting the following error :

Failed to resolve "vite-plugin-page-reload". This package is ESM only but it was tried to load by `require`. See http://vitejs.dev/guide/troubleshooting.html#this-package-is-esm-only for more details. [plugin externalize-deps]

   node_modules/esbuild/lib/main.js:1373:27:
     1373 │         let result = await callback({
          ╵                            ^

   at file:///*****/node_modules/vite/dist/node/chunks/dep-68d1a114.js:66275:43
   at requestCallbacks.on-resolve (/Users/*****/node_modules/esbuild/lib/main.js:1373:28)
   at handleRequest (/*****/node_modules/esbuild/lib/main.js:729:19)
   at handleIncomingPacket (/****/node_modules/esbuild/lib/main.js:755:7)
   at Socket.readFromStdout (/***/node_modules/esbuild/lib/main.js:679:7)
   at Socket.emit (node:events:514:28)
   at addChunk (node:internal/streams/readable:324:12)
   at readableAddChunk (node:internal/streams/readable:297:9)
   at Readable.push (node:internal/streams/readable:234:10)
   at Pipe.onStreamRead (node:internal/stream_base_commons:190:23)

 This error came from the "onResolve" callback registered here:

   node_modules/esbuild/lib/main.js:1292:20:
     1292 │       let promise = setup({
          ╵                     ^

   at setup (file:///****node_modules/vite/dist/node/chunks/dep-68d1a114.js:66250:27)
   at handlePlugins (/*****/node_modules/esbuild/lib/main.js:1292:21)
   at buildOrContextImpl (*****/node_modules/esbuild/lib/main.js:978:5)
   at Object.buildOrContext (//node_modules/esbuild/lib/main.js:786:5)
   at //node_modules/esbuild/lib/main.js:2177:15
   at new Promise (<anonymous>)
   at Object.build (//node_modules/esbuild/lib/main.js:2176:25)
   at build (//node_modules/esbuild/lib/main.js:2025:51)
   at bundleConfigFile (file:////node_modules/vite/dist/node/chunks/dep-68d1a114.js:66201:26)

 The plugin "externalize-deps" was triggered by this import

   vite.config.ts:4:23:
     4 │ import pageReload from 'vite-plugin-page-reload';
       ╵                        ~~~~~~~~~~~~~~~~~~~~~~~~~

failed to load config from //vite.config.ts
error when starting dev server:
Error: Build failed with 1 error:
node_modules/esbuild/lib/main.js:1373:27: ERROR: [plugin: externalize-deps] Failed to resolve "vite-plugin-page-reload". This package is ESM only but it was tried to load by `require`. See http://vitejs.dev/guide/troubleshooting.html#this-package-is-esm-only for more details.
   at failureErrorWithLog (//node_modules/esbuild/lib/main.js:1649:15)
   at //node_modules/esbuild/lib/main.js:1058:25
   at runOnEndCallbacks (//node_modules/esbuild/lib/main.js:1484:45)
   at buildResponseToResult (//node_modules/esbuild/lib/main.js:1056:7)
   at //node_modules/esbuild/lib/main.js:1085:16
   at responseCallbacks.<computed> (/****/node_modules/esbuild/lib/main.js:703:9)
   at handleIncomingPacket (//node_modules/esbuild/lib/main.js:762:9)
   at Socket.readFromStdout (/node_modules/esbuild/lib/main.js:679:7)
   at Socket.emit (node:events:514:28)
   at addChunk (node:internal/streams/readable:324:12)
error Command failed with exit code 1.

As I simply followed a trivial setup, multiple people might get this error, I'm wondering how to fix this issue ?

Keeping myself available for any help ! :)

Trouble rendering media on dev server

Hey all,

I'm just giving this plugin my first go and feel like I must be doing something wrong in relation to the dev server forwarding. Images ( product + section data uploads ) rendered using the image_url filter are not able to be accessed from my local host.

The url rendered looks like this:
http://my-ip-address:9292/cdn/shop/files/image.jpg?crop=center&v=1682971077&width=1500

The same image renders perfectly fine when previewing the dev theme from the Shopify domain. What am I doing wrong here?

PublicDir: how to handle static assets (images)

Hi guys, thanks for the work you put into this, it’s looking great!

I just wanted to know if there is a particular reason for forcing the publicdir to false, and how can I handle static assets.

As a basic example, I want to store a favicon in my repo, and my initial idea was using the vite publicdir, as it would be compiled (moved) to the shopify assets folder.

I tried to set the publicdir in vite config, but vte plugin shopify overrides it, forcing it to be ignored.

How/where can I put static images or other assets that I don’t want to be transformed, so they still are copied to the assets folder (and pushed to shopify)?

Would it be possible to add it as a plugin option, instead of forcing it?

Thanks again!

vite.liquid: Template content exceeds 256 KB limit

Hi,

We migrated a Shopify theme from Barrel CLI's codebase to Shopify Vite. The setup we have right now compiles all component JS and Vuejs files along with their peer dependencies (one file for each) to the assets folder. Due to the nature of many files for each component and the files being hashed by Vite, we couldn't figure out how to load module JS files dynamically with the [data-module] approach.

To overcome this, we included the JS files in each component snippet using the vite.liquid snippet in each component. Now that we have ~150 components and all the dependencies stuffed into the compiled vite.liquid, the size goes over 256 KB limit Shopify has on theme files. We get the following error:

Error: snippets/vite.liquid, Validation failed: Template content exceeds 256 KB limit.

I don't know where to go from here. Any directions would be appreciated. I'd love to have the modules load dynamically but don't know how.

// vite.config.js
import { defineConfig } from 'vite'
import shopify from 'vite-plugin-shopify'
import basicSsl from '@vitejs/plugin-basic-ssl'
import vue from '@vitejs/plugin-vue2'
import copy from 'rollup-plugin-copy'
import { resolve } from 'node:path'
import cleanup from '@by-association-only/vite-plugin-shopify-clean'

export default defineConfig({
  server: {
    host: true,
    https: true,
    port: 3000
  },
  publicDir: 'public',
  resolve: {
    alias: {
      '@modules': resolve('frontend/modules'),
      '@js': resolve('frontend/js'),
      '@css': resolve('frontend/css'),
      'vue': 'vue/dist/vue.esm.js'
    }
  },
  plugins: [
    basicSsl(),
    cleanup(),
    shopify({
      snippetFile: 'vite.liquid',
      additionalEntrypoints: [
        'frontend/modules/**/*.js',
        // 'frontend/modules/**/*.css'
      ]
    }),
    copy({
      targets: [
        { src: 'public/*', dest: 'assets' },
      ],
      flatten: true,
      hook: 'buildStart'
    }),
    vue(),
  ],
  css: {
    postcss: {
      plugins: [
        require('precss'),
        require('postcss-mixins'),
        require('postcss-inline-svg'),
        require('postcss-color-function'),
        require('autoprefixer')({
          browsers: [
            'last 3 versions',
            'iOS >= 8',
            'Safari >= 8',
            'ie 11'
          ]
        }),
        require('postcss-automath'),
        require('postcss-hexrgba'),
        require('postcss-extend'),
        require('postcss-each'),
        require('postcss-critical-split')({
          'output': process.env.NODE_ENV === 'production' ? 'rest' : 'input',
        })
      ]
    },
  },
  build: {
    emptyOutDir: false,
    sourcemap: true
  }
})

additionalEntrypoints functionality needs to be improved

  1. Additional entrypoints are being registered properly but, there is no way to load them in the theme
  2. Documentation for additionalEntrypoints needs to be created
  plugins: [
    shopify({
+     additionalEntrypoints: ['frontend/foo.ts', 'bar.ts']
    })
  ],

We would be able to load them like this:

  • When they're relative to sourceCodeDir (frontend/)
  {%- render 'vite-tag' with '@/foo.ts' -%} # @ = frontend 
  • When they're relateive to the root of the theme themeRoot
  {%- render 'vite-tag' with '/bar.ts' -%}  # / = theme root

vite-client.liquid snippet

Thank you so much for the work you're doing here! This is incredibly helpful as we are in the process of redeveloping the dev tools we use to create official premium themes. From our testing this seems to be the best approach we have come across, and we're working on a variation of a structure used at https://github.com/montalvomiguelo/hydrogen-theme that has the island architecture concept.

The one roadblock that I anticipate us facing when getting through Shopify's very strict review process is the empty vite-client.liquid file that gets left behind and the render tag reference in layout/theme.liquid.

On my end, I'm contemplating making a few different changes:

  1. Customizing our build/package scripts that manually strip out the empty snippet and the render tags for 'vite-client'
  2. Forking the package to concatenate the vite-client snippet into the vite-tag snippet

Right now I'm leaning to the 2nd option even though it would result in the client script tag being duplicated in each of the vite-tag snippets—only in development.

<script src="http://localhost:5173/@vite/client" type="module"></script>

Instead of forking the package would you be open to official options to get around having an empty vite-client snippet and render reference?

theme css file is not loading in app extension

Hi. Thanks for your great plugin. It really helped me a lot.

I found out an issue today. theme css file is not loading in app extension when I make a build. JS file is working and it is appearing in the dev store, but CSS styles are not loading. However it's working well when I'm developing using pnpm dev but when I deploy the extension to Shopify, CSS is not working.

I had to do a tricky workaround for now and manually add theme.css file in the block liquid file and it's working this way.

Any idea what would be the issue?

Here is my vite configs:

import path from "path"
import { defineConfig } from 'vite'
import shopify from 'vite-plugin-shopify'
import react from '@vitejs/plugin-react'
import cleanup from '@by-association-only/vite-plugin-shopify-clean';

export default defineConfig({
  plugins: [
    shopify({
      themeRoot: 'extensions/app-extension',
    }),
    cleanup({
      manifestFileName: 'manifest.json',
      themeRoot: 'extensions/app-extension',
    }),
    react(),
  ],
  resolve: {
    alias: {
      "@": path.resolve(__dirname, "./frontend"),
    },
  },
})

Thanks in advance.

Theme settings in one source file

Hi guys, thanks for your work with the vite plugins for shopify! It looks very exciting! I really want to try to use this in my next project with the implementation of dynamic imports that I saw in the hydrogen-theme @montalvomiguelo. Many thanks!

I also had attempts to create something similar (without vite or something) with import maps, but I never got around to finishing it, although it works fine (with polyfills)

Anyway. I created this issue because I would like to add some functionality to the vite-plugin-shopify-theme-settings plugin. Maybe it would also be helpful to someone else.

I like the idea that we use information from the package or options to dynamically replace this in the theme at build time. But I'm not comfortable separating all the settings into separate files, because there can be quite a lot of them. I'd like to have an option to disable or enable splitting by file but leave the ability to replace the information.

OR, I would like to be able to use an array of fragments (objects) in the file, not just one object, as now

Expected Behavior

└── theme
    ├── config
    │   └── src
    │       └── 001_theme_info.json
    │       └── 002_other_fragments.json
    │   └── sеttings_schema.json

Actual Behavior

└── theme
    ├── config
    │   └── src
    │       └── 001_theme_info.json
    │       └── 002_colors.json
    │       └── 003_typography.json
    │       └── 004_cart.json
    │       └── ...
    │   └── sеttings_schema.json

Example

Here:
https://github.com/barrel/barrel-shopify/blob/8619c4a8bb73fec3bda132e8e68d214ff3eff98d/packages/vite-plugin-shopify-theme-settings/src/index.ts#L54-L56

Add something like that. Can be with the option to enable/disable

const schemaFragments = await Promise.all(
  sourceFiles.map(async (fileName) =>
    JSON.parse(await fs.readFile(path.join(schemaSourceDir, fileName), 'utf-8'))
  )
)

const settingsSchema = schemaFragments.reduce(
  (schema, fragment) => schema.concat(fragment),
  []
)

Does it make sense? Let me know what you think:) Thanks

Vite tag is ignoring Shopify CDN disk cache logic by using the filter `asset_url | split: '?' | first `

Hello,

I upgraded the plugin to the lastest version and I got some issues cause of the liquid filter used in the vite-tag snippet :
asset_url | split: '?' | first

Indeed removing the versioning after the ? makes our website requesting the same asset name, and thus the Shopify CDN for the current theme (cf asset_url) keep delivering outdated assets.
Ex :

  • Create my_script.js
  • Build and push your theme
  • Edit my_script.js
  • Build and push and override your theme using last version of the plugin.
  • --> You will see in your network tab that the url is hitting the CDN returning a disk cache version, thus you don't see your changes on the my_script.js file (the DOM either!).

My solution was to downgrade the plugin to "vite-plugin-shopify": "^0.0.5", ; which was a version I used on another project and it works perfectly as the vite-tag snippet do not use the split from asset_url | split: '?' | first

Could you guys do something about it ?
Haven't got the time to PR it

Though, why such a choice for the vite tag snippet?

Regards
Iska

Stripped script and stylesheet version numbers breaks Shopify cache

Within the vite-tag.liquid file that is generated on build, the plugin strips the version query parameter. This makes it so any CSS or JS changes pushed up to an already existing theme don't reflect on the front end.

{{ 'dist__theme.js' | asset_url | split: '?' | first }}

Above is the code that does this for scripts. Is there any specific reason for this? Can it be updated to be this: {{ 'dist__theme.js' | asset_url }}? Or maybe an option to do so?

Recommend Projects

  • React photo React

    A declarative, efficient, and flexible JavaScript library for building user interfaces.

  • Vue.js photo Vue.js

    🖖 Vue.js is a progressive, incrementally-adoptable JavaScript framework for building UI on the web.

  • Typescript photo Typescript

    TypeScript is a superset of JavaScript that compiles to clean JavaScript output.

  • TensorFlow photo TensorFlow

    An Open Source Machine Learning Framework for Everyone

  • Django photo Django

    The Web framework for perfectionists with deadlines.

  • D3 photo D3

    Bring data to life with SVG, Canvas and HTML. 📊📈🎉

Recommend Topics

  • javascript

    JavaScript (JS) is a lightweight interpreted programming language with first-class functions.

  • web

    Some thing interesting about web. New door for the world.

  • server

    A server is a program made to process requests and deliver data to clients.

  • Machine learning

    Machine learning is a way of modeling and interpreting data that allows a piece of software to respond intelligently.

  • Game

    Some thing interesting about game, make everyone happy.

Recommend Org

  • Facebook photo Facebook

    We are working to build community through open source technology. NB: members must have two-factor auth.

  • Microsoft photo Microsoft

    Open source projects and samples from Microsoft.

  • Google photo Google

    Google ❤️ Open Source for everyone.

  • D3 photo D3

    Data-Driven Documents codes.