barrel / shopify-vite Goto Github PK
View Code? Open in Web Editor NEWModern frontend tooling for Shopify theme development using Vite for a best-in-class DX.
Home Page: https://shopify-vite.barrelny.com/
License: MIT License
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
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
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
.build.manifest
is string (custom file), the plugin cannot find it because the file is hardcoded to assets/.vite/manifest.json
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...
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 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"
}
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.
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!
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:
frontend/assets
before the folder is deletedfrontend/assets
folder as the public folderFor 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.
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
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
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
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.
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).
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.
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
can be string | boolean
true
value
server.httpServer?.address()
2a00:1450:4007:81a::2003
, ::1
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: [],
}),
],
};
I appreciate any recommendations or advise.
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.
Styles inside the red border have to be on top (they have higher priority):
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.
Look at docs https://shopify-vite.barrelny.com/guide/troubleshooting.html#how-to-cleanup-the-assets-folder
You mention this plugin https://www.npmjs.com/package/@by-association-only/vite-plugin-shopify-clean
But it doesn't support vite 5. And it seems like author is not going to do anything with it
May be this plugin would be better for this purpose
https://github.com/knjshimi/shopify-vite/tree/main/packages/vite-plugin-shopify-assets
Hey @montalvomiguelo, just checking if there's anything still needed for the release 3.0.0? Cheers!
When using vite-plugin-shopify
, after changing a liquid file, you often have to manually hard reload the page in order to see your changes. This also seems to be happening with the SEED theme.
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
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?
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.
If the port is in use, we need Vite to choose available port instead of exiting.
✅ 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.
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!
Hello,
I'm using tailwind on my boilerplate with "vite-plugin-shopify": "^2.2.1"
As a result :
I re-hit the save key on my IDE => My tw class get loaded.
Thus, the issue seems to appear when tailwind first init its class.
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: './'
}
});
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.
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!
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?
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
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.
With vite running, I do the following in vscode:
test.liquid
test
Result: Near instantly there is a test.section.liquid
file showing in the modules/test
dir
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.
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
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 :
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 ! :)
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?
Thanks for the new version of the plugin! While testing, I found a problem with using a custom name for snippet. It seems we also need to replace vite-tag
here
I'm not seeing how I would handle copying external scripts during dev. I tried https://www.npmjs.com/package/vite-plugin-static-copy but this also doesn't copy scripts when changed/added in dev.
The assets directory is cleaned out on build so they also can't be added there.
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!
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
needs to be created plugins: [
shopify({
+ additionalEntrypoints: ['frontend/foo.ts', 'bar.ts']
})
],
We would be able to load them like this:
sourceCodeDir
(frontend/) {%- render 'vite-tag' with '@/foo.ts' -%} # @ = frontend
themeRoot
{%- render 'vite-tag' with '/bar.ts' -%} # / = theme root
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:
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?
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.
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
└── theme
├── config
│ └── src
│ └── 001_theme_info.json
│ └── 002_other_fragments.json
│ └── sеttings_schema.json
└── theme
├── config
│ └── src
│ └── 001_theme_info.json
│ └── 002_colors.json
│ └── 003_typography.json
│ └── 004_cart.json
│ └── ...
│ └── sеttings_schema.json
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
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 :
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
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?
A declarative, efficient, and flexible JavaScript library for building user interfaces.
🖖 Vue.js is a progressive, incrementally-adoptable JavaScript framework for building UI on the web.
TypeScript is a superset of JavaScript that compiles to clean JavaScript output.
An Open Source Machine Learning Framework for Everyone
The Web framework for perfectionists with deadlines.
A PHP framework for web artisans
Bring data to life with SVG, Canvas and HTML. 📊📈🎉
JavaScript (JS) is a lightweight interpreted programming language with first-class functions.
Some thing interesting about web. New door for the world.
A server is a program made to process requests and deliver data to clients.
Machine learning is a way of modeling and interpreting data that allows a piece of software to respond intelligently.
Some thing interesting about visualization, use data art
Some thing interesting about game, make everyone happy.
We are working to build community through open source technology. NB: members must have two-factor auth.
Open source projects and samples from Microsoft.
Google ❤️ Open Source for everyone.
Alibaba Open Source for everyone
Data-Driven Documents codes.
China tencent open source team.