javascript - is it possible to run a rollup plugin without an input file (in a multi bundle instance)? - Stack Overflow

I have a situation where I am bundling multiple files via rollup cli an example of this is available in

I have a situation where I am bundling multiple files via rollup cli an example of this is available in documentation.

I export an array of bundles like so:

export default [
    {
        input: 'packages/A/index.js',
        output: {
            name: '[name]Bundle',
            file: '[name].umd.js',
            format: 'umd'
        }
    },
    {
        input: 'packages/B/index.js',
        output: {
            name: '[name]Bundle',
            file: '[name].umd.js',
            format: 'umd'
        }
    }
];

And then I have a function that adds a mon config to each bundle (think plugins) so something like:

import path from "path";

import alias from '@rollup/plugin-alias';
import resolve from '@rollup/plugin-node-resolve';


const augment = configs => {

    const generateAlias = (symbol, location) => {
        return {
            find: symbol,
            replacement: path.resolve(process.cwd(), location)
        };
    }

    const entries = [
        generateAlias("@", "src/"),
        generateAlias("~", "src/assets/scss/"),
        generateAlias("#", "src/assets/img/"),
        generateAlias("%", "config/"),
    ];

    const plugins = [
        alias({
            entries
        }),
        resolve({ browser: true }),
    ];

    return configs.map(entry => {
        return {
            ...entry,
            plugins
        }
    });
}

export {
    augment
}

And the I wrap the above exported array in augment like:

const bundles = [/* above example */];

export default augment(bundles);

Now this all works fine, but I have two plugins that I don't actually want to apply to each bundle I just want to run them once all the bundles have built, those two plugins are; rollup-plugin-serve and rollup-plugin-workbox now neither of these actually have anything to do with any of the files being bundled, and make no sense to instantiate more than once.

What I would like to do as part of the augment function to to append them to the end of the returned array something like:

const exportedArray = configs.map(/* function from above */);

exportedArray.push(...[
        {
                plugins: [
                        serve({
                                host,
                                port,
                                contentBase: 'dist/'
                        })
                ]
        }
]);

return exportedArray;

And this would not contain an input, I have tried the above and rollup plains, the alternative option would be to add these plugins to the final bundle on the array, I just prefer the idea of instantiating them without them being tied to a particular bundle.

I have a situation where I am bundling multiple files via rollup cli an example of this is available in documentation.

I export an array of bundles like so:

export default [
    {
        input: 'packages/A/index.js',
        output: {
            name: '[name]Bundle',
            file: '[name].umd.js',
            format: 'umd'
        }
    },
    {
        input: 'packages/B/index.js',
        output: {
            name: '[name]Bundle',
            file: '[name].umd.js',
            format: 'umd'
        }
    }
];

And then I have a function that adds a mon config to each bundle (think plugins) so something like:

import path from "path";

import alias from '@rollup/plugin-alias';
import resolve from '@rollup/plugin-node-resolve';


const augment = configs => {

    const generateAlias = (symbol, location) => {
        return {
            find: symbol,
            replacement: path.resolve(process.cwd(), location)
        };
    }

    const entries = [
        generateAlias("@", "src/"),
        generateAlias("~", "src/assets/scss/"),
        generateAlias("#", "src/assets/img/"),
        generateAlias("%", "config/"),
    ];

    const plugins = [
        alias({
            entries
        }),
        resolve({ browser: true }),
    ];

    return configs.map(entry => {
        return {
            ...entry,
            plugins
        }
    });
}

export {
    augment
}

And the I wrap the above exported array in augment like:

const bundles = [/* above example */];

export default augment(bundles);

Now this all works fine, but I have two plugins that I don't actually want to apply to each bundle I just want to run them once all the bundles have built, those two plugins are; rollup-plugin-serve and rollup-plugin-workbox now neither of these actually have anything to do with any of the files being bundled, and make no sense to instantiate more than once.

What I would like to do as part of the augment function to to append them to the end of the returned array something like:

const exportedArray = configs.map(/* function from above */);

exportedArray.push(...[
        {
                plugins: [
                        serve({
                                host,
                                port,
                                contentBase: 'dist/'
                        })
                ]
        }
]);

return exportedArray;

And this would not contain an input, I have tried the above and rollup plains, the alternative option would be to add these plugins to the final bundle on the array, I just prefer the idea of instantiating them without them being tied to a particular bundle.

Share Improve this question asked Jan 9, 2020 at 3:03 Otis WrightOtis Wright 2,1208 gold badges32 silver badges53 bronze badges 1
  • Did you figure this out? – Sam R. Commented May 5, 2020 at 17:12
Add a ment  | 

2 Answers 2

Reset to default 3

Rollup needs an input file to work, but that doesn't mean you cannot simply throw away the result of the file. You can make an empty file empty.js (or maybe add some ment in it) and use that as the input. Just leave out the output properties so that the result is not written anywhere.

---EDIT---

a bit like this:

export default {
    input: './empty.js',
    plugins: [{
        name: 'test plugin',
        load() {
            console.log('test plugin')
        }
    }]
}

---EDIT---

Alternatively you can write to a dummy file and remove it again

const fs = require('fs')

export default {
    input: './empty.js',
    output: {
        file: './dummy',
    },
    plugins: [{
        name: 'test plugin',
        writeBundle(options) {
            fs.unlinkSync(options.file)
        }
    }]
}

I faced a similar problem in our own rollup plugin. We use rollup to generate many bundles from many inputs. However, since the build takes a long time, we determine which inputs need to be built and which is unchanged. So there may be a situation where the rollup runs without any input.

The only solution is to create an empty file, which will not be written to disk as a result.

Config has no any input:

const rollupOptions: rollup.RollupOptions = {
    output: {
        dir: 'some-dir',
    },
    plugins: [buildManager(entryFiles)],
}

Plugin buildManager creates inputs on buildStart hook:

export function buildManager(entryFiles: string[]): rollup.Plugin {
    const emptyRunId = 'no-input-for-this-run';

    return {
        name: 'build-manager',
        buildStart() {
            for (const entryFile of entryFiles) {
                // if some condition met, emit chunk (~ create an input)
            }

            // if the condition does not met even once, no chunk is created, but rollup needs at least one input
            this.emitFile({
                id: emptyRunId,
                fileName: emptyRunId,
                type: 'chunk',
            });
        },
        resolveId(source) {
            if (source === emptyRunId) {
                // The leading \0 instructs other plugins and rollup not to try to resolve, load or transform this module
                return `\0${emptyRunId}`;
            }
            return null;
        },
        load(id) {
            if (id.includes(emptyRunId)) {
                // some random code to avoid rollup empty chunk warning
                return 'export const empty = true;';
            }

            return null;
        },
        generateBundle(options, bundle) {
            // remove empty chunk from final bundle to not write that file
            if (bundle[emptyRunId]) {
                delete bundle[emptyRunId];
            }
        },
    };
}

So it could be easily used as standalone plugin to handle empty run.

发布者:admin,转转请注明出处:http://www.yc00.com/questions/1744094104a4557623.html

相关推荐

发表回复

评论列表(0条)

  • 暂无评论

联系我们

400-800-8888

在线咨询: QQ交谈

邮件:admin@example.com

工作时间:周一至周五,9:30-18:30,节假日休息

关注微信