question-mark
Stuck on an issue?

Lightrun Answers was designed to reduce the constant googling that comes with debugging 3rd party libraries. It collects links to all the places you might be looking at while hunting down a tough bug.

And, if you’re still stuck at the end, we’re happy to hop on a call to see how we can help out.

Support multiple extractors

See original GitHub issue

🚀 Feature Proposal

Possibility to pass multiple extractors to ChunkExtractorManager

Motivation

It could be useful when you ship two bundles: for modern and old browsers. Currently we can achieve this by overriding stats field in ChunkExtractor instance, but it’s a bit dirty solution.

Example

<ChunkExtractorManager extractor={[firstExtractor, secondExtractor ]}>

Issue Analytics

  • State:closed
  • Created 4 years ago
  • Reactions:21
  • Comments:13 (7 by maintainers)

github_iconTop GitHub Comments

3reactions
7rulnikcommented, Sep 30, 2019

So if someone is looking for workaround so here you go:

Firstly we need to patch ChunkExtractor

// https://github.com/smooth-code/loadable-components/issues/365

import { ChunkExtractor } from '@loadable/server';

function getSriHtmlAttributes(asset) {
    if (!asset.integrity) {
        return '';
    }

    return ` integrity="${asset.integrity}"`;
}

function handleExtraProps(asset, extraProps) {
    return typeof extraProps === 'function' ? extraProps(asset) : extraProps;
}

function extraPropsToString(asset, extraProps) {
    return Object.entries(handleExtraProps(asset, extraProps)).reduce(
        (acc, [key, value]) => (key === 'nomodule' ? `${acc} ${key}` : `${acc} ${key}="${value}"`),
        ''
    );
}

function assetToScriptTag(asset, extraProps) {
    return `<script async data-chunk="${asset.chunk}" src="${asset.url}"${getSriHtmlAttributes(
        asset
    )}${extraPropsToString(asset, extraProps)}></script>`;
}

export class PatchedChunkExtractor extends ChunkExtractor {
    getScriptTags(extraProps = {}) {
        const mainAssets = this.getMainAssets('script');
        const assetsScriptTags = mainAssets.map(asset => assetToScriptTag(asset, extraProps));

        return assetsScriptTags.join('\n');
    }
}

Also we need a map function for extractor and multiple stats (but it’s optional):

/* eslint-disable no-param-reassign */
export function mapExtractorWithStats(extractor, statsAsArr, mappper) {
    const originalStats = extractor.stats;
    const originalPublicPath = extractor.publicPath;
    const originalOutputPath = extractor.outputPath;

    const arrs = statsAsArr.map((stat, index) => {
        extractor.stats = stat;
        extractor.publicPath = originalPublicPath || stat.publicPath;
        extractor.outputPath = originalPublicPath || stat.outputPath;

        return mappper(extractor, index);
    });

    extractor.stats = originalStats;
    extractor.publicPath = originalPublicPath;
    extractor.outputPath = originalOutputPath;

    return arrs;
}

And now we can generate markup:

const extractor = new PatchedChunkExtractor({
  stats: {},
  publicPath: process.env.PUBLIC_PATH
});

const jsx = extractor.collectChunks(<App />);

const markup = renderToString(jsx);

const [legacyResult, modernResult] = mapExtractorWithStats(
  extractor,
  [statsLegacy, statsModern],
  (patchedExtractor, index) => {
    const isModern = index === 1;
    const scriptOpts = {};

    if (isModern) {
      scriptOpts.type = "module";
    } else {
      scriptOpts.nomodule = true;
    }

    const requiredChunksScriptTag = patchedExtractor.getRequiredChunksScriptTag({});
    const scriptTags = patchedExtractor.getScriptTags(scriptOpts);
    const styleTags = patchedExtractor.getStyleTags();

    return {
      requiredChunksScriptTag,
      scriptTags,
      styleTags
    };
  }
);

/* Please read https://github.com/smooth-code/loadable-components/issues/365#issuecomment-536486639 before using it */
const html = `<html>
  <head>${linkTags}</head>
  <body>
    <div id="root">${markup}</div>
    <!-- required chunks script tag -->
    ${modernResult.requiredChunksScriptTag}

    <!-- modern assets -->
    ${modernResult.scriptTags}

    <!-- legacy assets -->
    ${legacyResult.scriptTags}
  </body>
</html>`
1reaction
kevinfarrugiacommented, Jun 1, 2022

What is the current recommendation if you want to implement the module / nomodule pattern?

Read more comments on GitHub >

github_iconTop Results From Across the Web

IRWIN Screw Extractor Set, Hex Head, Multi-Spline, 25- ...
VERSATILE: Remove broken studs, bolts, socket screws and fittings for high torque applications; GRIPPING POWER: Aggressive left hand spiral design for extra ...
Read more >
PSA: You can have multiple extractors per water deposit.
In fact, a single deposit can support up to 7 extractors for a whopping 28 water production. Of course, you'll deplete the node...
Read more >
Extractors - Nuclei - Community Powered Vulnerability Scanner
Multiple extractors can be specified in a request. As of now we support two type of extractors. regex - Extract data from response...
Read more >
Extraction to Multiple Target System – Part 1 | SAP Blogs
I would like to share some knowledge about the various datasources that can be used to extract data into multiple systems let's say...
Read more >
[feature] Allow multiple dynamic values extraction #304 - GitHub
As of now, the dynamicvalue as returned by the extractor is only allowed to be 1 extracted item. This works well on CSRF...
Read more >

github_iconTop Related Medium Post

No results found

github_iconTop Related StackOverflow Question

No results found

github_iconTroubleshoot Live Code

Lightrun enables developers to add logs, metrics and snapshots to live code - no restarts or redeploys required.
Start Free

github_iconTop Related Reddit Thread

No results found

github_iconTop Related Hackernoon Post

No results found

github_iconTop Related Tweet

No results found

github_iconTop Related Dev.to Post

No results found

github_iconTop Related Hashnode Post

No results found