jantimon / jantimon/html-webpack-plugin

Possible to control placement order of base tags?

Open
#1,685 2 comments 0 reactions 0 assignees View on GitHub
wontfix
Dominant language
JavaScript
Stars
10.7k
Forks
1.3k
Avg merge
1m
Merged PRs (30d)
1

Description

I currently have to support proxying to multiple apps via sub-document paths (via nginx) and the solution that I've found works the best is to set the base tag to `/` and then for sub-document path setting `sub_filter '' ''; ` which has been working great so far (as long as my webpack is configured without a publicPath, all ajax requests are relative, and i set react router's basename prop to `new URL(document.baseURI}.pathname`)

The only issue I'm running into is that when I use html-webpack-plugin to set the basename
```js
plugins: [
new HtmlWebpackPlugin({
template: 'src/index.html',
base: '/',
favicon: 'src/static/favicon.svg',
})
]
```

it works, (and nginx is able to replace it with it's `sub_filter` directive, which is awesome) BUT the injected `` tag is inserted after the existing `` content in the template:

```html

```

Which html-webpack-plugin ends up returning with the injected scripts and base tag as:

```html

```

If you notice, I'm loading a js file called config.js (it's generated by the server, and serves to inject some public variables at runtime for the docker container, so I can assign some vars to window.config which allows me to change some env variables for the client without having to have webpack rebuild the whole bundle) and putting it in my index.html that i'm using for the template.

I kept seeing that if I loaded the page on it's path without a trailing slash, it would try and load `http://my-proxy-server/config.js` instead of `http://my-proxy-server/subpath/config.js`, which resulted in the config file not being loaded. Even though I was serving it (thanks to nginx's sub_filter) with ``

I thought it was my nginx config, but had a hunch and moved the `` tag in the compiled index.html to the top of the `` and boom, it suddenly worked.

I'm guessing that as it parses the index.html, it first sees the `` tag, and any scripts loaded after that point are relative to the base tag, but ones before it use the document's current path, which when I'm not using a trailing slash, is the server root and not my sub-document path's root.

All that being said, I've learned that the order matters for where the `<base>` tag is placed in the `<head>` and I need it to be placed before my `<script>` tag. Since the script is loaded from the server, it's not something I can (as far as I know) get webpack to pick up and let html-webpack-plugin to include (plus it needs to be before the bundles) are loaded, but as html-webpack-plugin injects it at the bottom of my existing template content, it's getting placed too late in the `<head>`

tl;dr
```html
<head>
<base href="/subpath/">
<script src="file.js">

```
works but
```html


```
doesn't, and html-webpack-plugin places the header content AFTER the template's existing content there.

What would be the best practice to fix? Somehow ensure the `` tag generated by html-webpack-plugin is injected at the top of the ``, or at least before the script I need to load? Is there a way to let the script be injected by html-webpack-plugin when it's not park of the webpack build? Create a placeholder config.js and include in the build, only to be replaced at runtime by my startup script?

My current workaround is to just omit `base` in the plugin's options and just set it manually on the template, but I'd like to use html-webpack-plugin to generate the base tag if possible, so my webpack configs can be consistent between projects. (especially for ones that may not have a template at all and use the defaults)

Any help is appreciated. I'd like to figure out the cleanest approach. My current workaround feels hacky.

Contributor guide

No contributing guide indexed for this repository

Research direction

Start with the HtmlWebpackPlugin configuration shown and the src/index.html template, reproducing the generated head order with the base option and the runtime config.js script. Trace how the plugin injects the base tag and other assets, then define a placement option or documented approach whose completion criterion is placing the base tag before config.js while preserving default-template behavior.

Written by the indexing model from the issue text.

Assessment

Tech stack
javascript, webpack
Domain
build-system, tooling
Issue type
Feature
Difficulty
4/5
Estimated time
3-5 days
Activity status
Stale
Clarity
Mostly clear
Newbie friendliness
45/100

Get new issues in your inbox

A short digest of beginner-friendly GitHub issues.