-
Notifications
You must be signed in to change notification settings - Fork 10.3k
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
feat(gatsby): add assetPrefix to support deploying assets separate from html #12128
Changes from 12 commits
860f920
f070da7
c32d7f1
4351700
5b8e714
5e7516f
50c4841
e6ad72f
23749b6
7f9e076
6d61a3d
9a33fa6
e8b6d71
6687692
ad04a43
de7e73b
a665cc4
9acb7cd
26c2f33
7d27649
723bb82
f58d9a3
6af9bad
52d3e21
b144bd2
fe0f94a
20eae0b
4ac9648
8f25776
7e3b1e2
da45256
c7c6859
87c9815
6110801
5ec39f7
82be716
7734c5e
9234e33
b8a1c2c
39403b8
933f148
bbebb41
dff0e72
f8cfef0
560eb79
37293e3
45ec7c8
b0fef6e
0eb6c85
f0d9a91
0603c31
b22da6e
272551a
c3a1230
b88c2f8
5521302
08ede03
d28d6f1
d277729
4d073da
b1241c2
3b8c23a
a84aeb9
78374b2
d226f5e
983f010
60c2408
ae9b34c
4075e95
2a761db
File filter
Filter by extension
Conversations
Jump to
Diff view
Diff view
There are no files selected for viewing
Original file line number | Diff line number | Diff line change |
---|---|---|
|
@@ -4,7 +4,7 @@ import { navigate } from "gatsby" | |
import * as catchLinks from "../catch-links" | ||
|
||
beforeAll(() => { | ||
global.__PATH_PREFIX__ = `` | ||
global.__BASE_PATH__ = `` | ||
// Set the base URL we will be testing against to http://localhost:8000/blog | ||
window.history.pushState({}, `APP Url`, `${pathPrefix}`) | ||
}) | ||
|
@@ -365,13 +365,13 @@ describe(`pathPrefix is handled if catched link to ${pathPrefix}/article navigat | |
}) | ||
|
||
afterAll(() => { | ||
global.__PATH_PREFIX__ = `` | ||
global.__BASE_PATH__ = `` | ||
eventDestroyer() | ||
There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. 🔥 |
||
}) | ||
|
||
test(`on sites with pathPrefix '${pathPrefix}'`, done => { | ||
// simulate case with --prefix-paths and prefix /blog | ||
global.__PATH_PREFIX__ = pathPrefix | ||
global.__BASE_PATH__ = pathPrefix | ||
|
||
// create the element with href /blog/article | ||
const clickElement = document.createElement(`a`) | ||
|
@@ -408,7 +408,7 @@ describe(`pathPrefix is handled if catched link to ${pathPrefix}/article navigat | |
|
||
test(`on sites without pathPrefix`, done => { | ||
// simulate default case without --prefix-paths | ||
global.__PATH_PREFIX__ = `` | ||
global.__BASE_PATH__ = `` | ||
|
||
// create the element with href /blog/article | ||
const clickElement = document.createElement(`a`) | ||
|
Original file line number | Diff line number | Diff line change |
---|---|---|
|
@@ -65,6 +65,15 @@ module.exports = async program => { | |
} | ||
return next() | ||
}) | ||
app.use(function(req, res, next) { | ||
There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. Could probably use cors here 🤷♂️ |
||
res.header(`Access-Control-Allow-Origin`, `http://${host}:${port}`) | ||
res.header(`Access-Control-Allow-Credentials`, true) | ||
res.header( | ||
`Access-Control-Allow-Headers`, | ||
`Origin, X-Requested-With, Content-Type, Accept` | ||
) | ||
next() | ||
}) | ||
app.use(pathPrefix, router) | ||
|
||
const server = app.listen(port, host, () => { | ||
|
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -1,10 +1,18 @@ | ||
const Joi = require(`joi`) | ||
|
||
const stripTrailingSlash = chain => chain.replace(/(\w)\//, `$1`) | ||
There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. This is a nice addition - rather than requiring documentation (e.g. don't add a trailing slash), this will just remove it for us. It only impacts a string with content, e.g. |
||
|
||
export const gatsbyConfigSchema = Joi.object().keys({ | ||
__experimentalThemes: Joi.array(), | ||
polyfill: Joi.boolean(), | ||
siteMetadata: Joi.object(), | ||
pathPrefix: Joi.string(), | ||
assetPrefix: stripTrailingSlash(Joi.string().uri()), | ||
DSchau marked this conversation as resolved.
Show resolved
Hide resolved
|
||
pathPrefix: stripTrailingSlash( | ||
Joi.string().uri({ | ||
allowRelative: true, | ||
relativeOnly: true, | ||
}) | ||
), | ||
mapping: Joi.object(), | ||
plugins: Joi.array(), | ||
proxy: Joi.object().keys({ | ||
|
Original file line number | Diff line number | Diff line change |
---|---|---|
|
@@ -7,6 +7,7 @@ module.exports = schema => { | |
globals: { | ||
graphql: true, | ||
__PATH_PREFIX__: true, | ||
__BASE_PATH__: true, // this will rarely, if ever, be used by consumers | ||
There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. For more context here--it's used in the internal linking (e.g. with just pathPrefix) because pathPrefix itself is overloaded. |
||
}, | ||
extends: `react-app`, | ||
plugins: [`graphql`], | ||
|
Original file line number | Diff line number | Diff line change |
---|---|---|
|
@@ -2,13 +2,14 @@ require(`v8-compile-cache`) | |
|
||
const fs = require(`fs-extra`) | ||
const path = require(`path`) | ||
const url = require(`url`) | ||
const dotenv = require(`dotenv`) | ||
const FriendlyErrorsWebpackPlugin = require(`friendly-errors-webpack-plugin`) | ||
const { store } = require(`../redux`) | ||
const { actions } = require(`../redux/actions`) | ||
const debug = require(`debug`)(`gatsby:webpack-config`) | ||
const report = require(`gatsby-cli/lib/reporter`) | ||
const { withBasePath } = require(`./path`) | ||
const { withBasePath, withTrailingSlash } = require(`./path`) | ||
|
||
const apiRunnerNode = require(`./api-runner-node`) | ||
const createUtils = require(`./webpack-utils`) | ||
|
@@ -20,12 +21,7 @@ const hasLocalEslint = require(`./local-eslint-config-finder`) | |
// 3) build-javascript: Build JS and CSS chunks for production | ||
// 4) build-html: build all HTML files | ||
|
||
module.exports = async ( | ||
program, | ||
directory, | ||
suppliedStage, | ||
webpackPort = 1500 | ||
) => { | ||
module.exports = async (program, directory, suppliedStage) => { | ||
const directoryPath = withBasePath(directory) | ||
|
||
process.env.GATSBY_BUILD_STAGE = suppliedStage | ||
|
@@ -35,6 +31,15 @@ module.exports = async ( | |
const stage = suppliedStage | ||
const { rules, loaders, plugins } = await createUtils({ stage, program }) | ||
|
||
const { assetPrefix, pathPrefix } = store.getState().config | ||
|
||
let publicPath = `/` | ||
if (program.prefixPaths && (pathPrefix || assetPrefix)) { | ||
publicPath = url.resolve( | ||
...[assetPrefix, pathPrefix].map(part => part || ``) | ||
) | ||
} | ||
|
||
function processEnv(stage, defaultNodeEnv) { | ||
debug(`Building env for "${stage}"`) | ||
const env = process.env.NODE_ENV | ||
|
@@ -91,7 +96,7 @@ module.exports = async ( | |
if (pubPath.substr(-1) === `/`) { | ||
hmrBasePath = pubPath | ||
} else { | ||
hmrBasePath = `${pubPath}/` | ||
hmrBasePath = withTrailingSlash(pubPath) | ||
} | ||
} | ||
|
||
|
@@ -126,18 +131,14 @@ module.exports = async ( | |
library: `lib`, | ||
umdNamedDefine: true, | ||
globalObject: `this`, | ||
publicPath: program.prefixPaths | ||
? `${store.getState().config.pathPrefix}/` | ||
: `/`, | ||
publicPath: withTrailingSlash(publicPath), | ||
} | ||
case `build-javascript`: | ||
return { | ||
filename: `[name]-[contenthash].js`, | ||
chunkFilename: `[name]-[contenthash].js`, | ||
path: directoryPath(`public`), | ||
publicPath: program.prefixPaths | ||
? `${store.getState().config.pathPrefix}/` | ||
: `/`, | ||
publicPath: withTrailingSlash(publicPath), | ||
} | ||
default: | ||
throw new Error(`The state requested ${stage} doesn't exist.`) | ||
|
@@ -181,8 +182,10 @@ module.exports = async ( | |
// optimizations for React) and what the link prefix is (__PATH_PREFIX__). | ||
plugins.define({ | ||
...processEnv(stage, `development`), | ||
__PATH_PREFIX__: JSON.stringify( | ||
program.prefixPaths ? store.getState().config.pathPrefix : `` | ||
__BASE_PATH__: JSON.stringify(program.prefixPaths ? pathPrefix : ``), | ||
There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. Worth adding a note to explain why
|
||
__PATH_PREFIX__: JSON.stringify(program.prefixPaths ? publicPath : ``), | ||
__ASSET_PREFIX__: JSON.stringify( | ||
program.prefixPaths ? assetPrefix : `` | ||
There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. I'm not sure where to document this, but I feel like it would be useful to define differences between those. To my understanding plugins (for now) should only ever use There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. Correct! |
||
), | ||
}), | ||
] | ||
|
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
BASE_PATH is the new PATH_PREFIX. PATH_PREFIX is now overloaded with assetPrefix + pathPrefix.