webpack-contrib / mini-css-extract-plugin

Lightweight CSS extraction plugin
MIT License
4.66k stars 388 forks source link

Ability to add attributes to link tag and intercept onload event #413

Closed Rulexec closed 4 years ago

Rulexec commented 5 years ago

Feature Proposal

Add ability to add custom code to requireEnsure hook code to be able do something custom with the linkTag.

For me there is only two cases:

Feature Use Case

I'm using css-vars-ponyfill to use CSS Variables in IE11. And I want to call it after <link> tag was added by mini-css-extract-plugin, but before chunk will be loaded. Also, I need to add custom attribute to <link> tag to handle only own CSS.

Currently I'm solving it in a very dirty way:

compilation.mainTemplate.hooks.requireEnsure.tap({
    name: 'SkinsPlugin',
    stage: 9999999,
}, source => {
    const miniCssPluginPresent = source.indexOf('if(installedCssChunks[chunkId]) promises.push(installedCssChunks[chunkId]);') >= 0;
    if (!miniCssPluginPresent) {
        throw new Error('SkinsPlugin:noMiniCssExtractPlugin');
    }

    let replaced = false;

    const regexp =/^(\s*)linkTag.onload = resolve;$/m;

    source = source.replace(regexp, (full, indent) => {
        replaced = true;

        let code = ``;

        code += indent + `linkTag.setAttribute('data-include-css-ponyfill', '');`;

        code += indent + `linkTag.onload = function(e){\n`;
        code += indent + `\tif (typeof SomeGlobalObject !== 'undefined' && SomeGlobalObject && SomeGlobalObject._someFun) {\n`;
        code += indent + '\t\tSomeGlobalObject._someFun();\n';
        code += indent + '\t\tresolve(e);\n';
        code += indent + '\t}\n';
        code += indent + '};\n';

        return code;
    });

    if (!replaced) {
        throw new Error('SkinsPlugin:noMiniCssExtractPlugin');
    }

    return source;
});

But I think, that better is to collect some other use cases which need interception and implement some options to do it.

alexander-akait commented 5 years ago

hm, can you create example of this? I want investigate this situation? Looks like a good feature, thanks

Rulexec commented 5 years ago

@evilebottnawi sure — https://github.com/Rulexec/mini-css-extract-plugin-css-vars-ponyfill

alexander-akait commented 5 years ago

Thanks for test repo, in todo, anyway feel free to send a PR with feature

Rulexec commented 5 years ago

One of the possible solutions — https://github.com/Rulexec/mini-css-extract-plugin-css-vars-ponyfill/commit/e329d46c4afedc36fd6d38faa93c8c38336c4a4e

I don't know, how to better to implement it, I have never contributed to open-source projects.

This is looks as simple feature, but it is not simple options, which just customize some paths. It is first occurrence of plugin-like API in mini-css-extract-plugin. And it can impact, how following customizations of the generated code will be implemented and which API they will have. Too scary :)

alexander-akait commented 4 years ago

The attributes option was implemented and released (1.1.0), no onload, because it is unsafe and out of scope, you can emulate this logic using data attributes, feel free to feedback if you have a problem with setup