Skip to content

Commit 25b0fa2

Browse files
committed
refactor: unify deploy base path handling
1 parent 84f11c1 commit 25b0fa2

3 files changed

Lines changed: 54 additions & 36 deletions

File tree

packages/__docs__/src/index.html

Lines changed: 11 additions & 11 deletions
Original file line numberDiff line numberDiff line change
@@ -1,20 +1,20 @@
11
<!DOCTYPE html>
22
<html lang="en" dir="ltr">
33
<head>
4-
<base href="/" />
5-
<!-- GitHub Pages SPA redirect for subdirectory deployments.
6-
When serving this page as 404.html, redirect deep links under
7-
/pr-preview/pr-N/ or /latest/ back to the subdirectory root with
8-
the route encoded as a query parameter. No-op for root paths. -->
4+
<base href="<%= PUBLIC_PATH %>" />
5+
<!-- When GH Pages serves this as 404.html, redirect the deep link to the
6+
deploy base -->
97
<script>
108
;(function () {
9+
var base = '<%= PUBLIC_PATH %>'
1110
var l = window.location
12-
var m = l.pathname.match(/^(\/pr-preview\/pr-\d+|\/latest)(\/.*)$/)
13-
if (m && m[2] !== '/') {
14-
l.replace(
15-
m[1] + '/?__spa_route=' + encodeURIComponent(m[2] + l.hash)
16-
)
17-
}
11+
if (l.pathname === base) return
12+
if (l.pathname + '/' === base) return
13+
if (l.pathname.indexOf(base) !== 0) return
14+
var rest = l.pathname.slice(base.length)
15+
l.replace(
16+
base + '?__spa_route=' + encodeURIComponent('/' + rest + l.hash)
17+
)
1818
})()
1919
</script>
2020
<meta charset="utf-8" />

packages/__docs__/src/navigationUtils.ts

Lines changed: 33 additions & 21 deletions
Original file line numberDiff line numberDiff line change
@@ -22,36 +22,48 @@
2222
* SOFTWARE.
2323
*/
2424

25+
// Webpack-injected; equals output.publicPath.
26+
// Examples: '/', '/latest/', '/pr-preview/pr-123/'.
27+
declare const __webpack_public_path__: string
28+
2529
const MINOR_VERSION_REGEX = /^v\d+_\d+$/
2630

2731
type ParsedUrl = {
28-
prPrefix: string
32+
basePrefix: string
2933
minorVersion: string | null
3034
page: string
3135
sectionId: string | undefined
3236
}
3337

