From 860f9201c094c77d6b2ebc5150a77d4d8b848a31 Mon Sep 17 00:00:00 2001 From: Dustin Schau Date: Mon, 25 Feb 2019 10:33:16 -0600 Subject: [PATCH 01/60] chore: add validation schema, start tweaking webpack config --- packages/gatsby/src/joi-schemas/joi.js | 10 +++++++++- packages/gatsby/src/utils/webpack.config.js | 22 +++++++++++++-------- 2 files changed, 23 insertions(+), 9 deletions(-) diff --git a/packages/gatsby/src/joi-schemas/joi.js b/packages/gatsby/src/joi-schemas/joi.js index 7a5d1f97a69df..52505fcb6b5e2 100644 --- a/packages/gatsby/src/joi-schemas/joi.js +++ b/packages/gatsby/src/joi-schemas/joi.js @@ -1,10 +1,18 @@ const Joi = require(`joi`) +const stripTrailingSlash = chain => chain.replace(/\/$/, ``) + export const gatsbyConfigSchema = Joi.object().keys({ __experimentalThemes: Joi.array(), polyfill: Joi.boolean(), siteMetadata: Joi.object(), - pathPrefix: Joi.string(), + assetPrefix: stripTrailingSlash(Joi.string().uri()), + pathPrefix: stripTrailingSlash( + Joi.string().uri({ + allowRelative: true, + relativeOnly: true, + }) + ), mapping: Joi.object(), plugins: Joi.array(), proxy: Joi.object().keys({ diff --git a/packages/gatsby/src/utils/webpack.config.js b/packages/gatsby/src/utils/webpack.config.js index c3cbcb05db7e0..b9b2500339c07 100644 --- a/packages/gatsby/src/utils/webpack.config.js +++ b/packages/gatsby/src/utils/webpack.config.js @@ -35,6 +35,15 @@ module.exports = async ( const stage = suppliedStage const { rules, loaders, plugins } = await createUtils({ stage, program }) + const { assetPrefix, pathPrefix } = store.getState().config + + let publicPath = `/` + if (assetPrefix || pathPrefix) { + publicPath = [assetPrefix, pathPrefix] + .filter(part => part && part.length > 0) + .join(`/`) + } + function processEnv(stage, defaultNodeEnv) { debug(`Building env for "${stage}"`) const env = process.env.NODE_ENV @@ -126,18 +135,14 @@ module.exports = async ( library: `lib`, umdNamedDefine: true, globalObject: `this`, - publicPath: program.prefixPaths - ? `${store.getState().config.pathPrefix}/` - : `/`, + publicPath, } case `build-javascript`: return { filename: `[name]-[contenthash].js`, chunkFilename: `[name]-[contenthash].js`, path: directoryPath(`public`), - publicPath: program.prefixPaths - ? `${store.getState().config.pathPrefix}/` - : `/`, + publicPath, } default: throw new Error(`The state requested ${stage} doesn't exist.`) @@ -181,8 +186,9 @@ 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 : `` + __PATH_PREFIX__: JSON.stringify(program.prefixPaths ? publicPath : ``), + __ASSET_PREFIX__: JSON.stringify( + program.prefixPaths ? assetPrefix : `` ), }), ] From f070da7ac4525e6e2c759e29614f04f5ebb85199 Mon Sep 17 00:00:00 2001 From: Dustin Schau Date: Mon, 25 Feb 2019 10:53:25 -0600 Subject: [PATCH 02/60] chore: keep iterating --- packages/gatsby/cache-dir/production-app.js | 2 +- packages/gatsby/cache-dir/static-entry.js | 4 ++-- packages/gatsby/package.json | 1 + packages/gatsby/src/commands/serve.js | 2 ++ packages/gatsby/src/utils/path.js | 4 ++++ packages/gatsby/src/utils/webpack.config.js | 16 ++++++++-------- 6 files changed, 18 insertions(+), 11 deletions(-) diff --git a/packages/gatsby/cache-dir/production-app.js b/packages/gatsby/cache-dir/production-app.js index 0e174ab30376e..43bb9b6cbfe3e 100644 --- a/packages/gatsby/cache-dir/production-app.js +++ b/packages/gatsby/cache-dir/production-app.js @@ -88,7 +88,7 @@ apiRunnerAsync(`onClientEntry`).then(() => { createElement( Router, { - basepath: __PATH_PREFIX__, + basepath: __BASE_PATH__, }, createElement(RouteHandler, { path: `/*` }) ) diff --git a/packages/gatsby/cache-dir/static-entry.js b/packages/gatsby/cache-dir/static-entry.js index 3e0cb708ba184..2689793ce640f 100644 --- a/packages/gatsby/cache-dir/static-entry.js +++ b/packages/gatsby/cache-dir/static-entry.js @@ -155,11 +155,11 @@ export default (pagePath, callback) => { const routerElement = createElement( ServerLocation, - { url: `${__PATH_PREFIX__}${pagePath}` }, + { url: `${__BASE_PATH__}${pagePath}` }, createElement( Router, { - baseuri: `${__PATH_PREFIX__}`, + baseuri: `${__BASE_PATH__}`, }, createElement(RouteHandler, { path: `/*` }) ) diff --git a/packages/gatsby/package.json b/packages/gatsby/package.json index 0b5e7cddc2f59..ab5b2e3691796 100644 --- a/packages/gatsby/package.json +++ b/packages/gatsby/package.json @@ -40,6 +40,7 @@ "convert-hrtime": "^2.0.0", "copyfiles": "^1.2.0", "core-js": "^2.5.0", + "cors": "^2.8.5", "css-loader": "^1.0.0", "debug": "^3.1.0", "del": "^3.0.0", diff --git a/packages/gatsby/src/commands/serve.js b/packages/gatsby/src/commands/serve.js index 9ed5fe0a74d36..e83588b34b37a 100644 --- a/packages/gatsby/src/commands/serve.js +++ b/packages/gatsby/src/commands/serve.js @@ -8,6 +8,7 @@ const express = require(`express`) const getConfigFile = require(`../bootstrap/get-config-file`) const preferDefault = require(`../bootstrap/prefer-default`) const chalk = require(`chalk`) +const cors = require(`cors`) const { match: reachMatch } = require(`@reach/router/lib/utils`) const getPages = directory => @@ -66,6 +67,7 @@ module.exports = async program => { return next() }) app.use(pathPrefix, router) + app.use(cors()) const server = app.listen(port, host, () => { let openUrlString = `http://${host}:${port}${pathPrefix}` diff --git a/packages/gatsby/src/utils/path.js b/packages/gatsby/src/utils/path.js index d2c9645afddc5..35fa45d233f32 100644 --- a/packages/gatsby/src/utils/path.js +++ b/packages/gatsby/src/utils/path.js @@ -13,3 +13,7 @@ export function joinPath(...paths) { export function withBasePath(basePath) { return (...paths) => joinPath(basePath, ...paths) } + +export function withTrailingSlash(basePath) { + return basePath.replace(/([\/]+)?$/, '/') +} diff --git a/packages/gatsby/src/utils/webpack.config.js b/packages/gatsby/src/utils/webpack.config.js index b9b2500339c07..f0a4256957337 100644 --- a/packages/gatsby/src/utils/webpack.config.js +++ b/packages/gatsby/src/utils/webpack.config.js @@ -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`) @@ -38,10 +39,8 @@ module.exports = async ( const { assetPrefix, pathPrefix } = store.getState().config let publicPath = `/` - if (assetPrefix || pathPrefix) { - publicPath = [assetPrefix, pathPrefix] - .filter(part => part && part.length > 0) - .join(`/`) + if (program.prefixPaths && (pathPrefix || assetPrefix)) { + publicPath = url.resolve(assetPrefix, pathPrefix) } function processEnv(stage, defaultNodeEnv) { @@ -100,7 +99,7 @@ module.exports = async ( if (pubPath.substr(-1) === `/`) { hmrBasePath = pubPath } else { - hmrBasePath = `${pubPath}/` + hmrBasePath = withTrailingSlash(pubPath) } } @@ -135,14 +134,14 @@ module.exports = async ( library: `lib`, umdNamedDefine: true, globalObject: `this`, - publicPath, + publicPath: withTrailingSlash(publicPath), } case `build-javascript`: return { filename: `[name]-[contenthash].js`, chunkFilename: `[name]-[contenthash].js`, path: directoryPath(`public`), - publicPath, + publicPath: withTrailingSlash(publicPath), } default: throw new Error(`The state requested ${stage} doesn't exist.`) @@ -186,6 +185,7 @@ module.exports = async ( // optimizations for React) and what the link prefix is (__PATH_PREFIX__). plugins.define({ ...processEnv(stage, `development`), + __BASE_PATH__: JSON.stringify(program.prefixPaths ? pathPrefix : ``), __PATH_PREFIX__: JSON.stringify(program.prefixPaths ? publicPath : ``), __ASSET_PREFIX__: JSON.stringify( program.prefixPaths ? assetPrefix : `` From c32d7f1bb8f6e0865b180af2525e2a1a3e938d01 Mon Sep 17 00:00:00 2001 From: Dustin Schau Date: Mon, 25 Feb 2019 10:53:59 -0600 Subject: [PATCH 03/60] chore: yadda --- packages/gatsby/src/utils/path.js | 2 +- yarn.lock | 12 ++++++++++-- 2 files changed, 11 insertions(+), 3 deletions(-) diff --git a/packages/gatsby/src/utils/path.js b/packages/gatsby/src/utils/path.js index 35fa45d233f32..33e18daee94c7 100644 --- a/packages/gatsby/src/utils/path.js +++ b/packages/gatsby/src/utils/path.js @@ -15,5 +15,5 @@ export function withBasePath(basePath) { } export function withTrailingSlash(basePath) { - return basePath.replace(/([\/]+)?$/, '/') + return basePath.replace(/([\/]+)?$/, `/`) } diff --git a/yarn.lock b/yarn.lock index df4dbe404e6e6..f923eee6060b5 100644 --- a/yarn.lock +++ b/yarn.lock @@ -5618,6 +5618,14 @@ core-util-is@1.0.2, core-util-is@~1.0.0: resolved "https://registry.yarnpkg.com/core-util-is/-/core-util-is-1.0.2.tgz#b5fd54220aa2bc5ab57aab7140c940754503c1a7" integrity sha1-tf1UIgqivFq1eqtxQMlAdUUDwac= +cors@^2.8.5: + version "2.8.5" + resolved "https://registry.yarnpkg.com/cors/-/cors-2.8.5.tgz#eac11da51592dd86b9f06f6e7ac293b3df875d29" + integrity sha512-KIHbLJqu73RGr/hnbrO9uBeixNGuvSQjul/jdFvS/KFSIH1hWVd1ng7zOHx+YrEfInLG7q4n6GHQ9cDtxv/P6g== + dependencies: + object-assign "^4" + vary "^1" + cosmiconfig@^4.0.0: version "4.0.0" resolved "https://registry.yarnpkg.com/cosmiconfig/-/cosmiconfig-4.0.0.tgz#760391549580bbd2df1e562bc177b13c290972dc" @@ -14014,7 +14022,7 @@ oauth-sign@~0.9.0: resolved "https://registry.yarnpkg.com/oauth-sign/-/oauth-sign-0.9.0.tgz#47a7b016baa68b5fa0ecf3dee08a85c679ac6455" integrity sha512-fexhUFFPTGV8ybAtSIGbV6gOkSv8UtRbDBnAyLQw4QPKkgNlsH2ByPGtMUqdWkos6YCRmAqViwgZrJc/mRDzZQ== -object-assign@^4.0.1, object-assign@^4.1.0, object-assign@^4.1.1: +object-assign@^4, object-assign@^4.0.1, object-assign@^4.1.0, object-assign@^4.1.1: version "4.1.1" resolved "https://registry.yarnpkg.com/object-assign/-/object-assign-4.1.1.tgz#2109adc7965887cfc05cbbd442cac8bfbb360863" integrity sha1-IQmtx5ZYh8/AXLvUQsrIv7s2CGM= @@ -19673,7 +19681,7 @@ value-or-function@^3.0.0: resolved "https://registry.yarnpkg.com/value-or-function/-/value-or-function-3.0.0.tgz#1c243a50b595c1be54a754bfece8563b9ff8d813" integrity sha1-HCQ6ULWVwb5Up1S/7OhWO5/42BM= -vary@~1.1.2: +vary@^1, vary@~1.1.2: version "1.1.2" resolved "https://registry.yarnpkg.com/vary/-/vary-1.1.2.tgz#2299f02c6ded30d4a5961b0b9f74524a18f634fc" integrity sha1-IpnwLG3tMNSllhsLn3RSShj2NPw= From 4351700b383fd6d009aaf2be5b2a467bc0af4a03 Mon Sep 17 00:00:00 2001 From: Dustin Schau Date: Mon, 25 Feb 2019 12:38:33 -0600 Subject: [PATCH 04/60] chore: keep working --- packages/gatsby-link/src/index.js | 1 - packages/gatsby/package.json | 1 - packages/gatsby/src/commands/serve.js | 10 +++++++++- www/package.json | 2 +- 4 files changed, 10 insertions(+), 4 deletions(-) diff --git a/packages/gatsby-link/src/index.js b/packages/gatsby-link/src/index.js index 7865d0f756e28..bf17e895f010d 100644 --- a/packages/gatsby-link/src/index.js +++ b/packages/gatsby-link/src/index.js @@ -12,7 +12,6 @@ export function withPrefix(path) { } function normalizePath(path) { - return path.replace(/\/+/g, `/`) } const NavLinkPropTypes = { diff --git a/packages/gatsby/package.json b/packages/gatsby/package.json index ab5b2e3691796..0b5e7cddc2f59 100644 --- a/packages/gatsby/package.json +++ b/packages/gatsby/package.json @@ -40,7 +40,6 @@ "convert-hrtime": "^2.0.0", "copyfiles": "^1.2.0", "core-js": "^2.5.0", - "cors": "^2.8.5", "css-loader": "^1.0.0", "debug": "^3.1.0", "del": "^3.0.0", diff --git a/packages/gatsby/src/commands/serve.js b/packages/gatsby/src/commands/serve.js index e83588b34b37a..4289a50eae169 100644 --- a/packages/gatsby/src/commands/serve.js +++ b/packages/gatsby/src/commands/serve.js @@ -66,8 +66,16 @@ module.exports = async program => { } return next() }) + app.use(function(req, res, next) { + res.header(`Access-Control-Allow-Origin`, `http://localhost:9000`) + 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) - app.use(cors()) const server = app.listen(port, host, () => { let openUrlString = `http://${host}:${port}${pathPrefix}` diff --git a/www/package.json b/www/package.json index 9d7f37e9c7719..dba7ea977bbeb 100644 --- a/www/package.json +++ b/www/package.json @@ -36,7 +36,7 @@ "gatsby-plugin-twitter": "^2.0.5", "gatsby-plugin-typography": "^2.2.0", "gatsby-remark-autolink-headers": "^2.0.10", - "gatsby-remark-code-titles": "^1.0.2", + "gatsby-remark-code-titles": "^1.1.0-rc.0", "gatsby-remark-copy-linked-files": "^2.0.5", "gatsby-remark-graphviz": "^1.0.0", "gatsby-remark-images": "^2.0.1", From 5b8e71478ba6f31e5665efbb040387e823d548c0 Mon Sep 17 00:00:00 2001 From: Dustin Schau Date: Mon, 25 Feb 2019 12:38:43 -0600 Subject: [PATCH 05/60] keep doing stuff --- packages/gatsby-link/src/index.js | 3 +-- 1 file changed, 1 insertion(+), 2 deletions(-) diff --git a/packages/gatsby-link/src/index.js b/packages/gatsby-link/src/index.js index bf17e895f010d..a7b16f2258e45 100644 --- a/packages/gatsby-link/src/index.js +++ b/packages/gatsby-link/src/index.js @@ -11,8 +11,7 @@ export function withPrefix(path) { return normalizePath(`${__PATH_PREFIX__}/${path}`) } -function normalizePath(path) { -} +function normalizePath(path) {} const NavLinkPropTypes = { activeClassName: PropTypes.string, From 5e7516fa2adf91c20fedd19394a88a4fa8b12fcc Mon Sep 17 00:00:00 2001 From: Dustin Schau Date: Tue, 26 Feb 2019 15:56:19 -0600 Subject: [PATCH 06/60] chore: get mostly done (let's see!) --- .eslintrc.json | 4 +++- packages/gatsby-link/src/index.js | 8 +++++--- packages/gatsby/cache-dir/production-app.js | 7 +++---- packages/gatsby/src/utils/eslint-config.js | 1 + 4 files changed, 12 insertions(+), 8 deletions(-) diff --git a/.eslintrc.json b/.eslintrc.json index 3a13dd2256028..ae572f5c43b8e 100644 --- a/.eslintrc.json +++ b/.eslintrc.json @@ -26,7 +26,9 @@ "globals": { "before": true, "spyOn": true, - "__PATH_PREFIX__": true + "__PATH_PREFIX__": true, + "__BASE_PATH__": true, + "__ASSET_PREFIX__": true }, "rules": { "arrow-body-style": [ diff --git a/packages/gatsby-link/src/index.js b/packages/gatsby-link/src/index.js index a7b16f2258e45..5d71026f71381 100644 --- a/packages/gatsby-link/src/index.js +++ b/packages/gatsby-link/src/index.js @@ -1,4 +1,4 @@ -/*global __PATH_PREFIX__ */ +/*global __BASE_PATH__ */ import PropTypes from "prop-types" import React from "react" import { Link } from "@reach/router" @@ -8,10 +8,12 @@ import { parsePath } from "./parse-path" export { parsePath } export function withPrefix(path) { - return normalizePath(`${__PATH_PREFIX__}/${path}`) + return normalizePath(`${__BASE_PATH__}/${path}`) } -function normalizePath(path) {} +function normalizePath(path) { + return path.replace(/\/+/g, `/`) +} const NavLinkPropTypes = { activeClassName: PropTypes.string, diff --git a/packages/gatsby/cache-dir/production-app.js b/packages/gatsby/cache-dir/production-app.js index 43bb9b6cbfe3e..55c1e920d8815 100644 --- a/packages/gatsby/cache-dir/production-app.js +++ b/packages/gatsby/cache-dir/production-app.js @@ -77,10 +77,9 @@ apiRunnerAsync(`onClientEntry`).then(() => { // pages have this canonical path) !page.path.match(/^\/offline-plugin-app-shell-fallback\/?$/) ) { - navigate( - __PATH_PREFIX__ + page.path + browserLoc.search + browserLoc.hash, - { replace: true } - ) + navigate(__BASE_PATH__ + page.path + browserLoc.search + browserLoc.hash, { + replace: true, + }) } loader.getResourcesForPathname(browserLoc.pathname).then(() => { diff --git a/packages/gatsby/src/utils/eslint-config.js b/packages/gatsby/src/utils/eslint-config.js index 0f5136124a040..f48e16b454b09 100644 --- a/packages/gatsby/src/utils/eslint-config.js +++ b/packages/gatsby/src/utils/eslint-config.js @@ -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 }, extends: `react-app`, plugins: [`graphql`], From 50c48419218e0ae6c6825691bd7eb14b1600d50d Mon Sep 17 00:00:00 2001 From: Dustin Schau Date: Tue, 26 Feb 2019 16:02:50 -0600 Subject: [PATCH 07/60] chore: remove unused package --- packages/gatsby/src/commands/serve.js | 1 - yarn.lock | 12 ++---------- 2 files changed, 2 insertions(+), 11 deletions(-) diff --git a/packages/gatsby/src/commands/serve.js b/packages/gatsby/src/commands/serve.js index 4289a50eae169..ed8880bc8acab 100644 --- a/packages/gatsby/src/commands/serve.js +++ b/packages/gatsby/src/commands/serve.js @@ -8,7 +8,6 @@ const express = require(`express`) const getConfigFile = require(`../bootstrap/get-config-file`) const preferDefault = require(`../bootstrap/prefer-default`) const chalk = require(`chalk`) -const cors = require(`cors`) const { match: reachMatch } = require(`@reach/router/lib/utils`) const getPages = directory => diff --git a/yarn.lock b/yarn.lock index f923eee6060b5..df4dbe404e6e6 100644 --- a/yarn.lock +++ b/yarn.lock @@ -5618,14 +5618,6 @@ core-util-is@1.0.2, core-util-is@~1.0.0: resolved "https://registry.yarnpkg.com/core-util-is/-/core-util-is-1.0.2.tgz#b5fd54220aa2bc5ab57aab7140c940754503c1a7" integrity sha1-tf1UIgqivFq1eqtxQMlAdUUDwac= -cors@^2.8.5: - version "2.8.5" - resolved "https://registry.yarnpkg.com/cors/-/cors-2.8.5.tgz#eac11da51592dd86b9f06f6e7ac293b3df875d29" - integrity sha512-KIHbLJqu73RGr/hnbrO9uBeixNGuvSQjul/jdFvS/KFSIH1hWVd1ng7zOHx+YrEfInLG7q4n6GHQ9cDtxv/P6g== - dependencies: - object-assign "^4" - vary "^1" - cosmiconfig@^4.0.0: version "4.0.0" resolved "https://registry.yarnpkg.com/cosmiconfig/-/cosmiconfig-4.0.0.tgz#760391549580bbd2df1e562bc177b13c290972dc" @@ -14022,7 +14014,7 @@ oauth-sign@~0.9.0: resolved "https://registry.yarnpkg.com/oauth-sign/-/oauth-sign-0.9.0.tgz#47a7b016baa68b5fa0ecf3dee08a85c679ac6455" integrity sha512-fexhUFFPTGV8ybAtSIGbV6gOkSv8UtRbDBnAyLQw4QPKkgNlsH2ByPGtMUqdWkos6YCRmAqViwgZrJc/mRDzZQ== -object-assign@^4, object-assign@^4.0.1, object-assign@^4.1.0, object-assign@^4.1.1: +object-assign@^4.0.1, object-assign@^4.1.0, object-assign@^4.1.1: version "4.1.1" resolved "https://registry.yarnpkg.com/object-assign/-/object-assign-4.1.1.tgz#2109adc7965887cfc05cbbd442cac8bfbb360863" integrity sha1-IQmtx5ZYh8/AXLvUQsrIv7s2CGM= @@ -19681,7 +19673,7 @@ value-or-function@^3.0.0: resolved "https://registry.yarnpkg.com/value-or-function/-/value-or-function-3.0.0.tgz#1c243a50b595c1be54a754bfece8563b9ff8d813" integrity sha1-HCQ6ULWVwb5Up1S/7OhWO5/42BM= -vary@^1, vary@~1.1.2: +vary@~1.1.2: version "1.1.2" resolved "https://registry.yarnpkg.com/vary/-/vary-1.1.2.tgz#2299f02c6ded30d4a5961b0b9f74524a18f634fc" integrity sha1-IpnwLG3tMNSllhsLn3RSShj2NPw= From e6ad72f77b60e7c05ff608c4a7b2a4b0e2ad0b18 Mon Sep 17 00:00:00 2001 From: Dustin Schau Date: Tue, 26 Feb 2019 16:42:47 -0600 Subject: [PATCH 08/60] chore: ensure url is normalized correctly --- packages/gatsby/src/utils/webpack.config.js | 11 ++++------- 1 file changed, 4 insertions(+), 7 deletions(-) diff --git a/packages/gatsby/src/utils/webpack.config.js b/packages/gatsby/src/utils/webpack.config.js index f0a4256957337..f7d580c3ab5a9 100644 --- a/packages/gatsby/src/utils/webpack.config.js +++ b/packages/gatsby/src/utils/webpack.config.js @@ -21,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 @@ -40,7 +35,9 @@ module.exports = async ( let publicPath = `/` if (program.prefixPaths && (pathPrefix || assetPrefix)) { - publicPath = url.resolve(assetPrefix, pathPrefix) + publicPath = url.resolve( + ...[assetPrefix, pathPrefix].filter(part => part && part.length > 0) + ) } function processEnv(stage, defaultNodeEnv) { From 23749b6211de4d55b38098080746bedac49fb708 Mon Sep 17 00:00:00 2001 From: Dustin Schau Date: Tue, 26 Feb 2019 16:58:21 -0600 Subject: [PATCH 09/60] chore: try try again --- packages/gatsby/src/utils/webpack.config.js | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/packages/gatsby/src/utils/webpack.config.js b/packages/gatsby/src/utils/webpack.config.js index f7d580c3ab5a9..5e17daeeadc4e 100644 --- a/packages/gatsby/src/utils/webpack.config.js +++ b/packages/gatsby/src/utils/webpack.config.js @@ -36,7 +36,7 @@ module.exports = async (program, directory, suppliedStage) => { let publicPath = `/` if (program.prefixPaths && (pathPrefix || assetPrefix)) { publicPath = url.resolve( - ...[assetPrefix, pathPrefix].filter(part => part && part.length > 0) + ...[assetPrefix, pathPrefix].map(part => part || ``) ) } From 7f9e0766128ae2827138173608e369c3875c4ecd Mon Sep 17 00:00:00 2001 From: Dustin Schau Date: Tue, 26 Feb 2019 17:42:55 -0600 Subject: [PATCH 10/60] chore: fix for base path --- packages/gatsby/cache-dir/loader.js | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/packages/gatsby/cache-dir/loader.js b/packages/gatsby/cache-dir/loader.js index 913be9cad656b..6238c588dc8dc 100644 --- a/packages/gatsby/cache-dir/loader.js +++ b/packages/gatsby/cache-dir/loader.js @@ -203,7 +203,7 @@ let disableCorePrefetching = false const queue = { addPagesArray: newPages => { - findPage = pageFinderFactory(newPages, __PATH_PREFIX__) + findPage = pageFinderFactory(newPages, __BASE_PATH__) }, addDevRequires: devRequires => { syncRequires = devRequires From 6d61a3d12c0f54a8b7a92e5f84895d065fe6bdf6 Mon Sep 17 00:00:00 2001 From: Dustin Schau Date: Tue, 26 Feb 2019 18:23:29 -0600 Subject: [PATCH 11/60] test: tests are important; fix them --- packages/gatsby-link/src/__tests__/index.js | 10 +++++----- .../src/__tests__/catch-links.js | 8 ++++---- .../gatsby-plugin-feed/src/__tests__/gatsby-ssr.js | 11 +++++------ .../src/__tests__/gatsby-ssr.js | 4 ++-- packages/gatsby/cache-dir/__tests__/static-entry.js | 1 + packages/gatsby/src/commands/serve.js | 2 +- packages/gatsby/src/joi-schemas/joi.js | 2 +- 7 files changed, 19 insertions(+), 19 deletions(-) diff --git a/packages/gatsby-link/src/__tests__/index.js b/packages/gatsby-link/src/__tests__/index.js index a25dc12702a6c..251e3f7de3573 100644 --- a/packages/gatsby-link/src/__tests__/index.js +++ b/packages/gatsby-link/src/__tests__/index.js @@ -9,7 +9,7 @@ import { import Link, { navigate, push, replace, withPrefix } from "../" afterEach(() => { - global.__PATH_PREFIX__ = `` + global.__BASE_PATH__ = `` cleanup() }) @@ -34,12 +34,12 @@ const getReplace = () => { } const getWithPrefix = (pathPrefix = ``) => { - global.__PATH_PREFIX__ = pathPrefix + global.__BASE_PATH__ = pathPrefix return withPrefix } const setup = ({ sourcePath = `/active`, linkProps, pathPrefix = `` } = {}) => { - global.__PATH_PREFIX__ = pathPrefix + global.__BASE_PATH__ = pathPrefix const source = createMemorySource(sourcePath) const history = createHistory(source) @@ -151,11 +151,11 @@ describe(`navigate`, () => { it(`respects pathPrefix`, () => { const to = `/some-path` - global.__PATH_PREFIX__ = `/blog` + global.__BASE_PATH__ = `/blog` getNavigate()(to) expect(global.___navigate).toHaveBeenCalledWith( - `${global.__PATH_PREFIX__}${to}`, + `${global.__BASE_PATH__}${to}`, undefined ) }) diff --git a/packages/gatsby-plugin-catch-links/src/__tests__/catch-links.js b/packages/gatsby-plugin-catch-links/src/__tests__/catch-links.js index f13ebf4f3f6e9..a75d9e9f473e8 100644 --- a/packages/gatsby-plugin-catch-links/src/__tests__/catch-links.js +++ b/packages/gatsby-plugin-catch-links/src/__tests__/catch-links.js @@ -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() }) 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`) diff --git a/packages/gatsby-plugin-feed/src/__tests__/gatsby-ssr.js b/packages/gatsby-plugin-feed/src/__tests__/gatsby-ssr.js index 4512841a7ddfd..1196b12bcb50d 100644 --- a/packages/gatsby-plugin-feed/src/__tests__/gatsby-ssr.js +++ b/packages/gatsby-plugin-feed/src/__tests__/gatsby-ssr.js @@ -1,14 +1,13 @@ const { onRenderBody } = require(`../gatsby-ssr`) -const defaultPathPrefix = global.__PATH_PREFIX__ - describe(`Adds for feed to head`, () => { + const prefix = global.__BASE_PATH__ beforeEach(() => { - global.__PATH_PREFIX__ = `` + global.__BASE_PATH__ = `` }) - afterEach(() => { - global.__PATH_PREFIX__ = defaultPathPrefix + afterAll(() => { + global.__BASE_PATH__ = prefix }) it(`creates Link if feeds does exist`, async () => { @@ -55,7 +54,7 @@ describe(`Adds for feed to head`, () => { expect(setHeadComponents).toHaveBeenCalledTimes(1) }) it(`creates Link href with path prefix when __PATH_PREFIX__ sets`, async () => { - global.__PATH_PREFIX__ = `/hogwarts` + global.__BASE_PATH__ = `/hogwarts` const pluginOptions = { feeds: [ diff --git a/packages/gatsby-plugin-manifest/src/__tests__/gatsby-ssr.js b/packages/gatsby-plugin-manifest/src/__tests__/gatsby-ssr.js index 87c367e5ec86b..462a759dd76e3 100644 --- a/packages/gatsby-plugin-manifest/src/__tests__/gatsby-ssr.js +++ b/packages/gatsby-plugin-manifest/src/__tests__/gatsby-ssr.js @@ -9,7 +9,7 @@ const ssrArgs = { describe(`gatsby-plugin-manifest`, () => { beforeEach(() => { - global.__PATH_PREFIX__ = `` + global.__BASE_PATH__ = `` headComponents = [] }) @@ -130,7 +130,7 @@ describe(`gatsby-plugin-manifest`, () => { }) it(`Creates href attributes using pathPrefix`, () => { - global.__PATH_PREFIX__ = `/path-prefix` + global.__BASE_PATH__ = `/path-prefix` onRenderBody(ssrArgs, { icon: true, diff --git a/packages/gatsby/cache-dir/__tests__/static-entry.js b/packages/gatsby/cache-dir/__tests__/static-entry.js index 03d857d15a1de..644374a7d8981 100644 --- a/packages/gatsby/cache-dir/__tests__/static-entry.js +++ b/packages/gatsby/cache-dir/__tests__/static-entry.js @@ -136,6 +136,7 @@ describe(`develop-static-entry`, () => { describe(`static-entry`, () => { beforeEach(() => { global.__PATH_PREFIX__ = `` + global.__BASE_PATH__ = `` }) test(`onPreRenderHTML can be used to replace headComponents`, done => { diff --git a/packages/gatsby/src/commands/serve.js b/packages/gatsby/src/commands/serve.js index ed8880bc8acab..117eec5f7a36f 100644 --- a/packages/gatsby/src/commands/serve.js +++ b/packages/gatsby/src/commands/serve.js @@ -66,7 +66,7 @@ module.exports = async program => { return next() }) app.use(function(req, res, next) { - res.header(`Access-Control-Allow-Origin`, `http://localhost:9000`) + res.header(`Access-Control-Allow-Origin`, `http://${host}:${port}`) res.header(`Access-Control-Allow-Credentials`, true) res.header( `Access-Control-Allow-Headers`, diff --git a/packages/gatsby/src/joi-schemas/joi.js b/packages/gatsby/src/joi-schemas/joi.js index 52505fcb6b5e2..d1a2792d2e708 100644 --- a/packages/gatsby/src/joi-schemas/joi.js +++ b/packages/gatsby/src/joi-schemas/joi.js @@ -1,6 +1,6 @@ const Joi = require(`joi`) -const stripTrailingSlash = chain => chain.replace(/\/$/, ``) +const stripTrailingSlash = chain => chain.replace(/(\w)\//, `$1`) export const gatsbyConfigSchema = Joi.object().keys({ __experimentalThemes: Joi.array(), From 9a33fa662a68041075ff83e208b3b84ae1d37380 Mon Sep 17 00:00:00 2001 From: Dustin Schau Date: Tue, 26 Feb 2019 18:24:44 -0600 Subject: [PATCH 12/60] chore: remove a silly change --- www/package.json | 3 ++- 1 file changed, 2 insertions(+), 1 deletion(-) diff --git a/www/package.json b/www/package.json index dba7ea977bbeb..cce827f869a9c 100644 --- a/www/package.json +++ b/www/package.json @@ -5,6 +5,7 @@ "author": "Kyle Mathews ", "dependencies": { "@reach/skip-nav": "^0.1.1", + "@reach/visually-hidden": "^0.1.2", "axios": "^0.18.0", "bluebird": "^3.5.1", "dotenv": "^6.0.0", @@ -36,7 +37,7 @@ "gatsby-plugin-twitter": "^2.0.5", "gatsby-plugin-typography": "^2.2.0", "gatsby-remark-autolink-headers": "^2.0.10", - "gatsby-remark-code-titles": "^1.1.0-rc.0", + "gatsby-remark-code-titles": "^1.0.2", "gatsby-remark-copy-linked-files": "^2.0.5", "gatsby-remark-graphviz": "^1.0.0", "gatsby-remark-images": "^2.0.1", From e8b6d7184a6a1e9060f6c211aabf38c4c7fb5e61 Mon Sep 17 00:00:00 2001 From: Dustin Schau Date: Tue, 26 Feb 2019 18:35:25 -0600 Subject: [PATCH 13/60] chore: fix linter Note: this should've been fine --- packages/gatsby/src/utils/path.js | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/packages/gatsby/src/utils/path.js b/packages/gatsby/src/utils/path.js index 33e18daee94c7..98616148246fa 100644 --- a/packages/gatsby/src/utils/path.js +++ b/packages/gatsby/src/utils/path.js @@ -15,5 +15,5 @@ export function withBasePath(basePath) { } export function withTrailingSlash(basePath) { - return basePath.replace(/([\/]+)?$/, `/`) + return `${basePath}/` } From 6687692457eb0e742bbd091183f68dc0e6b04c52 Mon Sep 17 00:00:00 2001 From: Dustin Schau Date: Tue, 26 Feb 2019 23:30:15 -0600 Subject: [PATCH 14/60] fix(gatsby-plugin-offline): hard fail if assetPrefix is used Note: very possible this may be reverted --- packages/gatsby-plugin-offline/README.md | 6 ++++ .../__snapshots__/gatsby-node.js.snap | 7 ++++ .../src/__tests__/gatsby-node.js | 36 +++++++++++++++++++ .../gatsby-plugin-offline/src/gatsby-node.js | 14 ++++++++ 4 files changed, 63 insertions(+) create mode 100644 packages/gatsby-plugin-offline/src/__tests__/__snapshots__/gatsby-node.js.snap create mode 100644 packages/gatsby-plugin-offline/src/__tests__/gatsby-node.js diff --git a/packages/gatsby-plugin-offline/README.md b/packages/gatsby-plugin-offline/README.md index 0daac0c7bf3ac..808dcb52426aa 100644 --- a/packages/gatsby-plugin-offline/README.md +++ b/packages/gatsby-plugin-offline/README.md @@ -89,6 +89,8 @@ outdated version registered in users' browsers. ## Notes +### Empty View Source and SEO + Gatsby offers great SEO capabilities and that is no different with `gatsby-plugin-offline`. However, you shouldn't think that Gatsby doesn't serve HTML tags anymore when looking at your source code in the browser (with `Right click` => `View source`). `View source` doesn't represent the actual HTML data since `gatsby-plugin-offline` registers and loads a service worker that will cache and handle this differently. Your site is loaded from the service worker, not from its actual source (check your `Network` tab in the DevTools for that). To see the HTML data that crawlers will receive, run this in your terminal: @@ -98,3 +100,7 @@ curl https://www.yourdomain.tld ``` Alternatively you can have a look at the `/public/index.html` file in your project folder. + +### `assetPrefix` + +The [asset-prefix](https://gatsbyjs.app/docs/asset-prefix) feature _cannot_ be used in conjunction with this plugin. Service workers must exist on the same domain, and so therefore they cannot be hosted via a CDN or any other asset prefix. diff --git a/packages/gatsby-plugin-offline/src/__tests__/__snapshots__/gatsby-node.js.snap b/packages/gatsby-plugin-offline/src/__tests__/__snapshots__/gatsby-node.js.snap new file mode 100644 index 0000000000000..4000f5668af2c --- /dev/null +++ b/packages/gatsby-plugin-offline/src/__tests__/__snapshots__/gatsby-node.js.snap @@ -0,0 +1,7 @@ +// Jest Snapshot v1, https://goo.gl/fbAQLP + +exports[`it throws error if assetPrefix is in config 1`] = ` +"gatsby-plugin-offline cannot be used with the assetPrefix option. + A service worker specifies that it must be served on the same domain. + Either remove the assetPrefix from gatsby-config.js or remove this plugin." +`; diff --git a/packages/gatsby-plugin-offline/src/__tests__/gatsby-node.js b/packages/gatsby-plugin-offline/src/__tests__/gatsby-node.js new file mode 100644 index 0000000000000..75643013e29cd --- /dev/null +++ b/packages/gatsby-plugin-offline/src/__tests__/gatsby-node.js @@ -0,0 +1,36 @@ +const { onPreBootstrap } = require(`../gatsby-node`) + +const getOptions = config => { + return { + reporter: { + stripIndent: jest.fn(str => str.trim()), + }, + store: { + getState() { + return { + config, + } + }, + }, + } +} + +test(`it throws error if assetPrefix is in config`, () => { + expect(() => + onPreBootstrap( + getOptions({ + assetPrefix: `https://cdn.example.com`, + }) + ) + ).toThrowErrorMatchingSnapshot() +}) + +test(`it does not throw if assetPrefix is not in config`, () => { + expect(() => + onPreBootstrap( + getOptions({ + pathPrefix: `/blog`, + }) + ) + ).not.toThrow() +}) diff --git a/packages/gatsby-plugin-offline/src/gatsby-node.js b/packages/gatsby-plugin-offline/src/gatsby-node.js index 4d014c439ed8a..882cb074d79dd 100644 --- a/packages/gatsby-plugin-offline/src/gatsby-node.js +++ b/packages/gatsby-plugin-offline/src/gatsby-node.js @@ -6,6 +6,20 @@ const _ = require(`lodash`) const getResourcesFromHTML = require(`./get-resources-from-html`) +exports.onPreInit = ({ store, reporter }) => { + const { assetPrefix } = store.getState().config + + if (assetPrefix) { + throw new Error( + reporter.stripIndent(` + gatsby-plugin-offline cannot be used with the \`assetPrefix\` option. + A service worker specifies that it must be served on the same domain. + Either remove \`assetPrefix\` from gatsby-config.js or remove this plugin. + `) + ) + } +} + exports.createPages = ({ actions }) => { if (process.env.NODE_ENV === `production`) { const { createPage } = actions From ad04a4373d2724c6fc13692b8deb691bf12e6240 Mon Sep 17 00:00:00 2001 From: Dustin Schau Date: Tue, 26 Feb 2019 23:46:46 -0600 Subject: [PATCH 15/60] refactor: add a publicPath helper --- packages/gatsby/src/utils/api-runner-node.js | 10 +++++----- packages/gatsby/src/utils/get-public-path.js | 12 ++++++++++++ packages/gatsby/src/utils/webpack.config.js | 9 ++------- 3 files changed, 19 insertions(+), 12 deletions(-) create mode 100644 packages/gatsby/src/utils/get-public-path.js diff --git a/packages/gatsby/src/utils/api-runner-node.js b/packages/gatsby/src/utils/api-runner-node.js index a4a7036473304..c7f02dde28619 100644 --- a/packages/gatsby/src/utils/api-runner-node.js +++ b/packages/gatsby/src/utils/api-runner-node.js @@ -10,6 +10,7 @@ const apiList = require(`./api-node-docs`) const createNodeId = require(`./create-node-id`) const createContentDigest = require(`./create-content-digest`) const { emitter } = require(`../redux`) +const getPublicPath = require(`./get-public-path`) const { getNonGatsbyCodeFrame } = require(`./stack-trace-utils`) // Bind action creators per plugin so we can auto-add @@ -68,7 +69,6 @@ const runAPI = (plugin, api, args) => { pluginSpan.setTag(`api`, api) pluginSpan.setTag(`plugin`, plugin.name) - let pathPrefix = `` const { store, emitter } = require(`../redux`) const { loadNodeContent, @@ -87,9 +87,9 @@ const runAPI = (plugin, api, args) => { { ...args, parentSpan: pluginSpan } ) - if (store.getState().program.prefixPaths) { - pathPrefix = store.getState().config.pathPrefix - } + const { config, program } = store.getState() + + const publicPath = getPublicPath({ ...config, ...program }) const namespacedCreateNodeId = id => createNodeId(id, plugin.name) @@ -146,7 +146,7 @@ const runAPI = (plugin, api, args) => { const apiCallArgs = [ { ...args, - pathPrefix, + pathPrefix: publicPath, boundActionCreators: actions, actions, loadNodeContent, diff --git a/packages/gatsby/src/utils/get-public-path.js b/packages/gatsby/src/utils/get-public-path.js new file mode 100644 index 0000000000000..40ca734ec30f7 --- /dev/null +++ b/packages/gatsby/src/utils/get-public-path.js @@ -0,0 +1,12 @@ +const url = require(`url`) + +module.exports = function getPublicPath( + { assetPrefix, pathPrefix, prefixPaths }, + fallback = `/` +) { + if (prefixPaths && (assetPrefix || pathPrefix)) { + return url.resolve(...[assetPrefix, pathPrefix].map(part => part || ``)) + } + + return fallback +} diff --git a/packages/gatsby/src/utils/webpack.config.js b/packages/gatsby/src/utils/webpack.config.js index 5e17daeeadc4e..f40be25b0db0c 100644 --- a/packages/gatsby/src/utils/webpack.config.js +++ b/packages/gatsby/src/utils/webpack.config.js @@ -2,11 +2,11 @@ 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 getPublicPath = require(`./get-public-path`) const debug = require(`debug`)(`gatsby:webpack-config`) const report = require(`gatsby-cli/lib/reporter`) const { withBasePath, withTrailingSlash } = require(`./path`) @@ -33,12 +33,7 @@ module.exports = async (program, directory, suppliedStage) => { const { assetPrefix, pathPrefix } = store.getState().config - let publicPath = `/` - if (program.prefixPaths && (pathPrefix || assetPrefix)) { - publicPath = url.resolve( - ...[assetPrefix, pathPrefix].map(part => part || ``) - ) - } + const publicPath = getPublicPath({ assetPrefix, pathPrefix, ...program }) function processEnv(stage, defaultNodeEnv) { debug(`Building env for "${stage}"`) From de7e73b0f05271fec4aaa9db3bb714d36dd8dc1d Mon Sep 17 00:00:00 2001 From: Dustin Schau Date: Tue, 26 Feb 2019 23:59:10 -0600 Subject: [PATCH 16/60] test: add some get public path tests --- .../src/utils/__tests__/get-public-path.js | 60 +++++++++++++++++++ packages/gatsby/src/utils/api-runner-node.js | 2 +- packages/gatsby/src/utils/get-public-path.js | 8 ++- 3 files changed, 68 insertions(+), 2 deletions(-) create mode 100644 packages/gatsby/src/utils/__tests__/get-public-path.js diff --git a/packages/gatsby/src/utils/__tests__/get-public-path.js b/packages/gatsby/src/utils/__tests__/get-public-path.js new file mode 100644 index 0000000000000..d482ce3456435 --- /dev/null +++ b/packages/gatsby/src/utils/__tests__/get-public-path.js @@ -0,0 +1,60 @@ +const getPublicPath = require(`../get-public-path`) + +const assetPrefix = `https://cdn.example.com` +const pathPrefix = `/blog` + +describe(`basic functionality`, () => { + it(`returns assetPrefix`, () => { + expect( + getPublicPath({ + assetPrefix, + prefixPaths: true, + }) + ).toBe(assetPrefix) + }) + + it(`returns pathPrefix`, () => { + expect( + getPublicPath({ + pathPrefix, + prefixPaths: true, + }) + ).toBe(`/blog`) + }) + + it(`joins assetPrefix and pathPrefix`, () => { + expect( + getPublicPath({ + pathPrefix, + assetPrefix, + prefixPaths: true, + }) + ).toBe(`${assetPrefix}${pathPrefix}`) + }) +}) + +describe(`fallback behavior`, () => { + it(`uses default if prefixPaths is not specified`, () => { + expect( + getPublicPath({ + assetPrefix, + pathPrefix, + prefixPaths: false, + }) + ).toBe(`/`) + }) + + it(`can customize the default`, () => { + const fallback = `` + expect( + getPublicPath( + { + assetPrefix, + pathPrefix, + prefixPaths: false, + }, + fallback + ) + ).toBe(fallback) + }) +}) diff --git a/packages/gatsby/src/utils/api-runner-node.js b/packages/gatsby/src/utils/api-runner-node.js index c7f02dde28619..1a15fe00cfbcd 100644 --- a/packages/gatsby/src/utils/api-runner-node.js +++ b/packages/gatsby/src/utils/api-runner-node.js @@ -89,7 +89,7 @@ const runAPI = (plugin, api, args) => { const { config, program } = store.getState() - const publicPath = getPublicPath({ ...config, ...program }) + const publicPath = getPublicPath({ ...config, ...program }, ``) const namespacedCreateNodeId = id => createNodeId(id, plugin.name) diff --git a/packages/gatsby/src/utils/get-public-path.js b/packages/gatsby/src/utils/get-public-path.js index 40ca734ec30f7..3b281990c1389 100644 --- a/packages/gatsby/src/utils/get-public-path.js +++ b/packages/gatsby/src/utils/get-public-path.js @@ -1,11 +1,17 @@ const url = require(`url`) +// url.resolve adds a trailing slash if part #2 is defined but empty string +const stripTrailingSlash = part => + part.endsWith(`/`) ? part.slice(0, -1) : part + module.exports = function getPublicPath( { assetPrefix, pathPrefix, prefixPaths }, fallback = `/` ) { if (prefixPaths && (assetPrefix || pathPrefix)) { - return url.resolve(...[assetPrefix, pathPrefix].map(part => part || ``)) + return stripTrailingSlash( + url.resolve(...[assetPrefix, pathPrefix].map(part => part || ``)) + ) } return fallback From a665cc430f328cbe6f1ccd16e1ce674be26bb9cd Mon Sep 17 00:00:00 2001 From: Dustin Schau Date: Wed, 27 Feb 2019 00:19:06 -0600 Subject: [PATCH 17/60] chore: use correct name --- packages/gatsby-plugin-offline/src/__tests__/gatsby-node.js | 6 +++--- 1 file changed, 3 insertions(+), 3 deletions(-) diff --git a/packages/gatsby-plugin-offline/src/__tests__/gatsby-node.js b/packages/gatsby-plugin-offline/src/__tests__/gatsby-node.js index 75643013e29cd..6201c6caf7b00 100644 --- a/packages/gatsby-plugin-offline/src/__tests__/gatsby-node.js +++ b/packages/gatsby-plugin-offline/src/__tests__/gatsby-node.js @@ -1,4 +1,4 @@ -const { onPreBootstrap } = require(`../gatsby-node`) +const { onPreInit } = require(`../gatsby-node`) const getOptions = config => { return { @@ -17,7 +17,7 @@ const getOptions = config => { test(`it throws error if assetPrefix is in config`, () => { expect(() => - onPreBootstrap( + onPreInit( getOptions({ assetPrefix: `https://cdn.example.com`, }) @@ -27,7 +27,7 @@ test(`it throws error if assetPrefix is in config`, () => { test(`it does not throw if assetPrefix is not in config`, () => { expect(() => - onPreBootstrap( + onPreInit( getOptions({ pathPrefix: `/blog`, }) From 9acb7cddc30e291350bc67c67c79b1e2040db6fe Mon Sep 17 00:00:00 2001 From: Dustin Schau Date: Wed, 27 Feb 2019 11:56:15 -0600 Subject: [PATCH 18/60] docs: add asset prefix doc, and tweak path prefix --- docs/docs/asset-prefix.md | 79 +++++++++++++++++++++++++++++++++++ docs/docs/path-prefix.md | 86 +++++++++++++++++++++++++++------------ 2 files changed, 140 insertions(+), 25 deletions(-) create mode 100644 docs/docs/asset-prefix.md diff --git a/docs/docs/asset-prefix.md b/docs/docs/asset-prefix.md new file mode 100644 index 0000000000000..987152f2f781b --- /dev/null +++ b/docs/docs/asset-prefix.md @@ -0,0 +1,79 @@ +--- +title: Adding an Asset Prefix +--- + +Gatsby produces static content that can be hosted _anywhere_ at scale in a cost-effective manner. This static content is comprised of HTML files, JavaScript, CSS, images, and more that power your great, Gatsby application. + +There are scenarios in which it may be advantageous or necessary to deploy _assets_ (where an asset is a non-HTML resource, e.g. JavaScript, CSS, etc.) to a separate domain, oftentimes to enable functionality like a CDN or a particular hosting strategy that your company may employ where assets need to be separate from the core application. + +This `assetPrefix` functionality is available starting in gatsby@2.2.0, so that you can seamlessly use Gatsby with assets hosted from a separate domain. To use this functionality, ensure that your version of `gatsby` specified in `package.json` is at least `2.2.0`. + +## Usage + +### Adding to `gatsby-config.js` + +```js:title=gatsby-config.js +module.exports = { + assetPrefix: `https://cdn.example.com`, +} +``` + +That was easy! One more step - when we build out this application, we need to add a flag so that Gatsby picks up this option. + +### The `--prefix-paths` flag + +When building with an `assetPrefix`, we require a `--prefix-paths` flag. If this flag is not specified, the build will ignore this option, and build out content as if it was hosted on the same domain. To ensure we build out successfully, use the following command: + +```shell +gatsby build --prefix-paths +``` + +That's it! We now have an application that is ready to have its assets deployed from a CDN and its core files (e.g. HTML files) can be hosted on a separate domain. + +## Building / Deploying + +Once your application is built out, all assets will be automatically prefixed by this asset prefix. For example, if we have a JavaScript file `app-common-1234.js`, the script tag will look something like: + +```html + +``` + +However - if we were to deploy our application as-is, those assets would not be available! We can do this in a few ways, but the general approach will be to deploy the contents of the `public` folder to _both_ your core domain, and the CDN/asset prefix location. + +### Using `onPostBuild` + +We expose an [`onPostBuild`](/docs/node-apis/#onPostBuild) API hook. This can be used to deploy your content to the CDN, like so: + +```js:title=gatsby-node.js +const assetsDirectory = `public` + +exports.onPostBuild = async function onPostBuild() { + // do something with public + // e.g. upload to S3 +} +``` + +### Using `package.json` scripts + +Additionally, we can use an npm script, which will let us use some command line interfaces/executables to perform some action, in this case, deploying our assets directory! + +In this example, I'll use the `aws-cli` and `s3` to sync the `public` folder (containing all our assets) to the `s3` bucket. + +```json:title=package.json +{ + "scripts": { + "build": "gatsby build --prefix-paths", + "postbuild": "aws s3 sync public s3://mybucket" + } +} +``` + +Now whenever the `build` script is invoked, e.g. `npm run build`, the `postbuild` script will be invoked _after_ the build completes, therefore making our assets available on a _separate_ domain after we have finished building out our appliacation with prefixed assets. + +## Additional Considerations + +### Usage with `pathPrefix` + +The [`pathPrefix`](/docs/path-prefix/) feature can be thought of as semi-related to this feature. That feature allows _all_ your website content to be prefixed with some constant prefix, for example you may want your blog to be hosted from `/blog` rather than the project root. + +This feature works seamlessly with `pathPrefix`. Build out your application with the `--prefix-paths` flag and you'll be well on your way to hosting an application with its assets hosted on a CDN, and its core functionality available behind a path prefix. diff --git a/docs/docs/path-prefix.md b/docs/docs/path-prefix.md index f7f650821ec6b..ac8d105770be0 100644 --- a/docs/docs/path-prefix.md +++ b/docs/docs/path-prefix.md @@ -2,46 +2,82 @@ title: Adding a Path Prefix --- -Many sites are hosted at something other than the root of their domain. +Many applications are hosted at something other than the root (`/`) of their domain. -E.g. a Gatsby blog could live at `example.com/blog/` or a site could be hosted -on GitHub Pages at `example.github.io/my-gatsby-site/` +For example, a Gatsby blog could live at `example.com/blog/` or a site could be hosted on GitHub Pages at `example.github.io/my-gatsby-site/` Each of these sites need a prefix added to all paths on the site. So a link to `/my-sweet-blog-post/` should be rewritten to `/blog/my-sweet-blog-post`. -In addition links to various resources (JavaScript, images, CSS) need the same -prefix added (this is accomplished by setting the `publicPath` in webpack). +In addition links to various resources (JavaScript, CSS, images, and other static content) need the same prefix, so that the site continues to function and display correctly, even if served from this path prefix. -Luckily, for most sites, this work can be offloaded to Gatsby. Using -[Gatsby's Link component](/packages/gatsby-link/) for internal links ensures those links -will be prefixed correctly. Gatsby ensures that paths created internally and by -webpack are also correctly prefixed. +## Usage -## Development +### Add to `gatsby-config.js` -During development, write paths as if there was no path prefix e.g. for a blog -hosted at `example.com/blog`, don't add `/blog` to your links. The prefix will -be added when you build for deployment. - -## Production build - -There are two steps for building a site with path prefixes. - -First define the prefix in your site's `gatsby-config.js`. - -```javascript:title=gatsby-config.js +```js:title=gatsby-config.js module.exports = { - // Note: it must *not* have a trailing slash. pathPrefix: `/blog`, } ``` -Then pass `--prefix-paths` cmd option to Gatsby. +### Build + +Once the `pathPrefix` is specified in `gastby-config.js`, we are well on our way to a prefixed app. The final step is to build out your application with a flag `--prefix-paths`, like so: ```shell gatsby build --prefix-paths ``` -NOTE: When running the command without the `--prefix-paths` flag, Gatsby ignores -your `pathPrefix`. +If this flag is not passed, Gatsby will ignore your `pathPrefix` and build out your site as if it were hosted from the root domain. + +### In-app linking + +As a developer using this feature, it should be seamless. We provide APIs and libraries to make using this functionality a breeze. Specifically, the [`Link`](/docs/gatsby-link/) component has built-in functionality to handle path prefixing. + +For example, if we want to link to our `/page-2` link (but the actual link will be prefixed, e.g. `/blog/page-2`) we don't want to hard code this path prefix in all of our links. We have your back! Merely by using the `Link` component, we will automatically prefix your paths for you. If you later migrate off of `pathPrefix` your links will _still_ work seamlessly. + +Let's look at a quick example. + +```jsx:title=src/pages/index.js +import React from "react" +import { Link } from "gatsby" +import Layout from "../components/layout" + +function Index() { + return ( + + {/* highlight-next-line */} + Page 2 + + ) +} +``` + +Without doing _anything_ and merely using the `Link` component, this link will be prefixed with our specified `pathPrefix` in `gatsby-config.js`. Woo hoo! + +If we want to do programattic/dynamic navigation, totally possible too! We expose a `navigate` helper, and this too automatically handles path prefixing. + +```jsx:title=src/pages/index.js +import React from "react" +import { navigate } from "gatsby" +import Layout from "../components/layout" + +export default function Index() { + return ( + + {/* Note: this is an intentionally contrived example, but you get the idea! */} + {/* highlight-next-line */} + + + ) +} +``` + +### Additional Considerations + +The [`assetPrefix`](/docs/asset-prefix/) feature can be thought of as semi-related to this feature. That feature allows your assets (non-HTML files, e.g. images, JavaScript, etc.) to be hosted on a separate domain, for example a CDN. + +This feature works seamlessly with `assetPrefix`. Build out your application with the `--prefix-paths` flag and you'll be well on your way to hosting an application with its assets hosted on a CDN, and its core functionality available behind a path prefix. From 26c2f33c287bd1945a662bd55630a3c13b42039c Mon Sep 17 00:00:00 2001 From: Dustin Schau Date: Wed, 27 Feb 2019 11:57:36 -0600 Subject: [PATCH 19/60] chore: allow relative url for assetPrefix --- packages/gatsby/src/joi-schemas/joi.js | 6 +++++- 1 file changed, 5 insertions(+), 1 deletion(-) diff --git a/packages/gatsby/src/joi-schemas/joi.js b/packages/gatsby/src/joi-schemas/joi.js index d1a2792d2e708..0e7c6d6ebb0a0 100644 --- a/packages/gatsby/src/joi-schemas/joi.js +++ b/packages/gatsby/src/joi-schemas/joi.js @@ -6,7 +6,11 @@ export const gatsbyConfigSchema = Joi.object().keys({ __experimentalThemes: Joi.array(), polyfill: Joi.boolean(), siteMetadata: Joi.object(), - assetPrefix: stripTrailingSlash(Joi.string().uri()), + assetPrefix: stripTrailingSlash( + Joi.string().uri({ + allowRelative: true, + }) + ), pathPrefix: stripTrailingSlash( Joi.string().uri({ allowRelative: true, From 7d2764911452b2c68e6ae8c3afc49be1be66816b Mon Sep 17 00:00:00 2001 From: Dustin Schau Date: Wed, 27 Feb 2019 12:11:58 -0600 Subject: [PATCH 20/60] test: add a few more unit tests --- .../__snapshots__/gatsby-node.js.snap | 4 +- .../gatsby/src/joi-schemas/__tests__/joi.js | 46 +++++++++++++++++++ packages/gatsby/src/joi-schemas/joi.js | 2 +- 3 files changed, 49 insertions(+), 3 deletions(-) create mode 100644 packages/gatsby/src/joi-schemas/__tests__/joi.js diff --git a/packages/gatsby-plugin-offline/src/__tests__/__snapshots__/gatsby-node.js.snap b/packages/gatsby-plugin-offline/src/__tests__/__snapshots__/gatsby-node.js.snap index 4000f5668af2c..b175f7d9a4d25 100644 --- a/packages/gatsby-plugin-offline/src/__tests__/__snapshots__/gatsby-node.js.snap +++ b/packages/gatsby-plugin-offline/src/__tests__/__snapshots__/gatsby-node.js.snap @@ -1,7 +1,7 @@ // Jest Snapshot v1, https://goo.gl/fbAQLP exports[`it throws error if assetPrefix is in config 1`] = ` -"gatsby-plugin-offline cannot be used with the assetPrefix option. +"gatsby-plugin-offline cannot be used with the \`assetPrefix\` option. A service worker specifies that it must be served on the same domain. - Either remove the assetPrefix from gatsby-config.js or remove this plugin." + Either remove \`assetPrefix\` from gatsby-config.js or remove this plugin." `; diff --git a/packages/gatsby/src/joi-schemas/__tests__/joi.js b/packages/gatsby/src/joi-schemas/__tests__/joi.js new file mode 100644 index 0000000000000..44de0da11be50 --- /dev/null +++ b/packages/gatsby/src/joi-schemas/__tests__/joi.js @@ -0,0 +1,46 @@ +const { gatsbyConfigSchema } = require(`../joi`) + +describe(`gatsby config`, () => { + it(`strips trailing slashes from url fields`, async () => { + const config = { + pathPrefix: `/blog///`, + assetPrefix: `https://cdn.example.com/`, + } + + expect(await gatsbyConfigSchema.validate(config)).toEqual({ + pathPrefix: `/blog`, + assetPrefix: `https://cdn.example.com`, + }) + }) + + it(`allows assetPrefix to be full URL`, async () => { + const config = { + assetPrefix: `https://cdn.example.com`, + } + + expect(await gatsbyConfigSchema.validate(config)).toEqual(config) + }) + + it(`allows relative paths for url fields`, async () => { + const config = { + pathPrefix: `/blog`, + assetPrefix: `/assets`, + } + + expect(await gatsbyConfigSchema.validate(config)).toEqual(config) + }) + + it(`does not allow pathPrefix to be full URL`, async () => { + const config = { + pathPrefix: `https://google.com`, + } + + try { + await gatsbyConfigSchema.validate(config) + } catch (e) { + expect(e.message).toContain(`must be a valid relative uri`) + } finally { + expect.assertions(1) + } + }) +}) diff --git a/packages/gatsby/src/joi-schemas/joi.js b/packages/gatsby/src/joi-schemas/joi.js index 0e7c6d6ebb0a0..a8198d74cff17 100644 --- a/packages/gatsby/src/joi-schemas/joi.js +++ b/packages/gatsby/src/joi-schemas/joi.js @@ -1,6 +1,6 @@ const Joi = require(`joi`) -const stripTrailingSlash = chain => chain.replace(/(\w)\//, `$1`) +const stripTrailingSlash = chain => chain.replace(/(\w)\/+/, `$1`) export const gatsbyConfigSchema = Joi.object().keys({ __experimentalThemes: Joi.array(), From f58d9a3fabc6c48ad8e3dd7bc37cf789a42b6ba1 Mon Sep 17 00:00:00 2001 From: Dustin Schau Date: Wed, 27 Feb 2019 12:17:24 -0600 Subject: [PATCH 21/60] test: clean up test --- .../joi-schemas/__tests__/__snapshots__/joi.js.snap | 3 +++ packages/gatsby/src/joi-schemas/__tests__/joi.js | 12 ++++-------- 2 files changed, 7 insertions(+), 8 deletions(-) create mode 100644 packages/gatsby/src/joi-schemas/__tests__/__snapshots__/joi.js.snap diff --git a/packages/gatsby/src/joi-schemas/__tests__/__snapshots__/joi.js.snap b/packages/gatsby/src/joi-schemas/__tests__/__snapshots__/joi.js.snap new file mode 100644 index 0000000000000..b862e99ec74ed --- /dev/null +++ b/packages/gatsby/src/joi-schemas/__tests__/__snapshots__/joi.js.snap @@ -0,0 +1,3 @@ +// Jest Snapshot v1, https://goo.gl/fbAQLP + +exports[`gatsby config does not allow pathPrefix to be full URL 1`] = `"child \\"pathPrefix\\" fails because [\\"pathPrefix\\" must be a valid relative uri]"`; diff --git a/packages/gatsby/src/joi-schemas/__tests__/joi.js b/packages/gatsby/src/joi-schemas/__tests__/joi.js index 44de0da11be50..f36ad710e06c7 100644 --- a/packages/gatsby/src/joi-schemas/__tests__/joi.js +++ b/packages/gatsby/src/joi-schemas/__tests__/joi.js @@ -30,17 +30,13 @@ describe(`gatsby config`, () => { expect(await gatsbyConfigSchema.validate(config)).toEqual(config) }) - it(`does not allow pathPrefix to be full URL`, async () => { + it(`does not allow pathPrefix to be full URL`, () => { const config = { pathPrefix: `https://google.com`, } - try { - await gatsbyConfigSchema.validate(config) - } catch (e) { - expect(e.message).toContain(`must be a valid relative uri`) - } finally { - expect.assertions(1) - } + expect( + gatsbyConfigSchema.validate(config) + ).rejects.toThrowErrorMatchingSnapshot() }) }) From 52d3e21594b2b4041329e3fe20f5eeac1ca44c26 Mon Sep 17 00:00:00 2001 From: Dustin Schau Date: Wed, 27 Feb 2019 13:10:00 -0600 Subject: [PATCH 22/60] chore: fix e2e-test Note: this is a bug, will fix the underlying bug too. pathPrefix should have no effect unless using --prefix-paths --- e2e-tests/gatsby-image/gatsby-config.js | 1 - 1 file changed, 1 deletion(-) diff --git a/e2e-tests/gatsby-image/gatsby-config.js b/e2e-tests/gatsby-image/gatsby-config.js index bbee39b3be5a0..a3d119648e60e 100644 --- a/e2e-tests/gatsby-image/gatsby-config.js +++ b/e2e-tests/gatsby-image/gatsby-config.js @@ -1,7 +1,6 @@ const path = require(`path`) module.exports = { - pathPrefix: `/blog`, siteMetadata: { title: `Gatsby Image e2e`, }, From b144bd261b6dfbc4f04ce2a7afce457f3a626849 Mon Sep 17 00:00:00 2001 From: Dustin Schau Date: Wed, 27 Feb 2019 13:38:36 -0600 Subject: [PATCH 23/60] fix: fall back to empty string, not slash --- .../src/utils/__tests__/get-public-path.js | 26 ------------------- packages/gatsby/src/utils/get-public-path.js | 11 ++++---- 2 files changed, 6 insertions(+), 31 deletions(-) diff --git a/packages/gatsby/src/utils/__tests__/get-public-path.js b/packages/gatsby/src/utils/__tests__/get-public-path.js index d482ce3456435..7300d1c8860c5 100644 --- a/packages/gatsby/src/utils/__tests__/get-public-path.js +++ b/packages/gatsby/src/utils/__tests__/get-public-path.js @@ -32,29 +32,3 @@ describe(`basic functionality`, () => { ).toBe(`${assetPrefix}${pathPrefix}`) }) }) - -describe(`fallback behavior`, () => { - it(`uses default if prefixPaths is not specified`, () => { - expect( - getPublicPath({ - assetPrefix, - pathPrefix, - prefixPaths: false, - }) - ).toBe(`/`) - }) - - it(`can customize the default`, () => { - const fallback = `` - expect( - getPublicPath( - { - assetPrefix, - pathPrefix, - prefixPaths: false, - }, - fallback - ) - ).toBe(fallback) - }) -}) diff --git a/packages/gatsby/src/utils/get-public-path.js b/packages/gatsby/src/utils/get-public-path.js index 3b281990c1389..42cc8cb39751f 100644 --- a/packages/gatsby/src/utils/get-public-path.js +++ b/packages/gatsby/src/utils/get-public-path.js @@ -4,15 +4,16 @@ const url = require(`url`) const stripTrailingSlash = part => part.endsWith(`/`) ? part.slice(0, -1) : part -module.exports = function getPublicPath( - { assetPrefix, pathPrefix, prefixPaths }, - fallback = `/` -) { +module.exports = function getPublicPath({ + assetPrefix, + pathPrefix, + prefixPaths, +}) { if (prefixPaths && (assetPrefix || pathPrefix)) { return stripTrailingSlash( url.resolve(...[assetPrefix, pathPrefix].map(part => part || ``)) ) } - return fallback + return `` } From fe0f94a563d5462e51c2afbac00f8f2e9e7f43ad Mon Sep 17 00:00:00 2001 From: Dustin Schau Date: Wed, 27 Feb 2019 18:53:35 -0600 Subject: [PATCH 24/60] Update docs/docs/asset-prefix.md --- docs/docs/asset-prefix.md | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/docs/docs/asset-prefix.md b/docs/docs/asset-prefix.md index 987152f2f781b..ed5529cd4e904 100644 --- a/docs/docs/asset-prefix.md +++ b/docs/docs/asset-prefix.md @@ -4,7 +4,7 @@ title: Adding an Asset Prefix Gatsby produces static content that can be hosted _anywhere_ at scale in a cost-effective manner. This static content is comprised of HTML files, JavaScript, CSS, images, and more that power your great, Gatsby application. -There are scenarios in which it may be advantageous or necessary to deploy _assets_ (where an asset is a non-HTML resource, e.g. JavaScript, CSS, etc.) to a separate domain, oftentimes to enable functionality like a CDN or a particular hosting strategy that your company may employ where assets need to be separate from the core application. +There are scenarios in which it may be advantageous or necessary to deploy _assets_ (where an asset is a non-HTML resource, e.g. JavaScript, CSS, etc.) to a separate domain. This can oftentimes be used to enable functionality like a CDN or a particular hosting strategy that your company may employ where assets need to be separate from the core application. This `assetPrefix` functionality is available starting in gatsby@2.2.0, so that you can seamlessly use Gatsby with assets hosted from a separate domain. To use this functionality, ensure that your version of `gatsby` specified in `package.json` is at least `2.2.0`. From 4ac9648e9d3677634e173585546208670adb494a Mon Sep 17 00:00:00 2001 From: Dustin Schau Date: Fri, 8 Mar 2019 13:31:54 -0600 Subject: [PATCH 25/60] fix: handle relative paths --- .../src/utils/__tests__/get-public-path.js | 47 +++++++++++++++++++ packages/gatsby/src/utils/get-public-path.js | 16 ++++--- 2 files changed, 56 insertions(+), 7 deletions(-) diff --git a/packages/gatsby/src/utils/__tests__/get-public-path.js b/packages/gatsby/src/utils/__tests__/get-public-path.js index 7300d1c8860c5..6eb60aaaf0040 100644 --- a/packages/gatsby/src/utils/__tests__/get-public-path.js +++ b/packages/gatsby/src/utils/__tests__/get-public-path.js @@ -31,4 +31,51 @@ describe(`basic functionality`, () => { }) ).toBe(`${assetPrefix}${pathPrefix}`) }) + + describe(`assetPrefix variations`, () => { + it(`handles relative assetPrefix`, () => { + const localAssetPrefix = `/assets` + expect( + getPublicPath({ + pathPrefix, + assetPrefix: localAssetPrefix, + prefixPaths: true, + }) + ).toBe(`${localAssetPrefix}${pathPrefix}`) + }) + + it(`handles URL assetPrefix, e.g. a CDN`, () => { + const cdn = `https://cdn.example.org` + expect( + getPublicPath({ + pathPrefix, + assetPrefix: cdn, + prefixPaths: true, + }) + ).toBe(`${cdn}${pathPrefix}`) + }) + + it(`handles double slashes`, () => { + const cdn = `//cdn.example.org` + expect( + getPublicPath({ + pathPrefix, + assetPrefix: cdn, + prefixPaths: true, + }) + ).toBe(`${cdn}${pathPrefix}`) + }) + + it(`handles trailing slashes`, () => { + ;[`/assets/`, `https://cdn.example.org/`].forEach(prefix => { + expect( + getPublicPath({ + pathPrefix, + assetPrefix: prefix, + prefixPaths: true, + }) + ).toBe(`${prefix.slice(0, -1)}${pathPrefix}`) + }) + }) + }) }) diff --git a/packages/gatsby/src/utils/get-public-path.js b/packages/gatsby/src/utils/get-public-path.js index 42cc8cb39751f..35adf992d05a6 100644 --- a/packages/gatsby/src/utils/get-public-path.js +++ b/packages/gatsby/src/utils/get-public-path.js @@ -1,8 +1,7 @@ -const url = require(`url`) +const trimSlashes = part => part.replace(/(^\/)|(\/$)/g, ``) -// url.resolve adds a trailing slash if part #2 is defined but empty string -const stripTrailingSlash = part => - part.endsWith(`/`) ? part.slice(0, -1) : part +const isURL = possibleUrl => + [`http`, `//`].some(expr => possibleUrl.startsWith(expr)) module.exports = function getPublicPath({ assetPrefix, @@ -10,9 +9,12 @@ module.exports = function getPublicPath({ prefixPaths, }) { if (prefixPaths && (assetPrefix || pathPrefix)) { - return stripTrailingSlash( - url.resolve(...[assetPrefix, pathPrefix].map(part => part || ``)) - ) + const normalized = [assetPrefix, pathPrefix] + .filter(part => part && part.length > 0) + .map(part => trimSlashes(part)) + .join(`/`) + + return isURL(normalized) ? normalized : `/${normalized}` } return `` From 7e3b1e2713acd8d2ab539d177c88e3a752352228 Mon Sep 17 00:00:00 2001 From: Dustin Schau Date: Fri, 8 Mar 2019 14:20:53 -0600 Subject: [PATCH 26/60] feat: add withAssetPrefix helper for gatsby-link This should rarely be used--but should be exposed --- packages/gatsby-link/index.d.ts | 1 + packages/gatsby-link/src/index.js | 4 ++++ packages/gatsby/cache-dir/gatsby-browser-entry.js | 2 ++ packages/gatsby/index.d.ts | 1 + 4 files changed, 8 insertions(+) diff --git a/packages/gatsby-link/index.d.ts b/packages/gatsby-link/index.d.ts index 43a51922da898..a48c281111a99 100644 --- a/packages/gatsby-link/index.d.ts +++ b/packages/gatsby-link/index.d.ts @@ -15,6 +15,7 @@ export default class GatsbyLink extends React.Component< > {} export const navigate: NavigateFn export const withPrefix: (path: string) => string +export const withAssetPrefix: (path: string) => string // TODO: Remove navigateTo, push & replace for Gatsby v3 export const push: (to: string) => void diff --git a/packages/gatsby-link/src/index.js b/packages/gatsby-link/src/index.js index 87e7158283676..d0663dfc5a825 100644 --- a/packages/gatsby-link/src/index.js +++ b/packages/gatsby-link/src/index.js @@ -11,6 +11,10 @@ export function withPrefix(path) { return normalizePath(`${__BASE_PATH__}/${path}`) } +export function withAssetPrefix(path) { + return `${__PATH_PREFIX__}/${path}` +} + function normalizePath(path) { return path.replace(/\/+/g, `/`) } diff --git a/packages/gatsby/cache-dir/gatsby-browser-entry.js b/packages/gatsby/cache-dir/gatsby-browser-entry.js index 6126d73cad228..b55c014a5aae8 100644 --- a/packages/gatsby/cache-dir/gatsby-browser-entry.js +++ b/packages/gatsby/cache-dir/gatsby-browser-entry.js @@ -2,6 +2,7 @@ import React from "react" import PropTypes from "prop-types" import Link, { withPrefix, + withAssetPrefix, navigate, push, replace, @@ -69,6 +70,7 @@ function graphql() { export { Link, + withAssetPrefix, withPrefix, graphql, parsePath, diff --git a/packages/gatsby/index.d.ts b/packages/gatsby/index.d.ts index 2a944647ca28f..4b522ae13c945 100644 --- a/packages/gatsby/index.d.ts +++ b/packages/gatsby/index.d.ts @@ -9,6 +9,7 @@ export { push, replace, withPrefix, + withAssetPrefix, } from "gatsby-link" type RenderCallback = (data: any) => React.ReactNode From da452566a325de40c7565eeda9d1d027ab8ff720 Mon Sep 17 00:00:00 2001 From: Dustin Schau Date: Fri, 8 Mar 2019 14:23:47 -0600 Subject: [PATCH 27/60] fix: use withAssetPrefix (if available) for gatsby-plugin-manifest --- packages/gatsby-plugin-manifest/src/gatsby-ssr.js | 5 +++-- 1 file changed, 3 insertions(+), 2 deletions(-) diff --git a/packages/gatsby-plugin-manifest/src/gatsby-ssr.js b/packages/gatsby-plugin-manifest/src/gatsby-ssr.js index 5053e167053ef..fe75f6101cd56 100644 --- a/packages/gatsby-plugin-manifest/src/gatsby-ssr.js +++ b/packages/gatsby-plugin-manifest/src/gatsby-ssr.js @@ -1,8 +1,9 @@ import React from "react" -import { withPrefix } from "gatsby" +import { withPrefix as fallbackWithPrefix, withAssetPrefix } from "gatsby" import { defaultIcons } from "./common.js" exports.onRenderBody = ({ setHeadComponents }, pluginOptions) => { + const withPrefix = withAssetPrefix || fallbackWithPrefix // We use this to build a final array to pass as the argument to setHeadComponents at the end of onRenderBody. let headComponents = [] @@ -35,7 +36,7 @@ exports.onRenderBody = ({ setHeadComponents }, pluginOptions) => { ) From c7c68599fb7ffce48a0ec0f970f427595cce02ef Mon Sep 17 00:00:00 2001 From: David Bailey Date: Mon, 18 Mar 2019 15:52:19 +0000 Subject: [PATCH 28/60] Allow using gatsby-plugin-offline with assetPrefix --- packages/gatsby-plugin-offline/README.md | 4 --- .../__snapshots__/gatsby-node.js.snap | 7 ---- .../src/__tests__/gatsby-node.js | 36 ------------------- .../gatsby-plugin-offline/src/gatsby-node.js | 14 -------- .../cache-dir/register-service-worker.js | 2 +- 5 files changed, 1 insertion(+), 62 deletions(-) delete mode 100644 packages/gatsby-plugin-offline/src/__tests__/__snapshots__/gatsby-node.js.snap delete mode 100644 packages/gatsby-plugin-offline/src/__tests__/gatsby-node.js diff --git a/packages/gatsby-plugin-offline/README.md b/packages/gatsby-plugin-offline/README.md index 808dcb52426aa..6eccec542cfb6 100644 --- a/packages/gatsby-plugin-offline/README.md +++ b/packages/gatsby-plugin-offline/README.md @@ -100,7 +100,3 @@ curl https://www.yourdomain.tld ``` Alternatively you can have a look at the `/public/index.html` file in your project folder. - -### `assetPrefix` - -The [asset-prefix](https://gatsbyjs.app/docs/asset-prefix) feature _cannot_ be used in conjunction with this plugin. Service workers must exist on the same domain, and so therefore they cannot be hosted via a CDN or any other asset prefix. diff --git a/packages/gatsby-plugin-offline/src/__tests__/__snapshots__/gatsby-node.js.snap b/packages/gatsby-plugin-offline/src/__tests__/__snapshots__/gatsby-node.js.snap deleted file mode 100644 index b175f7d9a4d25..0000000000000 --- a/packages/gatsby-plugin-offline/src/__tests__/__snapshots__/gatsby-node.js.snap +++ /dev/null @@ -1,7 +0,0 @@ -// Jest Snapshot v1, https://goo.gl/fbAQLP - -exports[`it throws error if assetPrefix is in config 1`] = ` -"gatsby-plugin-offline cannot be used with the \`assetPrefix\` option. - A service worker specifies that it must be served on the same domain. - Either remove \`assetPrefix\` from gatsby-config.js or remove this plugin." -`; diff --git a/packages/gatsby-plugin-offline/src/__tests__/gatsby-node.js b/packages/gatsby-plugin-offline/src/__tests__/gatsby-node.js deleted file mode 100644 index 6201c6caf7b00..0000000000000 --- a/packages/gatsby-plugin-offline/src/__tests__/gatsby-node.js +++ /dev/null @@ -1,36 +0,0 @@ -const { onPreInit } = require(`../gatsby-node`) - -const getOptions = config => { - return { - reporter: { - stripIndent: jest.fn(str => str.trim()), - }, - store: { - getState() { - return { - config, - } - }, - }, - } -} - -test(`it throws error if assetPrefix is in config`, () => { - expect(() => - onPreInit( - getOptions({ - assetPrefix: `https://cdn.example.com`, - }) - ) - ).toThrowErrorMatchingSnapshot() -}) - -test(`it does not throw if assetPrefix is not in config`, () => { - expect(() => - onPreInit( - getOptions({ - pathPrefix: `/blog`, - }) - ) - ).not.toThrow() -}) diff --git a/packages/gatsby-plugin-offline/src/gatsby-node.js b/packages/gatsby-plugin-offline/src/gatsby-node.js index 882cb074d79dd..4d014c439ed8a 100644 --- a/packages/gatsby-plugin-offline/src/gatsby-node.js +++ b/packages/gatsby-plugin-offline/src/gatsby-node.js @@ -6,20 +6,6 @@ const _ = require(`lodash`) const getResourcesFromHTML = require(`./get-resources-from-html`) -exports.onPreInit = ({ store, reporter }) => { - const { assetPrefix } = store.getState().config - - if (assetPrefix) { - throw new Error( - reporter.stripIndent(` - gatsby-plugin-offline cannot be used with the \`assetPrefix\` option. - A service worker specifies that it must be served on the same domain. - Either remove \`assetPrefix\` from gatsby-config.js or remove this plugin. - `) - ) - } -} - exports.createPages = ({ actions }) => { if (process.env.NODE_ENV === `production`) { const { createPage } = actions diff --git a/packages/gatsby/cache-dir/register-service-worker.js b/packages/gatsby/cache-dir/register-service-worker.js index acb6347b450b0..52eb37a8475ae 100644 --- a/packages/gatsby/cache-dir/register-service-worker.js +++ b/packages/gatsby/cache-dir/register-service-worker.js @@ -9,7 +9,7 @@ if ( ) } else if (`serviceWorker` in navigator) { navigator.serviceWorker - .register(`${__PATH_PREFIX__}/sw.js`) + .register(`${__BASE_PATH__}/sw.js`) .then(function(reg) { reg.addEventListener(`updatefound`, () => { apiRunner(`onServiceWorkerUpdateFound`, { serviceWorker: reg }) From 87c9815430bcc1a22683e61511e7140c9ecc3c98 Mon Sep 17 00:00:00 2001 From: David Bailey Date: Mon, 18 Mar 2019 17:09:24 +0000 Subject: [PATCH 29/60] Add docs for using offline-plugin with asset prefix --- docs/docs/asset-prefix.md | 21 +++++++++++++++++++++ 1 file changed, 21 insertions(+) diff --git a/docs/docs/asset-prefix.md b/docs/docs/asset-prefix.md index ed5529cd4e904..6e3e7e1ec333d 100644 --- a/docs/docs/asset-prefix.md +++ b/docs/docs/asset-prefix.md @@ -77,3 +77,24 @@ Now whenever the `build` script is invoked, e.g. `npm run build`, the `postbuild The [`pathPrefix`](/docs/path-prefix/) feature can be thought of as semi-related to this feature. That feature allows _all_ your website content to be prefixed with some constant prefix, for example you may want your blog to be hosted from `/blog` rather than the project root. This feature works seamlessly with `pathPrefix`. Build out your application with the `--prefix-paths` flag and you'll be well on your way to hosting an application with its assets hosted on a CDN, and its core functionality available behind a path prefix. + +### Usage with `gatsby-plugin-offline` + +When using a custom asset prefix with `gatsby-plugin-offline`, your assets can still be cached offline. However, to ensure the plugin works correctly, there are a few things you need to do. + +1. Your asset server needs to have the following headers set: + + ``` + Access-Control-Allow-Origin: + Access-Control-Allow-Credentials: true + ``` + + Note that the origin needs to be specific, rather than using `*` to allow all origins. This is because Gatsby makes requests to fetch resources with `withCredentials` set to `true`, which disallows using `*` to match all origins. For local testing, use the following: + + ``` + Access-Control-Allow-Origin: http://localhost:9000 + ``` + +2. Certain essential resources need to be available on your content server (i.e. the one used to serve pages). This includes `sw.js`, as well as resources to precache: the Webpack bundle, the app bundle, the manifest (and any icons referenced), and the resources for the offline plugin app shell. + + You can find most of these by looking for the `self.__precacheManifest` variable in your generated `sw.js`. Remember to also include `sw.js` itself, and any icons referenced in your `manifest.webmanifest` if you have one. To check your service worker is functioning as expected, look in Application → Service Workers in your browser dev tools, and check for any failed resources in the Console/Network tabs. From 6110801778337550f9df5552bb6ce97d9bc2ab4d Mon Sep 17 00:00:00 2001 From: David Bailey Date: Mon, 18 Mar 2019 17:10:44 +0000 Subject: [PATCH 30/60] clarify docs --- docs/docs/asset-prefix.md | 6 +----- 1 file changed, 1 insertion(+), 5 deletions(-) diff --git a/docs/docs/asset-prefix.md b/docs/docs/asset-prefix.md index 6e3e7e1ec333d..0d5515dc78da6 100644 --- a/docs/docs/asset-prefix.md +++ b/docs/docs/asset-prefix.md @@ -89,11 +89,7 @@ When using a custom asset prefix with `gatsby-plugin-offline`, your assets can s Access-Control-Allow-Credentials: true ``` - Note that the origin needs to be specific, rather than using `*` to allow all origins. This is because Gatsby makes requests to fetch resources with `withCredentials` set to `true`, which disallows using `*` to match all origins. For local testing, use the following: - - ``` - Access-Control-Allow-Origin: http://localhost:9000 - ``` + Note that the origin needs to be specific, rather than using `*` to allow all origins. This is because Gatsby makes requests to fetch resources with `withCredentials` set to `true`, which disallows using `*` to match all origins. This is also why the second header is required. For local testing, use `http://localhost:9000` as the origin. 2. Certain essential resources need to be available on your content server (i.e. the one used to serve pages). This includes `sw.js`, as well as resources to precache: the Webpack bundle, the app bundle, the manifest (and any icons referenced), and the resources for the offline plugin app shell. From 7734c5eb03640b093279897cf5602e4df6e7da4f Mon Sep 17 00:00:00 2001 From: Dustin Schau Date: Tue, 26 Mar 2019 15:25:53 -0500 Subject: [PATCH 31/60] feat(*): use withAssetPrefix helper from gatsby-link BREAKING CHANGE: this is a breaking change (as currently authored) for a few plugins (specified in this commit). I'll work on a fallback--but I think it might make sense to just fail here. We can specify a peerDependency in the package.json of each of these packages, too. --- packages/gatsby-plugin-feed/src/gatsby-ssr.js | 4 ++-- packages/gatsby-plugin-manifest/src/gatsby-ssr.js | 13 ++++++++----- packages/gatsby-plugin-sitemap/src/gatsby-ssr.js | 4 ++-- packages/gatsby/src/commands/serve.js | 11 ++++++----- 4 files changed, 18 insertions(+), 14 deletions(-) diff --git a/packages/gatsby-plugin-feed/src/gatsby-ssr.js b/packages/gatsby-plugin-feed/src/gatsby-ssr.js index 85a0533a013b5..b869c0c16c3d2 100644 --- a/packages/gatsby-plugin-feed/src/gatsby-ssr.js +++ b/packages/gatsby-plugin-feed/src/gatsby-ssr.js @@ -1,5 +1,5 @@ import React from "react" -import { withPrefix } from "gatsby" +import { withAssetPrefix } from "gatsby" import { defaultOptions } from "./internals" exports.onRenderBody = ({ setHeadComponents }, pluginOptions) => { @@ -19,7 +19,7 @@ exports.onRenderBody = ({ setHeadComponents }, pluginOptions) => { rel="alternate" type="application/rss+xml" title={title} - href={withPrefix(output)} + href={withAssetPrefix(output)} /> ) }) diff --git a/packages/gatsby-plugin-manifest/src/gatsby-ssr.js b/packages/gatsby-plugin-manifest/src/gatsby-ssr.js index 18f582856d01f..8fb30b2632d72 100644 --- a/packages/gatsby-plugin-manifest/src/gatsby-ssr.js +++ b/packages/gatsby-plugin-manifest/src/gatsby-ssr.js @@ -1,13 +1,12 @@ import React from "react" import fs from "fs" -import { withPrefix as fallbackWithPrefix, withAssetPrefix } from "gatsby" +import { withAssetPrefix } from "gatsby" import { defaultIcons, createContentDigest, addDigestToPath } from "./common.js" let iconDigest = null exports.onRenderBody = ({ setHeadComponents }, pluginOptions) => { - const withPrefix = withAssetPrefix || fallbackWithPrefix // We use this to build a final array to pass as the argument to setHeadComponents at the end of onRenderBody. let headComponents = [] @@ -38,7 +37,9 @@ exports.onRenderBody = ({ setHeadComponents }, pluginOptions) => { ) } @@ -49,7 +50,7 @@ exports.onRenderBody = ({ setHeadComponents }, pluginOptions) => { ) @@ -78,7 +79,9 @@ exports.onRenderBody = ({ setHeadComponents }, pluginOptions) => { key={`gatsby-plugin-manifest-apple-touch-icon-${icon.sizes}`} rel="apple-touch-icon" sizes={icon.sizes} - href={withPrefix(addDigestToPath(icon.src, iconDigest, cacheBusting))} + href={withAssetPrefix( + addDigestToPath(icon.src, iconDigest, cacheBusting) + )} /> )) diff --git a/packages/gatsby-plugin-sitemap/src/gatsby-ssr.js b/packages/gatsby-plugin-sitemap/src/gatsby-ssr.js index 818242000ea33..dcee32db51f9a 100644 --- a/packages/gatsby-plugin-sitemap/src/gatsby-ssr.js +++ b/packages/gatsby-plugin-sitemap/src/gatsby-ssr.js @@ -1,5 +1,5 @@ import React from "react" -import { withPrefix } from "gatsby" +import { withAssetPrefix } from "gatsby" import { defaultOptions } from "./internals" exports.onRenderBody = ({ setHeadComponents }, pluginOptions) => { @@ -18,7 +18,7 @@ exports.onRenderBody = ({ setHeadComponents }, pluginOptions) => { key={`gatsby-plugin-sitemap`} rel="sitemap" type="application/xml" - href={withPrefix(output)} + href={withAssetPrefix(output)} />, ]) } diff --git a/packages/gatsby/src/commands/serve.js b/packages/gatsby/src/commands/serve.js index 11092f4b419a1..8647ada45d0c8 100644 --- a/packages/gatsby/src/commands/serve.js +++ b/packages/gatsby/src/commands/serve.js @@ -5,13 +5,13 @@ const fs = require(`fs-extra`) const signalExit = require(`signal-exit`) const compression = require(`compression`) const express = require(`express`) -const getConfigFile = require(`../bootstrap/get-config-file`) -const preferDefault = require(`../bootstrap/prefer-default`) const chalk = require(`chalk`) const { match: reachMatch } = require(`@reach/router/lib/utils`) - const telemetry = require(`gatsby-telemetry`) +const getConfigFile = require(`../bootstrap/get-config-file`) +const preferDefault = require(`../bootstrap/prefer-default`) + const getPages = directory => fs .readFile(path.join(directory, `.cache`, `pages.json`)) @@ -51,8 +51,9 @@ module.exports = async program => { getConfigFile(program.directory, `gatsby-config`) ) - let pathPrefix = config && config.pathPrefix - pathPrefix = prefixPaths && pathPrefix ? pathPrefix : `/` + const { pathPrefix: configPathPrefix } = config + + const pathPrefix = prefixPaths && configPathPrefix ? configPathPrefix : `/` const root = path.join(program.directory, `public`) const pages = await getPages(program.directory) From b8a1c2c5456679c805c5b772876c9a82d85bbfe2 Mon Sep 17 00:00:00 2001 From: Dustin Schau Date: Thu, 28 Mar 2019 11:15:42 -0500 Subject: [PATCH 32/60] test: get tests passing --- packages/gatsby/cache-dir/__tests__/static-entry.js | 1 + yarn.lock | 5 +++++ 2 files changed, 6 insertions(+) diff --git a/packages/gatsby/cache-dir/__tests__/static-entry.js b/packages/gatsby/cache-dir/__tests__/static-entry.js index fd757fdf5834a..7c5e2f7ecdb62 100644 --- a/packages/gatsby/cache-dir/__tests__/static-entry.js +++ b/packages/gatsby/cache-dir/__tests__/static-entry.js @@ -175,6 +175,7 @@ describe(`develop-static-entry`, () => { describe(`static-entry sanity checks`, () => { beforeEach(() => { global.__PATH_PREFIX__ = `` + global.__BASE_PATH__ = `` }) const methodsToCheck = [ diff --git a/yarn.lock b/yarn.lock index 0cf0dd3a93513..c6d46cebb6fe4 100644 --- a/yarn.lock +++ b/yarn.lock @@ -16300,6 +16300,11 @@ shebang-regex@^1.0.0: version "1.0.0" resolved "https://registry.yarnpkg.com/shebang-regex/-/shebang-regex-1.0.0.tgz#da42f49740c0b42db2ca9728571cb190c98efea3" +shell-escape@^0.2.0: + version "0.2.0" + resolved "https://registry.yarnpkg.com/shell-escape/-/shell-escape-0.2.0.tgz#68fd025eb0490b4f567a027f0bf22480b5f84133" + integrity sha1-aP0CXrBJC09WegJ/C/IkgLX4QTM= + shell-quote@1.6.1, shell-quote@^1.6.1: version "1.6.1" resolved "https://registry.yarnpkg.com/shell-quote/-/shell-quote-1.6.1.tgz#f4781949cce402697127430ea3b3c5476f481767" From 39403b8ac211d9c70b7fc028772aed37a1970807 Mon Sep 17 00:00:00 2001 From: Dustin Schau Date: Thu, 28 Mar 2019 11:19:35 -0500 Subject: [PATCH 33/60] test: add a test for assetPrefix with nesting --- .../gatsby/src/joi-schemas/__tests__/joi.js | 20 +++++++++++++------ packages/gatsby/src/joi-schemas/joi.js | 2 +- 2 files changed, 15 insertions(+), 7 deletions(-) diff --git a/packages/gatsby/src/joi-schemas/__tests__/joi.js b/packages/gatsby/src/joi-schemas/__tests__/joi.js index f36ad710e06c7..3e00d0e1fad1b 100644 --- a/packages/gatsby/src/joi-schemas/__tests__/joi.js +++ b/packages/gatsby/src/joi-schemas/__tests__/joi.js @@ -1,33 +1,41 @@ const { gatsbyConfigSchema } = require(`../joi`) describe(`gatsby config`, () => { - it(`strips trailing slashes from url fields`, async () => { + it(`strips trailing slashes from url fields`, () => { const config = { pathPrefix: `/blog///`, assetPrefix: `https://cdn.example.com/`, } - expect(await gatsbyConfigSchema.validate(config)).toEqual({ + expect(gatsbyConfigSchema.validate(config)).resolves.toEqual({ pathPrefix: `/blog`, assetPrefix: `https://cdn.example.com`, }) }) - it(`allows assetPrefix to be full URL`, async () => { + it(`allows assetPrefix to be full URL`, () => { const config = { assetPrefix: `https://cdn.example.com`, } - expect(await gatsbyConfigSchema.validate(config)).toEqual(config) + expect(gatsbyConfigSchema.validate(config)).resolves.toEqual(config) }) - it(`allows relative paths for url fields`, async () => { + it(`allows assetPrefix to be a URL with nested paths`, () => { + const config = { + assetPrefix: `https://cdn.example.com/some/nested/path`, + } + + expect(gatsbyConfigSchema.validate(config)).resolves.toEqual(config) + }) + + it(`allows relative paths for url fields`, () => { const config = { pathPrefix: `/blog`, assetPrefix: `/assets`, } - expect(await gatsbyConfigSchema.validate(config)).toEqual(config) + expect(gatsbyConfigSchema.validate(config)).resolves.toEqual(config) }) it(`does not allow pathPrefix to be full URL`, () => { diff --git a/packages/gatsby/src/joi-schemas/joi.js b/packages/gatsby/src/joi-schemas/joi.js index a8198d74cff17..8152135cbde88 100644 --- a/packages/gatsby/src/joi-schemas/joi.js +++ b/packages/gatsby/src/joi-schemas/joi.js @@ -1,6 +1,6 @@ const Joi = require(`joi`) -const stripTrailingSlash = chain => chain.replace(/(\w)\/+/, `$1`) +const stripTrailingSlash = chain => chain.replace(/(\w)\/+$/, `$1`) export const gatsbyConfigSchema = Joi.object().keys({ __experimentalThemes: Joi.array(), From 933f1487fc0c8849cad90bc377f4206872e83fd2 Mon Sep 17 00:00:00 2001 From: Michael <184316+muescha@users.noreply.github.com> Date: Tue, 30 Apr 2019 11:28:13 -0500 Subject: [PATCH 34/60] Update docs/docs/path-prefix.md Co-Authored-By: DSchau --- docs/docs/path-prefix.md | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/docs/docs/path-prefix.md b/docs/docs/path-prefix.md index d2a8edf44bdf6..4c53730db8ed1 100644 --- a/docs/docs/path-prefix.md +++ b/docs/docs/path-prefix.md @@ -56,7 +56,7 @@ function Index() { Without doing _anything_ and merely using the `Link` component, this link will be prefixed with our specified `pathPrefix` in `gatsby-config.js`. Woo hoo! -If we want to do programattic/dynamic navigation, totally possible too! We expose a `navigate` helper, and this too automatically handles path prefixing. +If we want to do programatic/dynamic navigation, totally possible too! We expose a `navigate` helper, and this too automatically handles path prefixing. ```jsx:title=src/pages/index.js import React from "react" From dff0e725036df9fee6aca122b03d541b1fe05b55 Mon Sep 17 00:00:00 2001 From: Dustin Schau Date: Tue, 30 Apr 2019 12:21:14 -0500 Subject: [PATCH 35/60] chore: fix up merge conflicts/get tests passing --- packages/gatsby-link/src/__tests__/index.js | 29 ++++++++++++++++++- packages/gatsby-link/src/index.js | 2 +- .../src/__tests__/gatsby-ssr.js | 3 +- .../src/__tests__/gatsby-ssr.js | 5 ---- .../gatsby-plugin-manifest/src/gatsby-ssr.js | 4 +-- packages/gatsby/src/commands/serve.js | 3 ++ 6 files changed, 36 insertions(+), 10 deletions(-) diff --git a/packages/gatsby-link/src/__tests__/index.js b/packages/gatsby-link/src/__tests__/index.js index 96dbcaaa5472a..88793411025da 100644 --- a/packages/gatsby-link/src/__tests__/index.js +++ b/packages/gatsby-link/src/__tests__/index.js @@ -6,7 +6,7 @@ import { createHistory, LocationProvider, } from "@reach/router" -import Link, { navigate, push, replace, withPrefix } from "../" +import Link, { navigate, push, replace, withPrefix, withAssetPrefix } from "../" afterEach(() => { global.__BASE_PATH__ = `` @@ -38,6 +38,11 @@ const getWithPrefix = (pathPrefix = ``) => { return withPrefix } +const getWithAssetPrefix = (prefix = ``) => { + global.__PATH_PREFIX__ = prefix + return withAssetPrefix +} + const setup = ({ sourcePath = `/active`, linkProps, pathPrefix = `` } = {}) => { global.__BASE_PATH__ = pathPrefix const source = createMemorySource(sourcePath) @@ -148,6 +153,28 @@ describe(`withPrefix`, () => { }) }) +describe(`withAssetPrefix`, () => { + it(`default prefix does not return "//"`, () => { + const to = `/` + const root = getWithAssetPrefix()(to) + expect(root).toEqual(to) + }) + + it(`respects pathPrefix`, () => { + const to = `/abc/` + const pathPrefix = `/blog` + const root = getWithAssetPrefix(pathPrefix)(to) + expect(root).toEqual(`${pathPrefix}${to}`) + }) + + it(`respects joined assetPrefix + pathPrefix`, () => { + const to = `/itsdatboi/` + const pathPrefix = `https://cdn.example.com/blog` + const root = getWithAssetPrefix(pathPrefix)(to) + expect(root).toEqual(`${pathPrefix}${to}`) + }) +}) + describe(`navigate`, () => { it(`navigates to correct path`, () => { const to = `/some-path` diff --git a/packages/gatsby-link/src/index.js b/packages/gatsby-link/src/index.js index 90392e12e927e..72778718e61fa 100644 --- a/packages/gatsby-link/src/index.js +++ b/packages/gatsby-link/src/index.js @@ -12,7 +12,7 @@ export function withPrefix(path) { } export function withAssetPrefix(path) { - return `${__PATH_PREFIX__}/${path}` + return [__PATH_PREFIX__].concat([path.replace(/^\//, ``)]).join(`/`) } function normalizePath(path) { diff --git a/packages/gatsby-plugin-feed/src/__tests__/gatsby-ssr.js b/packages/gatsby-plugin-feed/src/__tests__/gatsby-ssr.js index 1196b12bcb50d..995baba9eabae 100644 --- a/packages/gatsby-plugin-feed/src/__tests__/gatsby-ssr.js +++ b/packages/gatsby-plugin-feed/src/__tests__/gatsby-ssr.js @@ -4,6 +4,7 @@ describe(`Adds for feed to head`, () => { const prefix = global.__BASE_PATH__ beforeEach(() => { global.__BASE_PATH__ = `` + global.__PATH_PREFIX__ = `` }) afterAll(() => { @@ -54,7 +55,7 @@ describe(`Adds for feed to head`, () => { expect(setHeadComponents).toHaveBeenCalledTimes(1) }) it(`creates Link href with path prefix when __PATH_PREFIX__ sets`, async () => { - global.__BASE_PATH__ = `/hogwarts` + global.__PATH_PREFIX__ = `/hogwarts` const pluginOptions = { feeds: [ diff --git a/packages/gatsby-plugin-manifest/src/__tests__/gatsby-ssr.js b/packages/gatsby-plugin-manifest/src/__tests__/gatsby-ssr.js index bd70795d94429..056c9cad504fc 100644 --- a/packages/gatsby-plugin-manifest/src/__tests__/gatsby-ssr.js +++ b/packages/gatsby-plugin-manifest/src/__tests__/gatsby-ssr.js @@ -15,11 +15,6 @@ const setHeadComponents = args => (headComponents = headComponents.concat(args)) const ssrArgs = { setHeadComponents, - withAssetPrefix: jest.fn(prefix => - [global.__PATH_PREFIX__ || ``, prefix] - .join('/') - .replace(/^\/+/, '/') - ) } describe(`gatsby-plugin-manifest`, () => { diff --git a/packages/gatsby-plugin-manifest/src/gatsby-ssr.js b/packages/gatsby-plugin-manifest/src/gatsby-ssr.js index 13c3c63d02400..02a301ba10967 100644 --- a/packages/gatsby-plugin-manifest/src/gatsby-ssr.js +++ b/packages/gatsby-plugin-manifest/src/gatsby-ssr.js @@ -1,13 +1,13 @@ import React from "react" -import fs from "fs" import { withAssetPrefix } from "gatsby" +import fs from "fs" import createContentDigest from "gatsby/dist/utils/create-content-digest" import { defaultIcons, addDigestToPath } from "./common.js" let iconDigest = null -exports.onRenderBody = ({ setHeadComponents, withAssetPrefix }, pluginOptions) => { +exports.onRenderBody = ({ setHeadComponents }, pluginOptions) => { // We use this to build a final array to pass as the argument to setHeadComponents at the end of onRenderBody. let headComponents = [] diff --git a/packages/gatsby/src/commands/serve.js b/packages/gatsby/src/commands/serve.js index fb220bb9ca9c0..06910500870c6 100644 --- a/packages/gatsby/src/commands/serve.js +++ b/packages/gatsby/src/commands/serve.js @@ -10,7 +10,10 @@ const rl = require(`readline`) const onExit = require(`signal-exit`) const telemetry = require(`gatsby-telemetry`) + const detectPortInUseAndPrompt = require(`../utils/detect-port-in-use-and-prompt`) +const getConfigFile = require(`../bootstrap/get-config-file`) +const preferDefault = require(`../bootstrap/prefer-default`) const rlInterface = rl.createInterface({ input: process.stdin, From 560eb795333fc8c07ea05240c0ca49819e32b0f9 Mon Sep 17 00:00:00 2001 From: Dustin Schau Date: Tue, 30 Apr 2019 12:22:29 -0500 Subject: [PATCH 36/60] chore: tweak version --- docs/docs/asset-prefix.md | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/docs/docs/asset-prefix.md b/docs/docs/asset-prefix.md index 0d5515dc78da6..e4b2d062f8b0f 100644 --- a/docs/docs/asset-prefix.md +++ b/docs/docs/asset-prefix.md @@ -6,7 +6,7 @@ Gatsby produces static content that can be hosted _anywhere_ at scale in a cost- There are scenarios in which it may be advantageous or necessary to deploy _assets_ (where an asset is a non-HTML resource, e.g. JavaScript, CSS, etc.) to a separate domain. This can oftentimes be used to enable functionality like a CDN or a particular hosting strategy that your company may employ where assets need to be separate from the core application. -This `assetPrefix` functionality is available starting in gatsby@2.2.0, so that you can seamlessly use Gatsby with assets hosted from a separate domain. To use this functionality, ensure that your version of `gatsby` specified in `package.json` is at least `2.2.0`. +This `assetPrefix` functionality is available starting in gatsby@2.4.0, so that you can seamlessly use Gatsby with assets hosted from a separate domain. To use this functionality, ensure that your version of `gatsby` specified in `package.json` is at least `2.4.0`. ## Usage From 37293e31f105d2728d59b452ccd14c1392238b55 Mon Sep 17 00:00:00 2001 From: Dustin Schau Date: Tue, 30 Apr 2019 12:32:24 -0500 Subject: [PATCH 37/60] fix(gatsby-plugin-sitemap): work with asset prefix --- .../src/__tests__/gatsby-node.js | 9 ++++++-- .../src/__tests__/internals.js | 22 +++++++++++++++---- .../gatsby-plugin-sitemap/src/gatsby-node.js | 3 ++- .../gatsby-plugin-sitemap/src/internals.js | 5 ++--- 4 files changed, 29 insertions(+), 10 deletions(-) diff --git a/packages/gatsby-plugin-sitemap/src/__tests__/gatsby-node.js b/packages/gatsby-plugin-sitemap/src/__tests__/gatsby-node.js index 4afe8566cfd9b..9b0b01e48b0a7 100644 --- a/packages/gatsby-plugin-sitemap/src/__tests__/gatsby-node.js +++ b/packages/gatsby-plugin-sitemap/src/__tests__/gatsby-node.js @@ -2,10 +2,15 @@ jest.mock(`fs`) const fs = require(`fs`) const path = require(`path`) +const sitemap = require(`sitemap`) + const { onPostBuild } = require(`../gatsby-node`) const internals = require(`../internals`) const pathPrefix = `` -const sitemap = require(`sitemap`) + +beforeEach(() => { + global.__PATH_PREFIX__ = `` +}) describe(`Test plugin sitemap`, async () => { it(`default settings work properly`, async () => { @@ -35,7 +40,7 @@ describe(`Test plugin sitemap`, async () => { }, }, }) - await onPostBuild({ graphql, pathPrefix }, {}) + await onPostBuild({ graphql }, {}) const [filePath, contents] = internals.writeFile.mock.calls[0] expect(filePath).toEqual(path.join(`public`, `sitemap.xml`)) expect(contents).toMatchSnapshot() diff --git a/packages/gatsby-plugin-sitemap/src/__tests__/internals.js b/packages/gatsby-plugin-sitemap/src/__tests__/internals.js index f1a3dd7004062..0119d2955d47b 100644 --- a/packages/gatsby-plugin-sitemap/src/__tests__/internals.js +++ b/packages/gatsby-plugin-sitemap/src/__tests__/internals.js @@ -1,8 +1,13 @@ +const { withAssetPrefix } = require(`gatsby`) const { runQuery, defaultOptions: { serialize }, } = require(`../internals`) +beforeEach(() => { + global.__PATH_PREFIX__ = `` +}) + describe(`results using default settings`, () => { const generateQueryResultsMock = ( { siteUrl } = { siteUrl: `http://dummy.url` } @@ -37,9 +42,13 @@ describe(`results using default settings`, () => { } const runTests = (pathPrefix = ``) => { + beforeEach(() => { + global.__PATH_PREFIX__ = pathPrefix + }) + it(`prepares all urls correctly`, async () => { const graphql = () => Promise.resolve(generateQueryResultsMock()) - const queryRecords = await runQuery(graphql, ``, [], pathPrefix) + const queryRecords = await runQuery(graphql, ``, [], withAssetPrefix) const urls = serialize(queryRecords) verifyUrlsExistInResults(urls, [ @@ -53,7 +62,7 @@ describe(`results using default settings`, () => { Promise.resolve( generateQueryResultsMock({ siteUrl: `http://dummy.url/` }) ) - const queryRecords = await runQuery(graphql, ``, [], pathPrefix) + const queryRecords = await runQuery(graphql, ``, [], withAssetPrefix) const urls = serialize(queryRecords) verifyUrlsExistInResults(urls, [ @@ -64,7 +73,12 @@ describe(`results using default settings`, () => { it(`excludes pages`, async () => { const graphql = () => Promise.resolve(generateQueryResultsMock()) - const queryRecords = await runQuery(graphql, ``, [`/page-2`], pathPrefix) + const queryRecords = await runQuery( + graphql, + ``, + [`/page-2`], + withAssetPrefix + ) const urls = serialize(queryRecords) verifyUrlsExistInResults(urls, [`http://dummy.url${pathPrefix}/page-1`]) @@ -76,7 +90,7 @@ describe(`results using default settings`, () => { expect.assertions(1) try { - await runQuery(graphql, ``, [], pathPrefix) + await runQuery(graphql, ``, [], withAssetPrefix) } catch (err) { expect(err.message).toEqual( expect.stringContaining(`SiteMetaData 'siteUrl' property is required`) diff --git a/packages/gatsby-plugin-sitemap/src/gatsby-node.js b/packages/gatsby-plugin-sitemap/src/gatsby-node.js index 9cdc218bb4a8d..a1b880a8e146f 100644 --- a/packages/gatsby-plugin-sitemap/src/gatsby-node.js +++ b/packages/gatsby-plugin-sitemap/src/gatsby-node.js @@ -1,4 +1,5 @@ import path from "path" +import { withAssetPrefix } from "gatsby" import sitemap from "sitemap" import { defaultOptions, @@ -29,7 +30,7 @@ exports.onPostBuild = async ({ graphql, pathPrefix }, pluginOptions) => { graphql, query, excludeOptions, - pathPrefix + withAssetPrefix ) const urls = serialize(queryRecords) diff --git a/packages/gatsby-plugin-sitemap/src/internals.js b/packages/gatsby-plugin-sitemap/src/internals.js index 72b9b75ed336c..56a46f83eeb5f 100644 --- a/packages/gatsby-plugin-sitemap/src/internals.js +++ b/packages/gatsby-plugin-sitemap/src/internals.js @@ -8,7 +8,7 @@ export const withoutTrailingSlash = path => export const writeFile = pify(fs.writeFile) export const renameFile = pify(fs.rename) -export const runQuery = (handler, query, excludes, pathPrefix) => +export const runQuery = (handler, query, excludes, withAssetPrefix) => handler(query).then(r => { if (r.errors) { throw new Error(r.errors.join(`, `)) @@ -24,8 +24,7 @@ export const runQuery = (handler, query, excludes, pathPrefix) => // Add path prefix r.data.allSitePage.edges = r.data.allSitePage.edges.map(page => { - // uses `normalizePath` logic from `gatsby-link` - page.node.path = (pathPrefix + page.node.path).replace(/^\/\//g, `/`) + page.node.path = withAssetPrefix(page.node.path) return page }) From 45ec7c867633c73502510438d4dcdb395244cf91 Mon Sep 17 00:00:00 2001 From: Dustin Schau Date: Tue, 30 Apr 2019 14:59:19 -0500 Subject: [PATCH 38/60] fix(gatsby): disallow both relative assetPrefix and pathPrefix --- .../__tests__/__snapshots__/joi.js.snap | 2 + .../gatsby/src/joi-schemas/__tests__/joi.js | 13 +++- packages/gatsby/src/joi-schemas/joi.js | 77 +++++++++++++------ 3 files changed, 66 insertions(+), 26 deletions(-) diff --git a/packages/gatsby/src/joi-schemas/__tests__/__snapshots__/joi.js.snap b/packages/gatsby/src/joi-schemas/__tests__/__snapshots__/joi.js.snap index b862e99ec74ed..1be4b6fb32fbe 100644 --- a/packages/gatsby/src/joi-schemas/__tests__/__snapshots__/joi.js.snap +++ b/packages/gatsby/src/joi-schemas/__tests__/__snapshots__/joi.js.snap @@ -1,3 +1,5 @@ // Jest Snapshot v1, https://goo.gl/fbAQLP exports[`gatsby config does not allow pathPrefix to be full URL 1`] = `"child \\"pathPrefix\\" fails because [\\"pathPrefix\\" must be a valid relative uri]"`; + +exports[`gatsby config throws when relative path used for both assetPrefix and pathPrefix 1`] = `"assetPrefix must be an absolute URI when used with pathPrefix"`; diff --git a/packages/gatsby/src/joi-schemas/__tests__/joi.js b/packages/gatsby/src/joi-schemas/__tests__/joi.js index 3e00d0e1fad1b..630276791cea5 100644 --- a/packages/gatsby/src/joi-schemas/__tests__/joi.js +++ b/packages/gatsby/src/joi-schemas/__tests__/joi.js @@ -32,7 +32,7 @@ describe(`gatsby config`, () => { it(`allows relative paths for url fields`, () => { const config = { pathPrefix: `/blog`, - assetPrefix: `/assets`, + assetPrefix: `https://cdn.example.com`, } expect(gatsbyConfigSchema.validate(config)).resolves.toEqual(config) @@ -47,4 +47,15 @@ describe(`gatsby config`, () => { gatsbyConfigSchema.validate(config) ).rejects.toThrowErrorMatchingSnapshot() }) + + it(`throws when relative path used for both assetPrefix and pathPrefix`, () => { + const config = { + assetPrefix: `/assets`, + pathPrefix: `/blog`, + } + + expect( + gatsbyConfigSchema.validate(config) + ).rejects.toThrowErrorMatchingSnapshot() + }) }) diff --git a/packages/gatsby/src/joi-schemas/joi.js b/packages/gatsby/src/joi-schemas/joi.js index 6a8eb1ef7a9f8..d7e832e89a0d6 100644 --- a/packages/gatsby/src/joi-schemas/joi.js +++ b/packages/gatsby/src/joi-schemas/joi.js @@ -2,31 +2,58 @@ const Joi = require(`joi`) const stripTrailingSlash = chain => chain.replace(/(\w)\/+$/, `$1`) -export const gatsbyConfigSchema = Joi.object().keys({ - __experimentalThemes: Joi.array(), - polyfill: Joi.boolean(), - assetPrefix: stripTrailingSlash( - Joi.string().uri({ - allowRelative: true, - }) - ), - pathPrefix: stripTrailingSlash( - Joi.string().uri({ - allowRelative: true, - relativeOnly: true, - }) - ), - siteMetadata: Joi.object({ - siteUrl: stripTrailingSlash(Joi.string()).uri(), - }).unknown(), - mapping: Joi.object(), - plugins: Joi.array(), - proxy: Joi.object().keys({ - prefix: Joi.string().required(), - url: Joi.string().required(), - }), - developMiddleware: Joi.func(), -}) +export const gatsbyConfigSchema = Joi.object() + .keys({ + __experimentalThemes: Joi.array(), + polyfill: Joi.boolean(), + assetPrefix: stripTrailingSlash( + Joi.string().uri({ + allowRelative: true, + }) + ), + pathPrefix: stripTrailingSlash( + Joi.string().uri({ + allowRelative: true, + relativeOnly: true, + }) + ), + siteMetadata: Joi.object({ + siteUrl: stripTrailingSlash(Joi.string()).uri(), + }).unknown(), + mapping: Joi.object(), + plugins: Joi.array(), + proxy: Joi.object().keys({ + prefix: Joi.string().required(), + url: Joi.string().required(), + }), + developMiddleware: Joi.func(), + }) + // throws when both assetPrefix and pathPrefix are defined + .when( + Joi.object({ + assetPrefix: Joi.string().uri({ + allowRelative: true, + relativeOnly: true, + }), + pathPrefix: Joi.string().uri({ + allowRelative: true, + relativeOnly: true, + }), + }), + { + then: Joi.object({ + assetPrefix: Joi.string() + .uri({ + allowRelative: false, + }) + .error( + new Error( + `assetPrefix must be an absolute URI when used with pathPrefix` + ) + ), + }), + } + ) export const pageSchema = Joi.object() .keys({ From b0fef6eb33ceb50a13fa5fdad50a08fce8dad858 Mon Sep 17 00:00:00 2001 From: Dustin Schau Date: Tue, 30 Apr 2019 15:05:54 -0500 Subject: [PATCH 39/60] chore: fallback to withPathPrefix, bump peerDep --- packages/gatsby-plugin-feed/package.json | 2 +- packages/gatsby-plugin-feed/src/gatsby-ssr.js | 7 ++++++- packages/gatsby-plugin-manifest/package.json | 2 +- packages/gatsby-plugin-manifest/src/gatsby-ssr.js | 7 ++++++- packages/gatsby-plugin-sitemap/package.json | 2 +- packages/gatsby-plugin-sitemap/src/gatsby-ssr.js | 7 ++++++- 6 files changed, 21 insertions(+), 6 deletions(-) diff --git a/packages/gatsby-plugin-feed/package.json b/packages/gatsby-plugin-feed/package.json index 9e5b4cb9f96f7..0d55ba2bab876 100644 --- a/packages/gatsby-plugin-feed/package.json +++ b/packages/gatsby-plugin-feed/package.json @@ -29,7 +29,7 @@ "license": "MIT", "main": "index.js", "peerDependencies": { - "gatsby": "^2.0.0" + "gatsby": "^2.4.0" }, "repository": "https://github.com/gatsbyjs/gatsby/tree/master/packages/gatsby-plugin-feed", "scripts": { diff --git a/packages/gatsby-plugin-feed/src/gatsby-ssr.js b/packages/gatsby-plugin-feed/src/gatsby-ssr.js index b869c0c16c3d2..91a90799d9582 100644 --- a/packages/gatsby-plugin-feed/src/gatsby-ssr.js +++ b/packages/gatsby-plugin-feed/src/gatsby-ssr.js @@ -1,7 +1,12 @@ import React from "react" -import { withAssetPrefix } from "gatsby" +import { withPathPrefix, withAssetPrefix } from "gatsby" import { defaultOptions } from "./internals" +// TODO: remove for v3 +if (!withAssetPrefix) { + withAssetPrefix = withPathPrefix +} + exports.onRenderBody = ({ setHeadComponents }, pluginOptions) => { const { feeds } = { ...defaultOptions, diff --git a/packages/gatsby-plugin-manifest/package.json b/packages/gatsby-plugin-manifest/package.json index afe3e714e7512..9711bf2a5d5bc 100644 --- a/packages/gatsby-plugin-manifest/package.json +++ b/packages/gatsby-plugin-manifest/package.json @@ -29,7 +29,7 @@ "license": "MIT", "main": "index.js", "peerDependencies": { - "gatsby": "^2.0.15" + "gatsby": "^2.4.0" }, "repository": "https://github.com/gatsbyjs/gatsby/tree/master/packages/gatsby-plugin-manifest", "scripts": { diff --git a/packages/gatsby-plugin-manifest/src/gatsby-ssr.js b/packages/gatsby-plugin-manifest/src/gatsby-ssr.js index 02a301ba10967..3e120ce8e2775 100644 --- a/packages/gatsby-plugin-manifest/src/gatsby-ssr.js +++ b/packages/gatsby-plugin-manifest/src/gatsby-ssr.js @@ -1,10 +1,15 @@ import React from "react" -import { withAssetPrefix } from "gatsby" +import { withPathPrefix, withAssetPrefix } from "gatsby" import fs from "fs" import createContentDigest from "gatsby/dist/utils/create-content-digest" import { defaultIcons, addDigestToPath } from "./common.js" +// TODO: remove for v3 +if (!withAssetPrefix) { + withAssetPrefix = withPathPrefix +} + let iconDigest = null exports.onRenderBody = ({ setHeadComponents }, pluginOptions) => { diff --git a/packages/gatsby-plugin-sitemap/package.json b/packages/gatsby-plugin-sitemap/package.json index 3766fe5250d4f..2afa3ca9222e4 100644 --- a/packages/gatsby-plugin-sitemap/package.json +++ b/packages/gatsby-plugin-sitemap/package.json @@ -26,7 +26,7 @@ "license": "MIT", "main": "index.js", "peerDependencies": { - "gatsby": "^2.0.0" + "gatsby": "^2.4.0" }, "repository": "https://github.com/gatsbyjs/gatsby/tree/master/packages/gatsby-plugin-sitemap", "scripts": { diff --git a/packages/gatsby-plugin-sitemap/src/gatsby-ssr.js b/packages/gatsby-plugin-sitemap/src/gatsby-ssr.js index dcee32db51f9a..27cf9283b3986 100644 --- a/packages/gatsby-plugin-sitemap/src/gatsby-ssr.js +++ b/packages/gatsby-plugin-sitemap/src/gatsby-ssr.js @@ -1,7 +1,12 @@ import React from "react" -import { withAssetPrefix } from "gatsby" +import { withPathPrefix, withAssetPrefix } from "gatsby" import { defaultOptions } from "./internals" +// TODO: remove for v3 +if (!withAssetPrefix) { + withAssetPrefix = withPathPrefix +} + exports.onRenderBody = ({ setHeadComponents }, pluginOptions) => { let { output, createLinkInHead } = { ...defaultOptions, ...pluginOptions } From 0eb6c85caeae9db734327aea9ee315f7932f660c Mon Sep 17 00:00:00 2001 From: Dustin Schau Date: Tue, 30 Apr 2019 15:14:17 -0500 Subject: [PATCH 40/60] chore: remove caveat re: trailing slash --- .../2019-02-08-government-open-data-site-with-gatsby/index.md | 3 +-- docs/docs/gatsby-config.md | 1 - 2 files changed, 1 insertion(+), 3 deletions(-) diff --git a/docs/blog/2019-02-08-government-open-data-site-with-gatsby/index.md b/docs/blog/2019-02-08-government-open-data-site-with-gatsby/index.md index 0b0ef5316b1b1..72553314dce94 100644 --- a/docs/blog/2019-02-08-government-open-data-site-with-gatsby/index.md +++ b/docs/blog/2019-02-08-government-open-data-site-with-gatsby/index.md @@ -223,8 +223,7 @@ We set a `BASEURL` environment variable in `gatsby-config.js` that resolves the const BASEURL = process.env.BASEURL || "" module.exports = { - // Note: it must *not* have a trailing slash. - // This is currently the realtive path in our Jekyll deployment. This path points to our Gatsby pages. + // This is currently the relative path in our Jekyll deployment. This path points to our Gatsby pages. // This prefix is prepended to load all our related images, code, and pages. pathPrefix: `${BASEURL}/gatsby-public`, } diff --git a/docs/docs/gatsby-config.md b/docs/docs/gatsby-config.md index 22a81b6efb7b3..8aa8ffb0ce5f0 100644 --- a/docs/docs/gatsby-config.md +++ b/docs/docs/gatsby-config.md @@ -63,7 +63,6 @@ It's common for sites to be hosted somewhere other than the root of their domain ```javascript:title=gatsby-config.js module.exports = { - // Note: it must *not* have a trailing slash. pathPrefix: `/blog`, } ``` From f0d9a91f55a782568254587b838ea4d588d3978d Mon Sep 17 00:00:00 2001 From: Dustin Schau Date: Tue, 30 Apr 2019 16:05:58 -0500 Subject: [PATCH 41/60] fix: gatsby-plugin-sitemap regression --- .../src/__tests__/gatsby-node.js | 2 +- .../src/__tests__/internals.js | 14 ++++---------- packages/gatsby-plugin-sitemap/src/gatsby-node.js | 3 +-- packages/gatsby-plugin-sitemap/src/internals.js | 4 ++-- 4 files changed, 8 insertions(+), 15 deletions(-) diff --git a/packages/gatsby-plugin-sitemap/src/__tests__/gatsby-node.js b/packages/gatsby-plugin-sitemap/src/__tests__/gatsby-node.js index 9b0b01e48b0a7..18202c953aea0 100644 --- a/packages/gatsby-plugin-sitemap/src/__tests__/gatsby-node.js +++ b/packages/gatsby-plugin-sitemap/src/__tests__/gatsby-node.js @@ -40,7 +40,7 @@ describe(`Test plugin sitemap`, async () => { }, }, }) - await onPostBuild({ graphql }, {}) + await onPostBuild({ graphql, pathPrefix }, {}) const [filePath, contents] = internals.writeFile.mock.calls[0] expect(filePath).toEqual(path.join(`public`, `sitemap.xml`)) expect(contents).toMatchSnapshot() diff --git a/packages/gatsby-plugin-sitemap/src/__tests__/internals.js b/packages/gatsby-plugin-sitemap/src/__tests__/internals.js index 0119d2955d47b..4db76e15f7d70 100644 --- a/packages/gatsby-plugin-sitemap/src/__tests__/internals.js +++ b/packages/gatsby-plugin-sitemap/src/__tests__/internals.js @@ -1,4 +1,3 @@ -const { withAssetPrefix } = require(`gatsby`) const { runQuery, defaultOptions: { serialize }, @@ -48,7 +47,7 @@ describe(`results using default settings`, () => { it(`prepares all urls correctly`, async () => { const graphql = () => Promise.resolve(generateQueryResultsMock()) - const queryRecords = await runQuery(graphql, ``, [], withAssetPrefix) + const queryRecords = await runQuery(graphql, ``, [], pathPrefix) const urls = serialize(queryRecords) verifyUrlsExistInResults(urls, [ @@ -62,7 +61,7 @@ describe(`results using default settings`, () => { Promise.resolve( generateQueryResultsMock({ siteUrl: `http://dummy.url/` }) ) - const queryRecords = await runQuery(graphql, ``, [], withAssetPrefix) + const queryRecords = await runQuery(graphql, ``, [], pathPrefix) const urls = serialize(queryRecords) verifyUrlsExistInResults(urls, [ @@ -73,12 +72,7 @@ describe(`results using default settings`, () => { it(`excludes pages`, async () => { const graphql = () => Promise.resolve(generateQueryResultsMock()) - const queryRecords = await runQuery( - graphql, - ``, - [`/page-2`], - withAssetPrefix - ) + const queryRecords = await runQuery(graphql, ``, [`/page-2`], pathPrefix) const urls = serialize(queryRecords) verifyUrlsExistInResults(urls, [`http://dummy.url${pathPrefix}/page-1`]) @@ -90,7 +84,7 @@ describe(`results using default settings`, () => { expect.assertions(1) try { - await runQuery(graphql, ``, [], withAssetPrefix) + await runQuery(graphql, ``, [], pathPrefix) } catch (err) { expect(err.message).toEqual( expect.stringContaining(`SiteMetaData 'siteUrl' property is required`) diff --git a/packages/gatsby-plugin-sitemap/src/gatsby-node.js b/packages/gatsby-plugin-sitemap/src/gatsby-node.js index a1b880a8e146f..9cdc218bb4a8d 100644 --- a/packages/gatsby-plugin-sitemap/src/gatsby-node.js +++ b/packages/gatsby-plugin-sitemap/src/gatsby-node.js @@ -1,5 +1,4 @@ import path from "path" -import { withAssetPrefix } from "gatsby" import sitemap from "sitemap" import { defaultOptions, @@ -30,7 +29,7 @@ exports.onPostBuild = async ({ graphql, pathPrefix }, pluginOptions) => { graphql, query, excludeOptions, - withAssetPrefix + pathPrefix ) const urls = serialize(queryRecords) diff --git a/packages/gatsby-plugin-sitemap/src/internals.js b/packages/gatsby-plugin-sitemap/src/internals.js index 56a46f83eeb5f..58b8861480c7b 100644 --- a/packages/gatsby-plugin-sitemap/src/internals.js +++ b/packages/gatsby-plugin-sitemap/src/internals.js @@ -8,7 +8,7 @@ export const withoutTrailingSlash = path => export const writeFile = pify(fs.writeFile) export const renameFile = pify(fs.rename) -export const runQuery = (handler, query, excludes, withAssetPrefix) => +export const runQuery = (handler, query, excludes, pathPrefix) => handler(query).then(r => { if (r.errors) { throw new Error(r.errors.join(`, `)) @@ -24,7 +24,7 @@ export const runQuery = (handler, query, excludes, withAssetPrefix) => // Add path prefix r.data.allSitePage.edges = r.data.allSitePage.edges.map(page => { - page.node.path = withAssetPrefix(page.node.path) + page.node.path = (pathPrefix + page.node.path).replace(/^\/\//g, `/`) return page }) From 0603c3137c411db8c7f43d13e411e2e4323aec08 Mon Sep 17 00:00:00 2001 From: Dustin Schau Date: Tue, 30 Apr 2019 16:12:45 -0500 Subject: [PATCH 42/60] chore: revert peer dep --- packages/gatsby-plugin-sitemap/package.json | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/packages/gatsby-plugin-sitemap/package.json b/packages/gatsby-plugin-sitemap/package.json index 2afa3ca9222e4..3766fe5250d4f 100644 --- a/packages/gatsby-plugin-sitemap/package.json +++ b/packages/gatsby-plugin-sitemap/package.json @@ -26,7 +26,7 @@ "license": "MIT", "main": "index.js", "peerDependencies": { - "gatsby": "^2.4.0" + "gatsby": "^2.0.0" }, "repository": "https://github.com/gatsbyjs/gatsby/tree/master/packages/gatsby-plugin-sitemap", "scripts": { From b22da6e906ba0f2c905ec72b089087899bdfa9d3 Mon Sep 17 00:00:00 2001 From: Dustin Schau Date: Tue, 30 Apr 2019 16:31:50 -0500 Subject: [PATCH 43/60] chore: use basePath if it's defined --- packages/gatsby-plugin-sitemap/src/gatsby-node.js | 12 +++++------- packages/gatsby/src/utils/api-runner-node.js | 1 + 2 files changed, 6 insertions(+), 7 deletions(-) diff --git a/packages/gatsby-plugin-sitemap/src/gatsby-node.js b/packages/gatsby-plugin-sitemap/src/gatsby-node.js index 9cdc218bb4a8d..a68064eb67ac1 100644 --- a/packages/gatsby-plugin-sitemap/src/gatsby-node.js +++ b/packages/gatsby-plugin-sitemap/src/gatsby-node.js @@ -10,7 +10,10 @@ import { const publicPath = `./public` -exports.onPostBuild = async ({ graphql, pathPrefix }, pluginOptions) => { +exports.onPostBuild = async ( + { graphql, pathPrefix, basePath = pathPrefix }, + pluginOptions +) => { const options = { ...pluginOptions } delete options.plugins delete options.createLinkInHead @@ -25,12 +28,7 @@ exports.onPostBuild = async ({ graphql, pathPrefix }, pluginOptions) => { // Paths we're excluding... const excludeOptions = exclude.concat(defaultOptions.exclude) - const queryRecords = await runQuery( - graphql, - query, - excludeOptions, - pathPrefix - ) + const queryRecords = await runQuery(graphql, query, excludeOptions, basePath) const urls = serialize(queryRecords) if (!rest.sitemapSize || urls.length <= rest.sitemapSize) { diff --git a/packages/gatsby/src/utils/api-runner-node.js b/packages/gatsby/src/utils/api-runner-node.js index eeee7122aabb1..be09da5db6a3c 100644 --- a/packages/gatsby/src/utils/api-runner-node.js +++ b/packages/gatsby/src/utils/api-runner-node.js @@ -152,6 +152,7 @@ const runAPI = (plugin, api, args) => { const apiCallArgs = [ { ...args, + basePath: config.pathPrefix || ``, pathPrefix: publicPath, boundActionCreators: actions, actions, From 272551a5677482ef756cd7718730c9196d90630e Mon Sep 17 00:00:00 2001 From: Dustin Schau Date: Tue, 30 Apr 2019 16:42:03 -0500 Subject: [PATCH 44/60] chore: remove eslint global comment --- packages/gatsby-link/src/index.js | 1 - 1 file changed, 1 deletion(-) diff --git a/packages/gatsby-link/src/index.js b/packages/gatsby-link/src/index.js index 72778718e61fa..c27af7a39a9e2 100644 --- a/packages/gatsby-link/src/index.js +++ b/packages/gatsby-link/src/index.js @@ -1,4 +1,3 @@ -/*global __BASE_PATH__ */ import PropTypes from "prop-types" import React from "react" import { Link } from "@reach/router" From c3a1230dab7d820e958d4d201c3bbfc8b6133bc1 Mon Sep 17 00:00:00 2001 From: Dustin Schau Date: Tue, 30 Apr 2019 16:46:18 -0500 Subject: [PATCH 45/60] chore: ensure prefixPaths is set to enable pathPrefix --- packages/gatsby/src/utils/api-runner-node.js | 3 ++- 1 file changed, 2 insertions(+), 1 deletion(-) diff --git a/packages/gatsby/src/utils/api-runner-node.js b/packages/gatsby/src/utils/api-runner-node.js index be09da5db6a3c..527ff7b28716a 100644 --- a/packages/gatsby/src/utils/api-runner-node.js +++ b/packages/gatsby/src/utils/api-runner-node.js @@ -95,6 +95,7 @@ const runAPI = (plugin, api, args) => { const { config, program } = store.getState() + const pathPrefix = (program.prefixPaths && config.pathPrefix) || `` const publicPath = getPublicPath({ ...config, ...program }, ``) const namespacedCreateNodeId = id => createNodeId(id, plugin.name) @@ -152,7 +153,7 @@ const runAPI = (plugin, api, args) => { const apiCallArgs = [ { ...args, - basePath: config.pathPrefix || ``, + basePath: pathPrefix, pathPrefix: publicPath, boundActionCreators: actions, actions, From b88c2f8788e97a6584af9748ddedc9c1937a8a93 Mon Sep 17 00:00:00 2001 From: Dustin Schau Date: Tue, 30 Apr 2019 16:50:43 -0500 Subject: [PATCH 46/60] chore: fix read-only error (can't reassign imports ya dingus) --- packages/gatsby-plugin-feed/src/gatsby-ssr.js | 7 ++++--- packages/gatsby-plugin-manifest/src/gatsby-ssr.js | 13 ++++++------- packages/gatsby-plugin-sitemap/src/gatsby-ssr.js | 7 ++++--- 3 files changed, 14 insertions(+), 13 deletions(-) diff --git a/packages/gatsby-plugin-feed/src/gatsby-ssr.js b/packages/gatsby-plugin-feed/src/gatsby-ssr.js index 91a90799d9582..553099d909bfe 100644 --- a/packages/gatsby-plugin-feed/src/gatsby-ssr.js +++ b/packages/gatsby-plugin-feed/src/gatsby-ssr.js @@ -3,8 +3,9 @@ import { withPathPrefix, withAssetPrefix } from "gatsby" import { defaultOptions } from "./internals" // TODO: remove for v3 -if (!withAssetPrefix) { - withAssetPrefix = withPathPrefix +let withPrefix = withAssetPrefix +if (!withPrefix) { + withPrefix = withPathPrefix } exports.onRenderBody = ({ setHeadComponents }, pluginOptions) => { @@ -24,7 +25,7 @@ exports.onRenderBody = ({ setHeadComponents }, pluginOptions) => { rel="alternate" type="application/rss+xml" title={title} - href={withAssetPrefix(output)} + href={withPrefix(output)} /> ) }) diff --git a/packages/gatsby-plugin-manifest/src/gatsby-ssr.js b/packages/gatsby-plugin-manifest/src/gatsby-ssr.js index 3e120ce8e2775..1b2cf4b2aa4de 100644 --- a/packages/gatsby-plugin-manifest/src/gatsby-ssr.js +++ b/packages/gatsby-plugin-manifest/src/gatsby-ssr.js @@ -6,8 +6,9 @@ import createContentDigest from "gatsby/dist/utils/create-content-digest" import { defaultIcons, addDigestToPath } from "./common.js" // TODO: remove for v3 -if (!withAssetPrefix) { - withAssetPrefix = withPathPrefix +let withPrefix = withAssetPrefix +if (!withPrefix) { + withPrefix = withPathPrefix } let iconDigest = null @@ -45,9 +46,7 @@ exports.onRenderBody = ({ setHeadComponents }, pluginOptions) => { ) } @@ -58,7 +57,7 @@ exports.onRenderBody = ({ setHeadComponents }, pluginOptions) => { ) @@ -87,7 +86,7 @@ exports.onRenderBody = ({ setHeadComponents }, pluginOptions) => { key={`gatsby-plugin-manifest-apple-touch-icon-${icon.sizes}`} rel="apple-touch-icon" sizes={icon.sizes} - href={withAssetPrefix( + href={withPrefix( addDigestToPath( icon.src, iconDigest, diff --git a/packages/gatsby-plugin-sitemap/src/gatsby-ssr.js b/packages/gatsby-plugin-sitemap/src/gatsby-ssr.js index 27cf9283b3986..b251c009ef7db 100644 --- a/packages/gatsby-plugin-sitemap/src/gatsby-ssr.js +++ b/packages/gatsby-plugin-sitemap/src/gatsby-ssr.js @@ -3,8 +3,9 @@ import { withPathPrefix, withAssetPrefix } from "gatsby" import { defaultOptions } from "./internals" // TODO: remove for v3 -if (!withAssetPrefix) { - withAssetPrefix = withPathPrefix +let withPrefix = withAssetPrefix +if (!withPrefix) { + withPrefix = withPathPrefix } exports.onRenderBody = ({ setHeadComponents }, pluginOptions) => { @@ -23,7 +24,7 @@ exports.onRenderBody = ({ setHeadComponents }, pluginOptions) => { key={`gatsby-plugin-sitemap`} rel="sitemap" type="application/xml" - href={withAssetPrefix(output)} + href={withPrefix(output)} />, ]) } From 5521302fb42edb88a445016aed4445a0c423a56a Mon Sep 17 00:00:00 2001 From: Dustin Schau Date: Tue, 30 Apr 2019 16:54:15 -0500 Subject: [PATCH 47/60] chore: actually fallback --- packages/gatsby-plugin-feed/src/gatsby-ssr.js | 4 ++-- packages/gatsby-plugin-manifest/src/gatsby-ssr.js | 4 ++-- packages/gatsby-plugin-sitemap/src/gatsby-ssr.js | 4 ++-- 3 files changed, 6 insertions(+), 6 deletions(-) diff --git a/packages/gatsby-plugin-feed/src/gatsby-ssr.js b/packages/gatsby-plugin-feed/src/gatsby-ssr.js index 553099d909bfe..e77a3e417da77 100644 --- a/packages/gatsby-plugin-feed/src/gatsby-ssr.js +++ b/packages/gatsby-plugin-feed/src/gatsby-ssr.js @@ -1,11 +1,11 @@ import React from "react" -import { withPathPrefix, withAssetPrefix } from "gatsby" +import { withPrefix as fallbackWithPrefix, withAssetPrefix } from "gatsby" import { defaultOptions } from "./internals" // TODO: remove for v3 let withPrefix = withAssetPrefix if (!withPrefix) { - withPrefix = withPathPrefix + withPrefix = fallbackWithPrefix } exports.onRenderBody = ({ setHeadComponents }, pluginOptions) => { diff --git a/packages/gatsby-plugin-manifest/src/gatsby-ssr.js b/packages/gatsby-plugin-manifest/src/gatsby-ssr.js index 1b2cf4b2aa4de..4f3b85267dfa2 100644 --- a/packages/gatsby-plugin-manifest/src/gatsby-ssr.js +++ b/packages/gatsby-plugin-manifest/src/gatsby-ssr.js @@ -1,5 +1,5 @@ import React from "react" -import { withPathPrefix, withAssetPrefix } from "gatsby" +import { withPrefix as fallbackWithPrefix, withAssetPrefix } from "gatsby" import fs from "fs" import createContentDigest from "gatsby/dist/utils/create-content-digest" @@ -8,7 +8,7 @@ import { defaultIcons, addDigestToPath } from "./common.js" // TODO: remove for v3 let withPrefix = withAssetPrefix if (!withPrefix) { - withPrefix = withPathPrefix + withPrefix = fallbackWithPrefix } let iconDigest = null diff --git a/packages/gatsby-plugin-sitemap/src/gatsby-ssr.js b/packages/gatsby-plugin-sitemap/src/gatsby-ssr.js index b251c009ef7db..6bd11f273162f 100644 --- a/packages/gatsby-plugin-sitemap/src/gatsby-ssr.js +++ b/packages/gatsby-plugin-sitemap/src/gatsby-ssr.js @@ -1,11 +1,11 @@ import React from "react" -import { withPathPrefix, withAssetPrefix } from "gatsby" +import { withPrefix as fallbackWithPrefix, withAssetPrefix } from "gatsby" import { defaultOptions } from "./internals" // TODO: remove for v3 let withPrefix = withAssetPrefix if (!withPrefix) { - withPrefix = withPathPrefix + withPrefix = fallbackWithPrefix } exports.onRenderBody = ({ setHeadComponents }, pluginOptions) => { From 08ede0342c8ab81551a97b67c147a0437b0e8aa8 Mon Sep 17 00:00:00 2001 From: Mike Allanson Date: Wed, 1 May 2019 09:31:37 -0500 Subject: [PATCH 48/60] Update docs/docs/asset-prefix.md Co-Authored-By: DSchau --- docs/docs/asset-prefix.md | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/docs/docs/asset-prefix.md b/docs/docs/asset-prefix.md index e4b2d062f8b0f..ad3187573cac9 100644 --- a/docs/docs/asset-prefix.md +++ b/docs/docs/asset-prefix.md @@ -68,7 +68,7 @@ In this example, I'll use the `aws-cli` and `s3` to sync the `public` folder (co } ``` -Now whenever the `build` script is invoked, e.g. `npm run build`, the `postbuild` script will be invoked _after_ the build completes, therefore making our assets available on a _separate_ domain after we have finished building out our appliacation with prefixed assets. +Now whenever the `build` script is invoked, e.g. `npm run build`, the `postbuild` script will be invoked _after_ the build completes, therefore making our assets available on a _separate_ domain after we have finished building out our application with prefixed assets. ## Additional Considerations From d28d6f117e2e33bc0c84c4c2e434ea9c209c4f56 Mon Sep 17 00:00:00 2001 From: Michal Piechowiak Date: Wed, 1 May 2019 09:31:51 -0500 Subject: [PATCH 49/60] Update docs/docs/path-prefix.md Co-Authored-By: DSchau --- docs/docs/path-prefix.md | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/docs/docs/path-prefix.md b/docs/docs/path-prefix.md index 4c53730db8ed1..89a2893f43313 100644 --- a/docs/docs/path-prefix.md +++ b/docs/docs/path-prefix.md @@ -35,7 +35,7 @@ If this flag is not passed, Gatsby will ignore your `pathPrefix` and build out y As a developer using this feature, it should be seamless. We provide APIs and libraries to make using this functionality a breeze. Specifically, the [`Link`](/docs/gatsby-link/) component has built-in functionality to handle path prefixing. -For example, if we want to link to our `/page-2` link (but the actual link will be prefixed, e.g. `/blog/page-2`) we don't want to hard code this path prefix in all of our links. We have your back! Merely by using the `Link` component, we will automatically prefix your paths for you. If you later migrate off of `pathPrefix` your links will _still_ work seamlessly. +For example, if we want to link to our `/page-2` link (but the actual link will be prefixed, e.g. `/blog/page-2`) we don't want to hard code this path prefix in all of our links. We have your back! By using the `Link` component, we will automatically prefix your paths for you. If you later migrate off of `pathPrefix` your links will _still_ work seamlessly. Let's look at a quick example. From d277729e795b8142485c27aca7904ae0fb83af9c Mon Sep 17 00:00:00 2001 From: Mike Allanson Date: Wed, 1 May 2019 09:33:21 -0500 Subject: [PATCH 50/60] Update docs/docs/asset-prefix.md Co-Authored-By: DSchau --- docs/docs/asset-prefix.md | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/docs/docs/asset-prefix.md b/docs/docs/asset-prefix.md index ad3187573cac9..f6ad38d2a389a 100644 --- a/docs/docs/asset-prefix.md +++ b/docs/docs/asset-prefix.md @@ -2,7 +2,7 @@ title: Adding an Asset Prefix --- -Gatsby produces static content that can be hosted _anywhere_ at scale in a cost-effective manner. This static content is comprised of HTML files, JavaScript, CSS, images, and more that power your great, Gatsby application. +Gatsby produces static content that can be hosted _anywhere_ at scale in a cost-effective manner. This static content is comprised of HTML files, JavaScript, CSS, images, and more that power your great Gatsby application. There are scenarios in which it may be advantageous or necessary to deploy _assets_ (where an asset is a non-HTML resource, e.g. JavaScript, CSS, etc.) to a separate domain. This can oftentimes be used to enable functionality like a CDN or a particular hosting strategy that your company may employ where assets need to be separate from the core application. From 4d073da728036dd720e5e8e0e36bee20c96927ad Mon Sep 17 00:00:00 2001 From: Dustin Schau Date: Wed, 1 May 2019 09:34:10 -0500 Subject: [PATCH 51/60] chore: simply/merely remove the easy term ;) --- docs/docs/asset-prefix.md | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/docs/docs/asset-prefix.md b/docs/docs/asset-prefix.md index f6ad38d2a389a..39e405c9e9852 100644 --- a/docs/docs/asset-prefix.md +++ b/docs/docs/asset-prefix.md @@ -18,7 +18,7 @@ module.exports = { } ``` -That was easy! One more step - when we build out this application, we need to add a flag so that Gatsby picks up this option. +One more step - when we build out this application, we need to add a flag so that Gatsby picks up this option. ### The `--prefix-paths` flag From b1241c2fe44450ebf971485906c29f67ab1d67b7 Mon Sep 17 00:00:00 2001 From: Mike Allanson Date: Wed, 1 May 2019 09:36:04 -0500 Subject: [PATCH 52/60] Update docs/docs/asset-prefix.md Co-Authored-By: DSchau --- docs/docs/asset-prefix.md | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/docs/docs/asset-prefix.md b/docs/docs/asset-prefix.md index 39e405c9e9852..798ac773af26f 100644 --- a/docs/docs/asset-prefix.md +++ b/docs/docs/asset-prefix.md @@ -4,7 +4,7 @@ title: Adding an Asset Prefix Gatsby produces static content that can be hosted _anywhere_ at scale in a cost-effective manner. This static content is comprised of HTML files, JavaScript, CSS, images, and more that power your great Gatsby application. -There are scenarios in which it may be advantageous or necessary to deploy _assets_ (where an asset is a non-HTML resource, e.g. JavaScript, CSS, etc.) to a separate domain. This can oftentimes be used to enable functionality like a CDN or a particular hosting strategy that your company may employ where assets need to be separate from the core application. +In some circumstances you may want to deploy _assets_ (non-HTML resources such as JavaScript, CSS, etc.) to a separate domain. Typically this is when you're required to use a dedicated CDN for assets or need to follow company-specific hosting policies. This `assetPrefix` functionality is available starting in gatsby@2.4.0, so that you can seamlessly use Gatsby with assets hosted from a separate domain. To use this functionality, ensure that your version of `gatsby` specified in `package.json` is at least `2.4.0`. From a84aeb90097e7faa9189fdee58d5c38a4d4babd0 Mon Sep 17 00:00:00 2001 From: Dustin Schau Date: Wed, 1 May 2019 12:53:29 -0500 Subject: [PATCH 53/60] test: write e2e test for asset prefix Note: this very well may fail --- e2e-tests/path-prefix/.gitignore | 3 +- .../cypress/integration/asset-prefix.js | 52 +++++++++++++++++++ .../cypress/integration/path-prefix.js | 6 +-- .../path-prefix/cypress/plugins/index.js | 17 ++++++ e2e-tests/path-prefix/gatsby-config.js | 44 ++++++++++++++++ e2e-tests/path-prefix/package.json | 18 ++++--- e2e-tests/path-prefix/scripts/serve.js | 28 ++++++++++ 7 files changed, 158 insertions(+), 10 deletions(-) create mode 100644 e2e-tests/path-prefix/cypress/integration/asset-prefix.js create mode 100644 e2e-tests/path-prefix/cypress/plugins/index.js create mode 100644 e2e-tests/path-prefix/scripts/serve.js diff --git a/e2e-tests/path-prefix/.gitignore b/e2e-tests/path-prefix/.gitignore index 615f726febf63..3d1c1613bdf9d 100644 --- a/e2e-tests/path-prefix/.gitignore +++ b/e2e-tests/path-prefix/.gitignore @@ -3,9 +3,10 @@ node_modules yarn-error.log -# Build directory +# Build assets /public .DS_Store +/assets # Cypress output cypress/videos/ diff --git a/e2e-tests/path-prefix/cypress/integration/asset-prefix.js b/e2e-tests/path-prefix/cypress/integration/asset-prefix.js new file mode 100644 index 0000000000000..5272e165a47d7 --- /dev/null +++ b/e2e-tests/path-prefix/cypress/integration/asset-prefix.js @@ -0,0 +1,52 @@ +const { assetPrefix } = require(`../../gatsby-config`) + +const assetPrefixExpression = new RegExp(`^${assetPrefix}`) + +const assetPrefixMatcher = (chain, attr = `href`) => + chain.should(`have.attr`, attr).and(`matches`, assetPrefixExpression) + +describe(`assetPrefix`, () => { + beforeEach(() => { + cy.visit(`/`).waitForRouteChange() + }) + + describe(`runtime`, () => { + it(`prefixes preloads`, () => { + assetPrefixMatcher(cy.get(`head link[rel="preload"]`)) + }) + + it(`prefixes styles`, () => { + assetPrefixMatcher(cy.get(`head style[data-href]`), `data-href`) + }) + + it(`prefixes scripts`, () => { + assetPrefixMatcher(cy.get(`body script[src]`), `src`) + }) + }) + + describe(`gatsby-plugin-manifest`, () => { + it(`prefixes manifest`, () => { + assetPrefixMatcher(cy.get(`head link[rel="manifest"]`)) + }) + + it(`prefixes shortcut icon`, () => { + assetPrefixMatcher(cy.get(`head link[rel="shortcut icon"]`)) + }) + + it(`prefixes manifest icons`, () => { + assetPrefixMatcher(cy.get(`head link[rel="apple-touch-icon"]`)) + }) + }) + + describe(`gatsby-plugin-sitemap`, () => { + it(`prefixes sitemap`, () => { + assetPrefixMatcher(cy.get(`head link[rel="sitemap"]`)) + }) + }) + + describe(`gatsby-plugin-feed`, () => { + it(`prefixes RSS feed`, () => { + assetPrefixMatcher(cy.get(`head link[type="application/rss+xml"]`)) + }) + }) +}) diff --git a/e2e-tests/path-prefix/cypress/integration/path-prefix.js b/e2e-tests/path-prefix/cypress/integration/path-prefix.js index 4dfefc60d398d..ba8f710bc245c 100644 --- a/e2e-tests/path-prefix/cypress/integration/path-prefix.js +++ b/e2e-tests/path-prefix/cypress/integration/path-prefix.js @@ -35,12 +35,12 @@ describe(`Production pathPrefix`, () => { cy.location(`pathname`).should(`eq`, withTrailingSlash(pathPrefix)) }) - it(`can go back`, () => { + it.only(`can go back`, () => { cy.getTestElement(`page-2-link`) .click() .waitForRouteChange() - - cy.go(`back`).waitForRouteChange() + .go(`back`) + .waitForRouteChange() cy.location(`pathname`).should(`eq`, withTrailingSlash(pathPrefix)) }) diff --git a/e2e-tests/path-prefix/cypress/plugins/index.js b/e2e-tests/path-prefix/cypress/plugins/index.js new file mode 100644 index 0000000000000..fd170fba6912b --- /dev/null +++ b/e2e-tests/path-prefix/cypress/plugins/index.js @@ -0,0 +1,17 @@ +// *********************************************************** +// This example plugins/index.js can be used to load plugins +// +// You can change the location of this file or turn off loading +// the plugins file with the 'pluginsFile' configuration option. +// +// You can read more here: +// https://on.cypress.io/plugins-guide +// *********************************************************** + +// This function is called when a project is opened or re-opened (e.g. due to +// the project's config changing) + +module.exports = (on, config) => { + // `on` is used to hook into various events Cypress emits + // `config` is the resolved Cypress config +} diff --git a/e2e-tests/path-prefix/gatsby-config.js b/e2e-tests/path-prefix/gatsby-config.js index e80b503e2601f..d97cbc4d4ee57 100644 --- a/e2e-tests/path-prefix/gatsby-config.js +++ b/e2e-tests/path-prefix/gatsby-config.js @@ -1,6 +1,10 @@ +const pathPrefix = `/blog` + module.exports = { + assetPrefix: `http://localhost:9001`, pathPrefix: `/blog`, siteMetadata: { + siteUrl: `http://localhost:9000`, title: `Gatsby Default Starter`, }, plugins: [ @@ -17,5 +21,45 @@ module.exports = { icon: `src/images/gatsby-icon.png`, // This path is relative to the root of the site. }, }, + `gatsby-plugin-sitemap`, + { + resolve: `gatsby-plugin-feed`, + options: { + query: ` + { + site { + siteMetadata { + siteUrl + site_url: siteUrl + } + } + } + `, + feeds: [ + { + query: ` + { + pages: allSitePage { + nodes { + path + } + } + } + `, + serialize({ query: { site, pages } }) { + return pages.nodes.map(node => { + return { + description: `A sample page hello world suh dude`, + date: `10-08-1990`, + url: `${site.siteMetadata.siteUrl}${pathPrefix}${node.path}`, + } + }) + }, + title: `assetPrefix + pathPrefix RSS Feed`, + output: `rss.xml`, + }, + ], + }, + }, ], } diff --git a/e2e-tests/path-prefix/package.json b/e2e-tests/path-prefix/package.json index e28122afc515c..b0f93b0352ea1 100644 --- a/e2e-tests/path-prefix/package.json +++ b/e2e-tests/path-prefix/package.json @@ -5,10 +5,12 @@ "author": "Kyle Mathews ", "dependencies": { "cypress": "^3.1.0", - "gatsby": "^2.0.118", + "gatsby": "2.3.34-dev-1556723094897", + "gatsby-plugin-feed": "^2.1.2", "gatsby-plugin-manifest": "^2.0.17", "gatsby-plugin-offline": "^2.0.23", "gatsby-plugin-react-helmet": "^3.0.6", + "gatsby-plugin-sitemap": "^2.0.12", "react": "^16.8.0", "react-dom": "^16.8.0", "react-helmet": "^5.2.0" @@ -18,18 +20,22 @@ ], "license": "MIT", "scripts": { - "build": "gatsby build --prefix-paths", + "prebuild": "rm -rf assets && mkdir -p assets/blog", + "build": "CYPRESS_SUPPORT=y gatsby build --prefix-paths", + "postbuild": "cp -r public/. assets/blog", "develop": "gatsby develop", "format": "prettier --write '**/*.js'", "test": "CYPRESS_SUPPORT=y npm run build && npm run start-server-and-test", - "start-server-and-test": "start-server-and-test serve http://localhost:9000/blog cy:run", - "serve": "gatsby serve --prefix-paths", - "cy:open": "cypress open", - "cy:run": "cypress run --browser chrome" + "start-server-and-test": "start-server-and-test serve \"http://localhost:9000/blog/|http://localhost:9001/blog/\" cy:run", + "serve": "gatsby serve --prefix-paths & npm run serve:assets", + "serve:assets": "node scripts/serve.js", + "cy:open": "CYPRESS_SUPPORT=y cypress open", + "cy:run": "CYPRESS_SUPPORT=y cypress run --browser chrome" }, "devDependencies": { "gatsby-cypress": "^0.1.7", "prettier": "^1.14.3", + "serve-handler": "^6.0.0", "start-server-and-test": "^1.7.1" }, "repository": { diff --git a/e2e-tests/path-prefix/scripts/serve.js b/e2e-tests/path-prefix/scripts/serve.js new file mode 100644 index 0000000000000..06b6af1a6982b --- /dev/null +++ b/e2e-tests/path-prefix/scripts/serve.js @@ -0,0 +1,28 @@ +const handler = require(`serve-handler`) +const http = require(`http`) +const path = require(`path`) + +const server = http.createServer((request, response) => + handler(request, response, { + public: path.resolve(`assets`), + headers: [ + { + source: `**/*`, + headers: [ + { + key: `Access-Control-Allow-Origin`, + value: `http://localhost:9000`, + }, + { + key: `Access-Control-Allow-Credentials`, + value: true, + }, + ], + }, + ], + }) +) + +server.listen(9001, () => { + console.log(`Running at http://localhost:9001`) +}) From 78374b28066d52a42d3cbe983e3b8d38cec4f191 Mon Sep 17 00:00:00 2001 From: Dustin Schau Date: Wed, 1 May 2019 13:01:16 -0500 Subject: [PATCH 54/60] chore: fix package json and make isURL test stricter --- e2e-tests/path-prefix/package.json | 6 +++--- packages/gatsby/src/utils/get-public-path.js | 2 +- 2 files changed, 4 insertions(+), 4 deletions(-) diff --git a/e2e-tests/path-prefix/package.json b/e2e-tests/path-prefix/package.json index b0f93b0352ea1..8076a1bbea2d4 100644 --- a/e2e-tests/path-prefix/package.json +++ b/e2e-tests/path-prefix/package.json @@ -21,7 +21,7 @@ "license": "MIT", "scripts": { "prebuild": "rm -rf assets && mkdir -p assets/blog", - "build": "CYPRESS_SUPPORT=y gatsby build --prefix-paths", + "build": "gatsby build --prefix-paths", "postbuild": "cp -r public/. assets/blog", "develop": "gatsby develop", "format": "prettier --write '**/*.js'", @@ -29,8 +29,8 @@ "start-server-and-test": "start-server-and-test serve \"http://localhost:9000/blog/|http://localhost:9001/blog/\" cy:run", "serve": "gatsby serve --prefix-paths & npm run serve:assets", "serve:assets": "node scripts/serve.js", - "cy:open": "CYPRESS_SUPPORT=y cypress open", - "cy:run": "CYPRESS_SUPPORT=y cypress run --browser chrome" + "cy:open": "cypress open", + "cy:run": "cypress run --browser chrome" }, "devDependencies": { "gatsby-cypress": "^0.1.7", diff --git a/packages/gatsby/src/utils/get-public-path.js b/packages/gatsby/src/utils/get-public-path.js index 35adf992d05a6..035e4bc35958f 100644 --- a/packages/gatsby/src/utils/get-public-path.js +++ b/packages/gatsby/src/utils/get-public-path.js @@ -1,7 +1,7 @@ const trimSlashes = part => part.replace(/(^\/)|(\/$)/g, ``) const isURL = possibleUrl => - [`http`, `//`].some(expr => possibleUrl.startsWith(expr)) + [`http://`, `https://`, `//`].some(expr => possibleUrl.startsWith(expr)) module.exports = function getPublicPath({ assetPrefix, From d226f5ed7a9e762ae01039bd882327b0376363d1 Mon Sep 17 00:00:00 2001 From: Dustin Schau Date: Wed, 1 May 2019 14:56:25 -0500 Subject: [PATCH 55/60] chore: fix yarn and stuff hopefully --- e2e-tests/path-prefix/cypress/integration/path-prefix.js | 2 +- e2e-tests/path-prefix/package.json | 2 +- 2 files changed, 2 insertions(+), 2 deletions(-) diff --git a/e2e-tests/path-prefix/cypress/integration/path-prefix.js b/e2e-tests/path-prefix/cypress/integration/path-prefix.js index ba8f710bc245c..00fb257b158da 100644 --- a/e2e-tests/path-prefix/cypress/integration/path-prefix.js +++ b/e2e-tests/path-prefix/cypress/integration/path-prefix.js @@ -35,7 +35,7 @@ describe(`Production pathPrefix`, () => { cy.location(`pathname`).should(`eq`, withTrailingSlash(pathPrefix)) }) - it.only(`can go back`, () => { + it(`can go back`, () => { cy.getTestElement(`page-2-link`) .click() .waitForRouteChange() diff --git a/e2e-tests/path-prefix/package.json b/e2e-tests/path-prefix/package.json index 8076a1bbea2d4..7fa4d414afa7a 100644 --- a/e2e-tests/path-prefix/package.json +++ b/e2e-tests/path-prefix/package.json @@ -5,7 +5,7 @@ "author": "Kyle Mathews ", "dependencies": { "cypress": "^3.1.0", - "gatsby": "2.3.34-dev-1556723094897", + "gatsby": "^2.3.34", "gatsby-plugin-feed": "^2.1.2", "gatsby-plugin-manifest": "^2.0.17", "gatsby-plugin-offline": "^2.0.23", From 983f010b16ec804ff2f2f77abbc10f883e56aff8 Mon Sep 17 00:00:00 2001 From: Dustin Schau Date: Thu, 2 May 2019 12:19:43 -0500 Subject: [PATCH 56/60] chore: minor clean up --- packages/gatsby-plugin-feed/src/gatsby-ssr.js | 5 +---- packages/gatsby-plugin-manifest/src/gatsby-ssr.js | 6 ++---- packages/gatsby-plugin-sitemap/src/gatsby-ssr.js | 5 +---- 3 files changed, 4 insertions(+), 12 deletions(-) diff --git a/packages/gatsby-plugin-feed/src/gatsby-ssr.js b/packages/gatsby-plugin-feed/src/gatsby-ssr.js index e77a3e417da77..b958df1dc6684 100644 --- a/packages/gatsby-plugin-feed/src/gatsby-ssr.js +++ b/packages/gatsby-plugin-feed/src/gatsby-ssr.js @@ -3,10 +3,7 @@ import { withPrefix as fallbackWithPrefix, withAssetPrefix } from "gatsby" import { defaultOptions } from "./internals" // TODO: remove for v3 -let withPrefix = withAssetPrefix -if (!withPrefix) { - withPrefix = fallbackWithPrefix -} +const withPrefix = withAssetPrefix || fallbackWithPrefix exports.onRenderBody = ({ setHeadComponents }, pluginOptions) => { const { feeds } = { diff --git a/packages/gatsby-plugin-manifest/src/gatsby-ssr.js b/packages/gatsby-plugin-manifest/src/gatsby-ssr.js index 4f3b85267dfa2..2a9d3986d7b3a 100644 --- a/packages/gatsby-plugin-manifest/src/gatsby-ssr.js +++ b/packages/gatsby-plugin-manifest/src/gatsby-ssr.js @@ -6,10 +6,8 @@ import createContentDigest from "gatsby/dist/utils/create-content-digest" import { defaultIcons, addDigestToPath } from "./common.js" // TODO: remove for v3 -let withPrefix = withAssetPrefix -if (!withPrefix) { - withPrefix = fallbackWithPrefix -} +// TODO: remove for v3 +const withPrefix = withAssetPrefix || fallbackWithPrefix let iconDigest = null diff --git a/packages/gatsby-plugin-sitemap/src/gatsby-ssr.js b/packages/gatsby-plugin-sitemap/src/gatsby-ssr.js index 6bd11f273162f..e4e5c1b3c0614 100644 --- a/packages/gatsby-plugin-sitemap/src/gatsby-ssr.js +++ b/packages/gatsby-plugin-sitemap/src/gatsby-ssr.js @@ -3,10 +3,7 @@ import { withPrefix as fallbackWithPrefix, withAssetPrefix } from "gatsby" import { defaultOptions } from "./internals" // TODO: remove for v3 -let withPrefix = withAssetPrefix -if (!withPrefix) { - withPrefix = fallbackWithPrefix -} +const withPrefix = withAssetPrefix || fallbackWithPrefix exports.onRenderBody = ({ setHeadComponents }, pluginOptions) => { let { output, createLinkInHead } = { ...defaultOptions, ...pluginOptions } From 60c2408b09d79ea033c450e603a5128b4b177c4d Mon Sep 17 00:00:00 2001 From: Dustin Schau Date: Thu, 2 May 2019 12:37:14 -0500 Subject: [PATCH 57/60] fix(gatsby): fix initial navigation not registering in history --- e2e-tests/path-prefix/package.json | 1 + packages/gatsby/cache-dir/production-app.js | 4 ++-- 2 files changed, 3 insertions(+), 2 deletions(-) diff --git a/e2e-tests/path-prefix/package.json b/e2e-tests/path-prefix/package.json index 7fa4d414afa7a..b07d2976e23b5 100644 --- a/e2e-tests/path-prefix/package.json +++ b/e2e-tests/path-prefix/package.json @@ -11,6 +11,7 @@ "gatsby-plugin-offline": "^2.0.23", "gatsby-plugin-react-helmet": "^3.0.6", "gatsby-plugin-sitemap": "^2.0.12", + "gatsby-transformer-documentationjs": "4.0.0-dev-1556818128358", "react": "^16.8.0", "react-dom": "^16.8.0", "react-helmet": "^5.2.0" diff --git a/packages/gatsby/cache-dir/production-app.js b/packages/gatsby/cache-dir/production-app.js index 6120b0dac8a2d..90d8f871289cc 100644 --- a/packages/gatsby/cache-dir/production-app.js +++ b/packages/gatsby/cache-dir/production-app.js @@ -66,10 +66,10 @@ apiRunnerAsync(`onClientEntry`).then(() => { // Make sure the window.page object is defined page && // The canonical path doesn't match the actual path (i.e. the address bar) - __PATH_PREFIX__ + page.path !== browserLoc.pathname && + __BASE_PATH__ + page.path !== browserLoc.pathname && // ...and if matchPage is specified, it also doesn't match the actual path (!page.matchPath || - !match(__PATH_PREFIX__ + page.matchPath, browserLoc.pathname)) && + !match(__BASE_PATH__ + page.matchPath, browserLoc.pathname)) && // Ignore 404 pages, since we want to keep the same URL page.path !== `/404.html` && !page.path.match(/^\/404\/?$/) && From ae9b34c3e671388013f00f2951291fef6f94a63b Mon Sep 17 00:00:00 2001 From: Dustin Schau Date: Thu, 2 May 2019 12:50:28 -0500 Subject: [PATCH 58/60] chore: remove unneccessary dep --- e2e-tests/path-prefix/package.json | 1 - 1 file changed, 1 deletion(-) diff --git a/e2e-tests/path-prefix/package.json b/e2e-tests/path-prefix/package.json index b07d2976e23b5..7fa4d414afa7a 100644 --- a/e2e-tests/path-prefix/package.json +++ b/e2e-tests/path-prefix/package.json @@ -11,7 +11,6 @@ "gatsby-plugin-offline": "^2.0.23", "gatsby-plugin-react-helmet": "^3.0.6", "gatsby-plugin-sitemap": "^2.0.12", - "gatsby-transformer-documentationjs": "4.0.0-dev-1556818128358", "react": "^16.8.0", "react-dom": "^16.8.0", "react-helmet": "^5.2.0" From 4075e955d1276e1553136189aee94c4dd593c820 Mon Sep 17 00:00:00 2001 From: Dustin Schau Date: Thu, 2 May 2019 13:11:58 -0500 Subject: [PATCH 59/60] fix: use __BASE_PATH__ in development runtime too; add a test --- .../cypress/integration/navigation/linking.js | 10 ++++++++++ packages/gatsby/cache-dir/root.js | 2 +- 2 files changed, 11 insertions(+), 1 deletion(-) diff --git a/e2e-tests/development-runtime/cypress/integration/navigation/linking.js b/e2e-tests/development-runtime/cypress/integration/navigation/linking.js index b2f511ea4a2ee..8cf9c5fb0056d 100644 --- a/e2e-tests/development-runtime/cypress/integration/navigation/linking.js +++ b/e2e-tests/development-runtime/cypress/integration/navigation/linking.js @@ -25,6 +25,16 @@ describe(`navigation`, () => { cy.location(`pathname`).should(`equal`, `/`) }) + it(`can navigate back using history`, () => { + cy.getTestElement(`page-two`) + .click() + .waitForRouteChange() + + cy.go(`back`).waitForRouteChange() + + cy.location(`pathname`).should(`equal`, `/`) + }) + describe(`non-existant route`, () => { beforeEach(() => { cy.getTestElement(`broken-link`) diff --git a/packages/gatsby/cache-dir/root.js b/packages/gatsby/cache-dir/root.js index f6d73b8439d92..c19a134f30bcb 100644 --- a/packages/gatsby/cache-dir/root.js +++ b/packages/gatsby/cache-dir/root.js @@ -87,7 +87,7 @@ const Root = () => createElement( Router, { - basepath: __PATH_PREFIX__, + basepath: __BASE_PATH__, }, createElement(RouteHandler, { path: `/*` }) ) From 2a761db8015f05e28fe5e212646f0287d4442c04 Mon Sep 17 00:00:00 2001 From: Dustin Schau Date: Thu, 2 May 2019 13:46:55 -0500 Subject: [PATCH 60/60] chore: fix @pieh nit before he finds it --- packages/gatsby-plugin-manifest/src/gatsby-ssr.js | 1 - 1 file changed, 1 deletion(-) diff --git a/packages/gatsby-plugin-manifest/src/gatsby-ssr.js b/packages/gatsby-plugin-manifest/src/gatsby-ssr.js index 2a9d3986d7b3a..fb2625893571f 100644 --- a/packages/gatsby-plugin-manifest/src/gatsby-ssr.js +++ b/packages/gatsby-plugin-manifest/src/gatsby-ssr.js @@ -5,7 +5,6 @@ import createContentDigest from "gatsby/dist/utils/create-content-digest" import { defaultIcons, addDigestToPath } from "./common.js" -// TODO: remove for v3 // TODO: remove for v3 const withPrefix = withAssetPrefix || fallbackWithPrefix