barrel / shopify-vite

Modern frontend tooling for Shopify theme development using Vite for a best-in-class DX.
https://shopify-vite.barrelny.com/
MIT License
293 stars 45 forks source link

vite.liquid: Template content exceeds 256 KB limit #100

Closed junaidkbr closed 1 year ago

junaidkbr commented 1 year ago

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
  }
})
montalvomiguelo commented 1 year ago

Did you try import.meta.glob ? I have this example that you could adjust as needed to load Vue components dynamically.

junaidkbr commented 1 year ago

Thanks Miquel. That's a neat solution. There're some side-effects of this approach but we can resolve those hopefully.

slavamak commented 1 year ago

@junaidkbr Just curious, what was the number of modules when you reached the limit?

junaidkbr commented 1 year ago

@slavamak For us, it was ~210 components. The actual component CSS and JS injections weren't that big of a deal but the preloading modules bombarded the vite.liquid file.

slavamak commented 1 year ago

Interesting, tried to break it on my side but no luck 😁 I guess there are additional conditions that make it happen.

ps. Did get to break this when the snippet contained a little over 3000 lines.