38+
/**
39+
* Returns '' for a root deploy, '/latest' on instructure.design,
40+
* '/pr-preview/pr-<n>' for PR previews. For sub-host deployments it can be
41+
* '/<repo>/pr-preview/pr-<n>'.
42+
*/
43+
function getDeployBase(): string {
44+
if (typeof __webpack_public_path__ === 'string' && __webpack_public_path__) {
45+
return __webpack_public_path__.replace(/\/+$/, '')
46+
}
47+
return ''
48+
}
49+
3450
function parseCurrentUrl(): ParsedUrl {
3551
const { pathname, hash } = window.location
36-
const cleanPath = pathname.replace(/^\/+|\/+$/g, '')
52+
53+
const deployBase = getDeployBase()
54+
let rest = pathname
55+
if (deployBase && rest.startsWith(deployBase)) {
56+
rest = rest.slice(deployBase.length)
57+
}
58+
59+
const cleanPath = rest.replace(/^\/+|\/+$/g, '')
3760
const segments = cleanPath.split('/').filter(Boolean)
3861

39-
let prPrefix = ''
62+
let appPrefix = ''
4063
let idx = 0
4164

42-
// Detect PR preview prefix: /pr-preview/pr-123
43-
if (
44-
segments.length >= 2 &&
45-
segments[0] === 'pr-preview' &&
46-
segments[1].startsWith('pr-')
47-
) {
48-
prPrefix = `/${segments[0]}/${segments[1]}`
49-
idx = 2
50-
}
51-
52-
// Detect /latest/ prefix
53-
if (idx === 0 && segments[idx] === 'latest') {
54-
prPrefix = '/latest'
65+
if (segments[idx] === 'latest') {
66+
appPrefix = '/latest'
5567
idx++
5668
}
5769

@@ -71,7 +83,7 @@ function parseCurrentUrl(): ParsedUrl {
7183
sectionId = decodeURI(hash.replace(/^#+/, ''))
7284
}
7385

74-
return { prPrefix, minorVersion, page, sectionId }
86+
return { basePrefix: deployBase + appPrefix, minorVersion, page, sectionId }
7587
}
7688

7789
type BuildUrlOptions = {
@@ -80,13 +92,13 @@ type BuildUrlOptions = {
8092
}
8193

8294
function buildUrl(targetPage: string, options?: BuildUrlOptions): string {
83-
const { prPrefix } = parseCurrentUrl()
95+
const parsed = parseCurrentUrl()
8496
const minorVersion =
8597
options?.minorVersion !== undefined
8698
? options.minorVersion
87-
: parseCurrentUrl().minorVersion
99+
: parsed.minorVersion
88100

89-
let url = prPrefix
101+
let url = parsed.basePrefix
90102

91103
if (minorVersion) {
92104
url += `/${minorVersion}`
@@ -123,7 +135,7 @@ function navigateToVersion(version: string | null): void {
123135
* On PR previews this is e.g. `/pr-preview/pr-2425`, otherwise empty string.
124136
*/
125137
function getAssetBasePath(): string {
126-
return parseCurrentUrl().prPrefix
138+
return getDeployBase()
127139
}
128140

129141
export {

packages/__docs__/webpack.config.mjs

Lines changed: 10 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -32,7 +32,14 @@ const ENV = process.env.NODE_ENV || 'production'
3232
const DEBUG = process.env.DEBUG || ENV === 'development'
3333
const GITHUB_PULL_REQUEST_PREVIEW = process.env.GITHUB_PULL_REQUEST_PREVIEW || 'false'
3434
const PR_NUMBER = process.env.PR_NUMBER
35-
const PUBLIC_PATH = process.env.PUBLIC_PATH
35+
// The URL prefix this build is deployed under. Must end with a trailing
36+
// slash. Fed into output.publicPath (which webpack exposes at runtime as
37+
// __webpack_public_path__) and into the HTML template's <base href> and
38+
// 404 SPA-redirect script. Keeping a single source here means a new deploy
39+
// target only needs to set this one env var.
40+
const PUBLIC_PATH =
41+
process.env.PUBLIC_PATH ||
42+
(PR_NUMBER ? `/pr-preview/pr-${PR_NUMBER}/` : '/')
3643

3744
const outputPath = resolvePath(import.meta.dirname, '__build__')
3845

@@ -51,9 +58,7 @@ const config = merge(baseConfig, {
5158
output: {
5259
path: outputPath,
5360
filename: '[name].js',
54-
// Builds deployed to subdirectories on GitHub Pages (e.g. /pr-preview/pr-123/
55-
// or /latest/) need a matching publicPath so script tags resolve correctly.
56-
publicPath: PUBLIC_PATH || (PR_NUMBER ? `/pr-preview/pr-${PR_NUMBER}/` : '/'),
61+
publicPath: PUBLIC_PATH,
5762
},
5863
devServer: {
5964
static: {
@@ -69,6 +74,7 @@ const config = merge(baseConfig, {
6974
new HtmlWebpackPlugin({
7075
template: './src/index.html',
7176
chunks: ['main'],
77+
templateParameters: { PUBLIC_PATH },
7278
}),
7379
new webpack.DefinePlugin({
7480
'process.env.GITHUB_PULL_REQUEST_PREVIEW': JSON.stringify(GITHUB_PULL_REQUEST_PREVIEW),

0 commit comments

Comments
 (0)