Search code examples
laravelviterollup

How do I completely disable chunking in Vite and Rollup?


I'm back in Laravel development after being out of practice since 2019ish. I'm more accustomed to Mix than to Vite but I like the @vite helpers in Blade. For this app I have to provide a Firebase service worker in the root public directory, accessible at https://example.com/firebase-messaging-sw.js. This is what my vite.config.js looks like:

import { defineConfig } from 'vite';
import laravel from 'laravel-vite-plugin';
export default defineConfig({
    plugins: [
        laravel({
            valetTls: 'whatever.test',
            input: [
                'resources/css/app.css',
                'resources/js/app.js',
                'resources/js/firebase-messaging-sw.js'
            ],
            refresh: true,
        })
    ]
});

The problem is that firebase-messaging-sw.js uses import statements to grab Firebase functions from node_modules, which also end up in the compiled public-facing file as minified gibberish. Since a service worker isn't referenced as a module, "import" statements fail. ALL I want is for that file to be compiled into one single JavaScript file with no imports in the final product. This is trivially easy with Mix:

const mix = require('laravel-mix');
mix.js('./build/firebase-messaging-sw.js', './public/firebase-messaging-sw.js');

But I'm already in too deep to switch to Mix at this point. What can I do to my configuration to make Vite output a single clean file, preferably without a hashed filename? I see this, but it assumes a much deeper knowledge of Rollup than I have, and I'm honestly not sure where the lines between Laravel/Vite/Rollup are drawn in this case. This seems like a very simple question but I can't find a recent answer.

Per this answer, I tried changing my vite.config.js to this:

export default defineConfig({

    build: {
        rollupOptions: {
          output: {
            manualChunks: {}
          },
        }
    },

    plugins: [
        laravel({
            valetTls: 'whatever.test',
            input: [
                'resources/css/app.css',
                'resources/js/app.js',
                'resources/js/firebase-messaging-sw.js'
            ],
            refresh: true,
        })
    ],

});

But this had no effect on Vite's output.


Solution

  • We can turn off chunking by dynamic imports with 'output.inlineDynamicImports: true`. The problem we have several inputs that doesn't support this options...

    I didn't find any better solution than building the inputs separately:

    • pass input file as an argument to vite-cli after -- (Vite doesn't support custom arguments)

    • dynamically change your Vite config to process only 1 input file at a time with inlineDynamicImports

    • set emptyOutDir: false so a build wouldn't delete files built with another build.


    The OP went with several config files which is a valid option too.
    How this can be done:
    How to build multiple bundles using Vite similar to Multi Compiler mode(multi config) in Webpack

    import { defineConfig } from 'vite';
    
    const input = process.argv[4]?.split('=')?.[1];
    if (input) {
        console.log('SINGLE INPUT PROVIDED: ' + input);
    }
    
    export default defineConfig(() => {
        return {
            build: {
                emptyOutDir: false,
                rollupOptions: {
                    input: input || ['main.js', 'test.js'],
                    output: {
                        [input ? 'inlineDynamicImports' : 'dummy']: true,
                        entryFileNames: input || ['main.js', 'test.js']
                    }
                },
            },
        };
    });
    

    My output:

    printf "test.js main.js" | xargs -d ' ' -P0 -I% npx vite build -- --input=%
    SINGLE INPUT PROVIDED: main.js
    SINGLE INPUT PROVIDED: test.js
    vite v4.3.9 building for production...
    vite v4.3.9 building for production...
    ✓ 5 modules transformed.
    ✓ 3 modules transformed.
    dist/test.js  0.95 kB │ gzip: 0.59 kB
    dist/assets/javascript-8dac5379.svg  1.00 kB │ gzip: 0.60 kB
    dist/assets/vite-4a748afd.svg        1.50 kB │ gzip: 0.77 kB
    dist/assets/main-48a8825f.css        1.24 kB │ gzip: 0.65 kB
    dist/main.js                         0.75 kB │ gzip: 0.43 kB
    ✓ built in 67ms
    ✓ built in 68ms