Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Add query parameter support #998

Open
Hacksign opened this issue Feb 5, 2024 · 3 comments
Open

Add query parameter support #998

Hacksign opened this issue Feb 5, 2024 · 3 comments

Comments

@Hacksign
Copy link

Hacksign commented Feb 5, 2024

🚀 Feature Proposal

When accessing some scripts, sometimes we need append a query/search parameter (a.com/?x=1&y=2), but ChunkExtractor do not support this.

Motivation

Think this scenario:

Suppose we have a website which support 2 languages: A and B, there is an nginx reverse proxy which routing accesses by query parameter ?lang=A|B.

In this scenario, we need ChunkExtractor.getScript* generate <script src='xxxxx?lang=A'></scrpt> or <script src='xxxxx?lang=B'></scrpt> DOM elements staticly or dynamicly.

But ChunkExtractor has no such ability for now :(

Example

const clientExtractor = new ChunkExtractor(
  {
    entrypoints: entrypoint,
    statsFile: path.resolve(process.cwd(), './dist/client/loadable-stats.json'),
    search: `?lang=${props.lang}`    // <--- search parameter injection
  }
);
clientExtractor.getScriptTags();

Suppose props.lang = en-US, clientExtractor.getScriptTags() will generate DOM like this:

<script .... src='/some/component/chunks.js?lang=en-US'></script>

NOTE: dynamic loaded component should stick to this rule as well.

Pitch

Now I'm modifing query parameters like this:

clientExtractor.getScriptTags().split('\n').map(
  i => i.replace(
    /(<script.*?src=['"])(.*?)(['"])/,
    `$1$2?lang=${props.lang}$3`
  )
).join('\n'),

But currently I have no idea how to modify dynamicly loaded component. And there is nothing to help by reading the API document.

@theKashey
Copy link
Collaborator

Your solution for server-side definitely works, but I am not sure if it can be adapted for client side.

The problem is - loadable is not importing scripts by itself, it's just asking webpack to do so with all script names being hardcoded in the webpack manifest.

So you have the following options:

  • (hard) modify your script by injecting the language to alter manifest file and point to other files
  • (easy) change URL format to /en-US/some/component/chunks.js, in this case you can use webpack.publicPath to control "prefix" setting it to where it should
    • done, that works like magic and more importantly scripts dont use any query string and are better cacheable

@Hacksign
Copy link
Author

Hacksign commented Feb 6, 2024

Solution I currently use is adding a routing method, which is by cookie, in nginx proxy server.

Then add response.cookie('lang', language) in request handler (which is server_side_renderer function in my project), so when the first request is responsed, there will be a lang field in the continuing request in HTTP Cookie header.

(⬆️ The hard way)

The easy way, is not that easy actually, because sometimes there may be dynamic language support demand, this is why I said:

NOTE: dynamic loaded component should stick to this rule as well.

As there is dynamic demands, webpack.publicPath is not a perfect solution as well, this can only solve static situations. There will be multi entry scripts which is compiled with different webpack.publicPath, the only difference among these scripts is the webpack.publicPath.

Maybe loadable's webpack plugin can add some hooks to solve this ? I'm not familiar with webpack development (actually I'm not a frontend engineer...).

@theKashey
Copy link
Collaborator

Then add response.cookie('lang', language) in request handler

That actually should work out of the box. Just use cookies not extra query parameters

As there is dynamic demands, webpack.publicPath is not a perfect solution as well,

It is, because it can be configured in runtime. And that would be same script, just prefixed with language - something nginx can use instead of query attribute.

Maybe loadable's webpack plugin can add some hooks to solve this

It cannot because it's not only about loadable-stats (server side), but client-side as well, fully managed by webpack

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
None yet
Projects
None yet
Development

No branches or pull requests

2 participants