diff --git a/docs/docs/building-with-components.md b/docs/docs/building-with-components.md index a0f848b3a2398..7290572fb0248 100644 --- a/docs/docs/building-with-components.md +++ b/docs/docs/building-with-components.md @@ -161,9 +161,10 @@ import React from "react"; import favicon from "./favicon.png"; let inlinedStyles = ""; +const buildDirectory = process.env.GATSBY_BUILD_DIR || `public` if (process.env.NODE_ENV === "production") { try { - inlinedStyles = require("!raw-loader!../public/styles.css"); + inlinedStyles = require(`!raw-loader!../${buildDirectory}/styles.css`); } catch (e) { console.log(e); } diff --git a/examples/client-only-paths/src/html.js b/examples/client-only-paths/src/html.js index 432fc911a9a9b..cc09e9b4490cf 100644 --- a/examples/client-only-paths/src/html.js +++ b/examples/client-only-paths/src/html.js @@ -4,9 +4,10 @@ import { TypographyStyle } from "react-typography" import typography from "./utils/typography" let stylesStr +const buildDirectory = process.env.GATSBY_BUILD_DIR || `public` if (process.env.NODE_ENV === `production`) { try { - stylesStr = require(`!raw-loader!../public/styles.css`) + stylesStr = require(`!raw-loader!../${buildDirectory}/styles.css`) } catch (e) { console.log(e) } diff --git a/examples/using-postcss-sass/src/html.js b/examples/using-postcss-sass/src/html.js index 7188509c8126b..7eaebce5af180 100644 --- a/examples/using-postcss-sass/src/html.js +++ b/examples/using-postcss-sass/src/html.js @@ -6,9 +6,10 @@ import { TypographyStyle } from "react-typography" const typography = new Typography() let stylesStr +const buildDirectory = process.env.GATSBY_BUILD_DIR || `public` if (process.env.NODE_ENV === `production`) { try { - stylesStr = require(`!raw-loader!../public/styles.css`) + stylesStr = require(`!raw-loader!../${buildDirectory}/styles.css`) } catch (e) { console.log(e) } diff --git a/examples/using-remark/src/html.js b/examples/using-remark/src/html.js index 0a5d44d48267d..23aa5d8332682 100644 --- a/examples/using-remark/src/html.js +++ b/examples/using-remark/src/html.js @@ -4,9 +4,10 @@ import { TypographyStyle } from "react-typography" import typography from "./utils/typography" let stylesStr +const buildDirectory = process.env.GATSBY_BUILD_DIR || `public` if (process.env.NODE_ENV === `production`) { try { - stylesStr = require(`!raw-loader!../public/styles.css`) + stylesStr = require(`!raw-loader!../${buildDirectory}/styles.css`) } catch (e) { console.log(e) } diff --git a/examples/using-sass/src/html.js b/examples/using-sass/src/html.js index ddc1dfc0aefa0..9ce7cf3759fea 100644 --- a/examples/using-sass/src/html.js +++ b/examples/using-sass/src/html.js @@ -6,9 +6,10 @@ import { TypographyStyle } from "react-typography" const typography = new Typography() let stylesStr +const buildDirectory = process.env.GATSBY_BUILD_DIR || `public` if (process.env.NODE_ENV === `production`) { try { - stylesStr = require(`!raw-loader!../public/styles.css`) + stylesStr = require(`!raw-loader!../${buildDirectory}/styles.css`) } catch (e) { console.log(e) } diff --git a/examples/using-styled-components/src/html.js b/examples/using-styled-components/src/html.js index 5affc9b4f6904..e3b009ef3381a 100644 --- a/examples/using-styled-components/src/html.js +++ b/examples/using-styled-components/src/html.js @@ -6,7 +6,8 @@ import typography from "./utils/typography" let stylesStr if (process.env.NODE_ENV === `production`) { try { - stylesStr = require(`!raw-loader!../public/styles.css`) + const buildDirectory = process.env.GATSBY_BUILD_DIR || `public` + stylesStr = require(`!raw-loader!../${buildDirectory}/styles.css`) } catch (e) { console.log(e) } diff --git a/examples/using-styletron/src/html.js b/examples/using-styletron/src/html.js index 0b86d80857252..3ede7aa3d438e 100644 --- a/examples/using-styletron/src/html.js +++ b/examples/using-styletron/src/html.js @@ -4,9 +4,10 @@ import { TypographyStyle } from "react-typography" import typography from "./utils/typography" let stylesStr +const buildDirectory = process.env.GATSBY_BUILD_DIR || `public` if (process.env.NODE_ENV === `production`) { try { - stylesStr = require(`!raw-loader!../public/styles.css`) + stylesStr = require(`!raw-loader!../${buildDirectory}/styles.css`) } catch (e) { console.log(e) } diff --git a/examples/using-stylus/src/html.js b/examples/using-stylus/src/html.js index fdaad9c7f9479..d8ab0ffd26e7d 100644 --- a/examples/using-stylus/src/html.js +++ b/examples/using-stylus/src/html.js @@ -6,9 +6,10 @@ import { TypographyStyle } from "react-typography" const typography = new Typography() let stylesStr +const buildDirectory = process.env.GATSBY_BUILD_DIR || `public` if (process.env.NODE_ENV === `production`) { try { - stylesStr = require(`!raw-loader!../public/styles.css`) + stylesStr = require(`!raw-loader!../${buildDirectory}/styles.css`) } catch (e) { console.log(e) } diff --git a/examples/using-typescript/src/html.tsx b/examples/using-typescript/src/html.tsx index 34b85c777777e..0b2402c2ff327 100644 --- a/examples/using-typescript/src/html.tsx +++ b/examples/using-typescript/src/html.tsx @@ -5,9 +5,10 @@ import * as React from "react"; // Load production style let styles: string; +const buildDirectory = process.env.GATSBY_BUILD_DIR || `public` if (process.env.NODE_ENV === `production`) { try { - styles = require("!raw-loader!../public/styles.css"); + styles = require(`!raw-loader!../${buildDirectory}/styles.css`); } catch (err) { console.log(err); } diff --git a/infrastructure/build-site.js b/infrastructure/build-site.js index f0b6ad14968e1..1d3f7d99c7157 100644 --- a/infrastructure/build-site.js +++ b/infrastructure/build-site.js @@ -142,7 +142,8 @@ const Main = async () => { updateBuild(buildId, "FAILURE") process.exit(code) } - const publicDir = `${pathToSite}/public` + const buildDirectory = process.env.GATSBY_BUILD_DIR || `public` + const publicDir = `${pathToSite}/${buildDirectory}` console.log(`uploading files from ${publicDir}`) // 1. Push built files to s3 bucket diff --git a/packages/gatsby-cli/src/create-cli.js b/packages/gatsby-cli/src/create-cli.js index 756276652cd22..257c8ed94159e 100644 --- a/packages/gatsby-cli/src/create-cli.js +++ b/packages/gatsby-cli/src/create-cli.js @@ -115,10 +115,22 @@ function buildLocalCommands(cli, isLocalSite) { type: `string`, default: ``, describe: `Custom HTTPS key file (relative path; also required: --https, --cert-file). See https://www.gatsbyjs.org/docs/local-https/`, + }) + .option(`build-dir`, { + alias: `buildDirectory`, + type: `string`, + default: `public`, + describe: `Set build directory. Defaults to public`, }), handler: handlerP( getCommandHandler(`develop`, (args, cmd) => { process.env.NODE_ENV = process.env.NODE_ENV || `development` + + process.env.GATSBY_BUILD_DIR = process.env.GATSBY_BUILD_DIR || path.resolve(args.buildDirectory) || `public` + if (!fs.existsSync(process.env.GATSBY_BUILD_DIR)) { + fs.mkdirSync(process.env.GATSBY_BUILD_DIR) + } + cmd(args) // Return an empty promise to prevent handlerP from exiting early. // The development server shouldn't ever exit until the user directly @@ -140,10 +152,21 @@ function buildLocalCommands(cli, isLocalSite) { type: `boolean`, default: false, describe: `Build site without uglifying JS bundles (for debugging).`, + }).option(`build-dir`, { + alias: `buildDirectory`, + type: `string`, + default: `public`, + describe: `Set build directory. Defaults to public`, }), handler: handlerP( getCommandHandler(`build`, (args, cmd) => { process.env.NODE_ENV = `production` + + process.env.GATSBY_BUILD_DIR = process.env.GATSBY_BUILD_DIR || path.resolve(args.buildDirectory) || `public` + if (!fs.existsSync(process.env.GATSBY_BUILD_DIR)) { + fs.mkdirSync(process.env.GATSBY_BUILD_DIR) + } + return cmd(args) }) ), diff --git a/packages/gatsby-plugin-feed/src/gatsby-node.js b/packages/gatsby-plugin-feed/src/gatsby-node.js index 6bc0f497e0240..482d84e6fbd2a 100644 --- a/packages/gatsby-plugin-feed/src/gatsby-node.js +++ b/packages/gatsby-plugin-feed/src/gatsby-node.js @@ -3,7 +3,8 @@ import RSS from "rss" import merge from "lodash.merge" import { defaultOptions, runQuery, writeFile } from "./internals" -const publicPath = `./public` +const buildDirectory = process.env.GATSBY_BUILD_DIR || `public` +const publicPath = `./${buildDirectory}` // A default function to transform query data into feed entries. const serialize = ({ query: { site, allMarkdownRemark } }) => diff --git a/packages/gatsby-plugin-manifest/src/gatsby-node.js b/packages/gatsby-plugin-manifest/src/gatsby-node.js index 951e992b4d5e3..cc969373ef0b4 100644 --- a/packages/gatsby-plugin-manifest/src/gatsby-node.js +++ b/packages/gatsby-plugin-manifest/src/gatsby-node.js @@ -3,13 +3,14 @@ const path = require(`path`) const Promise = require(`bluebird`) const sharp = require(`sharp`) const defaultIcons = require(`./common.js`).defaultIcons +const buildDirectory = process.env.GATSBY_BUILD_DIR || `public` sharp.simd(true) function generateIcons(icons, srcIcon) { return Promise.map(icons, icon => { const size = parseInt(icon.sizes.substring(0, icon.sizes.lastIndexOf(`x`))) - const imgPath = path.join(`public`, icon.src) + const imgPath = path.join(buildDirectory, icon.src) return sharp(srcIcon) .resize(size) @@ -34,7 +35,7 @@ exports.onPostBuild = (args, pluginOptions) => // Determine destination path for icons. const iconPath = path.join( - `public`, + buildDirectory, manifest.icons[0].src.substring(0, manifest.icons[0].src.lastIndexOf(`/`)) ) @@ -44,7 +45,7 @@ exports.onPostBuild = (args, pluginOptions) => } fs.writeFileSync( - path.join(`public`, `manifest.webmanifest`), + path.join(buildDirectory, `manifest.webmanifest`), JSON.stringify(manifest) ) diff --git a/packages/gatsby-plugin-netlify/README.md b/packages/gatsby-plugin-netlify/README.md index 4e99b10ec2adf..b54ee1c356d21 100644 --- a/packages/gatsby-plugin-netlify/README.md +++ b/packages/gatsby-plugin-netlify/README.md @@ -76,7 +76,7 @@ An example: Link paths are specially handed by this plugin. Since most files are processed and cache-busted through Gatsby (with a file hash), the plugin will transform any base file names to the hashed variants. If the file is not hashed, it will -ensure the path is valid relative to the output `public` folder. You should be +ensure the path is valid relative to the build `public` folder. You should be able to reference assets imported through javascript in the `static` folder. Do not specify the public path in the config, as the plugin will provide it for diff --git a/packages/gatsby-plugin-netlify/src/plugin-data.js b/packages/gatsby-plugin-netlify/src/plugin-data.js index 92fc471fc7991..083054ee5bfc9 100644 --- a/packages/gatsby-plugin-netlify/src/plugin-data.js +++ b/packages/gatsby-plugin-netlify/src/plugin-data.js @@ -31,7 +31,8 @@ function applyLayouts(pages, layouts) { // hashed filenames and ensure we pull in the componentChunkName and layoutComponentChunkName. export default function makePluginData(store, assetsManifest, pathPrefix) { const { program, layouts, pages: storePages } = store.getState() - const publicFolder = buildPrefixer(program.directory, `public`) + const buildDirectory = process.env.GATSBY_BUILD_DIR || `public` + const publicFolder = buildPrefixer(program.directory, buildDirectory) const stats = require(publicFolder(`stats.json`)) const chunkManifest = normalizeStats(stats) const pages = applyLayouts(storePages, layouts) diff --git a/packages/gatsby-plugin-offline/src/gatsby-node.js b/packages/gatsby-plugin-offline/src/gatsby-node.js index 0ee8d770ac7f1..aee9e7c110db2 100644 --- a/packages/gatsby-plugin-offline/src/gatsby-node.js +++ b/packages/gatsby-plugin-offline/src/gatsby-node.js @@ -14,7 +14,7 @@ exports.createPages = ({ boundActionCreators }) => { } exports.onPostBuild = (args, pluginOptions) => { - const rootDir = `public` + const rootDir = process.env.GATSBY_BUILD_DIR || `public` const options = { staticFileGlobs: [ @@ -28,7 +28,7 @@ exports.onPostBuild = (args, pluginOptions) => { ], stripPrefix: rootDir, // If `pathPrefix` is configured by user, we should replace - // the `public` prefix with `pathPrefix`. + // the build directory (default: `public`) prefix with `pathPrefix`. // See more at: // https://github.com/GoogleChrome/sw-precache#replaceprefix-string replacePrefix: args.pathPrefix || ``, @@ -57,5 +57,5 @@ exports.onPostBuild = (args, pluginOptions) => { const combinedOptions = _.defaults(pluginOptions, options) - return precache.write(`public/sw.js`, combinedOptions) + return precache.write(`${rootDir}/sw.js`, combinedOptions) } diff --git a/packages/gatsby-plugin-sharp/src/index.js b/packages/gatsby-plugin-sharp/src/index.js index b8d9f9579779f..702847795e8b9 100644 --- a/packages/gatsby-plugin-sharp/src/index.js +++ b/packages/gatsby-plugin-sharp/src/index.js @@ -173,7 +173,7 @@ const processFile = (file, jobs, cb, reporter) => { ], }) .then(imageminBuffer => { - fs.writeFile(job.outputPath, imageminBuffer, onFinish) + fs.writeFile(job.buildPath, imageminBuffer, onFinish) }) .catch(onFinish) ) @@ -191,14 +191,14 @@ const processFile = (file, jobs, cb, reporter) => { plugins: [imageminWebp({ quality: args.quality })], }) .then(imageminBuffer => { - fs.writeFile(job.outputPath, imageminBuffer, onFinish) + fs.writeFile(job.buildPath, imageminBuffer, onFinish) }) .catch(onFinish) ) .catch(onFinish) // any other format (jpeg, tiff) - don't compress it just handle output } else { - clonedPipeline.toFile(job.outputPath, onFinish) + clonedPipeline.toFile(job.buildPath, onFinish) } }) } @@ -210,7 +210,7 @@ const q = queue((task, callback) => { const queueJob = (job, reporter) => { const inputFileKey = job.file.absolutePath.replace(/\./g, `%2E`) - const outputFileKey = job.outputPath.replace(/\./g, `%2E`) + const outputFileKey = job.buildPath.replace(/\./g, `%2E`) const jobPath = `${inputFileKey}.${outputFileKey}` // Check if the job has already been queued. If it has, there's nothing @@ -220,7 +220,7 @@ const queueJob = (job, reporter) => { } // Check if the output file already exists so we don't redo work. - if (fs.existsSync(job.outputPath)) { + if (fs.existsSync(job.buildPath)) { return } @@ -304,7 +304,8 @@ function queueImageResizing({ file, args = {}, reporter }) { const imgSrc = `/${file.name}-${ file.internal.contentDigest }-${argsDigestShort}.${fileExtension}` - const filePath = path.join(process.cwd(), `public`, `static`, imgSrc) + const buildDirectory = process.env.GATSBY_BUILD_DIR || `public` + const filePath = path.join(process.cwd(), buildDirectory, `static`, imgSrc) // Create function to call when the image is finished. let outsideResolve, outsideReject @@ -342,7 +343,7 @@ function queueImageResizing({ file, args = {}, reporter }) { outsideResolve, outsideReject, inputPath: file.absolutePath, - outputPath: filePath, + buildPath: filePath, } queueJob(job, reporter) diff --git a/packages/gatsby-plugin-sitemap/src/gatsby-node.js b/packages/gatsby-plugin-sitemap/src/gatsby-node.js index d4957c386579b..c75ad2a0b49a0 100644 --- a/packages/gatsby-plugin-sitemap/src/gatsby-node.js +++ b/packages/gatsby-plugin-sitemap/src/gatsby-node.js @@ -2,7 +2,8 @@ import path from "path" import sitemap from "sitemap" import { defaultOptions, runQuery, writeFile } from "./internals" -const publicPath = `./public` +const buildDirectory = process.env.GATSBY_BUILD_DIR || `public` +const publicPath = `./${buildDirectory}` exports.onPostBuild = async ({ graphql, pathPrefix }, pluginOptions) => { const options = { ...pluginOptions } diff --git a/packages/gatsby-remark-copy-linked-files/src/__tests__/index.js b/packages/gatsby-remark-copy-linked-files/src/__tests__/index.js index f5b0e5840b7c0..fc7526dcb3155 100644 --- a/packages/gatsby-remark-copy-linked-files/src/__tests__/index.js +++ b/packages/gatsby-remark-copy-linked-files/src/__tests__/index.js @@ -171,8 +171,9 @@ describe(`gatsby-remark-copy-linked-files`, () => { describe(`options.destinationDir`, () => { const imagePath = `images/sample-image.gif` + const buildDirectory = process.env.GATSBY_BUILD_DIR || `public` - it(`throws an error if the destination directory is not within 'public'`, async () => { + it(`throws an error if the destination directory is not within '${buildDirectory}'`, async () => { const markdownAST = remark.parse(`![some absolute image](${imagePath})`) const invalidDestinationDir = `../destination` expect.assertions(2) @@ -192,7 +193,7 @@ describe(`gatsby-remark-copy-linked-files`, () => { const validDestinationDir = `path/to/dir` const expectedNewPath = path.posix.join( process.cwd(), - `public`, + buildDirectory, validDestinationDir, `/undefined-undefined.gif` ) @@ -246,7 +247,7 @@ describe(`gatsby-remark-copy-linked-files`, () => { const markdownAST = remark.parse(`![some absolute image](${imagePath})`) const expectedNewPath = path.posix.join( process.cwd(), - `public`, + buildDirectory, `/undefined-undefined.gif` ) expect.assertions(3) diff --git a/packages/gatsby-remark-copy-linked-files/src/index.js b/packages/gatsby-remark-copy-linked-files/src/index.js index 7fead4418b3df..b54beb807ff95 100644 --- a/packages/gatsby-remark-copy-linked-files/src/index.js +++ b/packages/gatsby-remark-copy-linked-files/src/index.js @@ -7,8 +7,6 @@ const _ = require(`lodash`) const cheerio = require(`cheerio`) const imageSize = require(`probe-image-size`) -const DEPLOY_DIR = `public` - const invalidDestinationDirMessage = dir => `[gatsby-remark-copy-linked-files You have supplied an invalid destination directory. The destination directory must be a child but was: ${dir}` @@ -22,15 +20,16 @@ const newFileName = linkNode => `${linkNode.name}-${linkNode.internal.contentDigest}.${linkNode.extension}` const newPath = (linkNode, destinationDir) => { + const buildDirectory = process.env.GATSBY_BUILD_DIR || `public` if (destinationDir) { return path.posix.join( process.cwd(), - DEPLOY_DIR, + buildDirectory, destinationDir, newFileName(linkNode) ) } - return path.posix.join(process.cwd(), DEPLOY_DIR, newFileName(linkNode)) + return path.posix.join(process.cwd(), buildDirectory, newFileName(linkNode)) } const newLinkURL = (linkNode, destinationDir, pathPrefix) => { diff --git a/packages/gatsby-source-filesystem/src/extend-file-node.js b/packages/gatsby-source-filesystem/src/extend-file-node.js index 38d07c0dd3e98..911d6ded547a8 100644 --- a/packages/gatsby-source-filesystem/src/extend-file-node.js +++ b/packages/gatsby-source-filesystem/src/extend-file-node.js @@ -7,11 +7,13 @@ module.exports = ({ type, getNodeAndSavePathDependency, pathPrefix = `` }) => { return {} } + const buildDirectory = process.env.GATSBY_BUILD_DIR || `public` + return { publicURL: { type: GraphQLString, args: {}, - description: `Copy file to static directory and return public url to it`, + description: `Copy file to static directory and return ${buildDirectory} url to it`, resolve: (file, fieldArgs, context) => { const details = getNodeAndSavePathDependency(file.id, context.path) const fileName = `${file.name}-${file.internal.contentDigest}${ @@ -20,7 +22,7 @@ module.exports = ({ type, getNodeAndSavePathDependency, pathPrefix = `` }) => { const publicPath = path.join( process.cwd(), - `public`, + buildDirectory, `static`, fileName ) diff --git a/packages/gatsby-transformer-sharp/src/extend-node-type.js b/packages/gatsby-transformer-sharp/src/extend-node-type.js index b147b0a820c4c..1205f9d005185 100644 --- a/packages/gatsby-transformer-sharp/src/extend-node-type.js +++ b/packages/gatsby-transformer-sharp/src/extend-node-type.js @@ -73,9 +73,10 @@ module.exports = ({ const imageName = `${details.name}-${image.internal.contentDigest}${ details.ext }` + const buildDirectory = process.env.GATSBY_BUILD_DIR || `public` const publicPath = path.join( process.cwd(), - `public`, + buildDirectory, `static`, imageName ) diff --git a/packages/gatsby/cache-dir/default-html.js b/packages/gatsby/cache-dir/default-html.js index e668269bc66cf..e826761a9da57 100644 --- a/packages/gatsby/cache-dir/default-html.js +++ b/packages/gatsby/cache-dir/default-html.js @@ -1,9 +1,10 @@ import React from "react" let stylesStr +const buildDirectory = process.env.GATSBY_BUILD_DIR || `public` if (process.env.NODE_ENV === `production`) { try { - stylesStr = require(`!raw-loader!../public/styles.css`) + stylesStr = require(`!raw-loader!../${buildDirectory}/styles.css`) } catch (e) { console.log(e) } diff --git a/packages/gatsby/cache-dir/static-entry.js b/packages/gatsby/cache-dir/static-entry.js index 61cd525188520..617a823a26fa3 100644 --- a/packages/gatsby/cache-dir/static-entry.js +++ b/packages/gatsby/cache-dir/static-entry.js @@ -52,6 +52,7 @@ module.exports = (locals, callback) => { let preBodyComponents = [] let postBodyComponents = [] let bodyProps = {} + const buildDirectory = process.env.GATSBY_BUILD_DIR || `public` const replaceBodyHTMLString = body => { bodyHtml = body @@ -139,7 +140,7 @@ module.exports = (locals, callback) => { let stats try { - stats = require(`../public/stats.json`) + stats = require(`../${buildDirectory}/stats.json`) } catch (e) { // ignore } @@ -184,7 +185,7 @@ module.exports = (locals, callback) => { }) // Add the chunk-manifest at the end of body element. - const chunkManifest = require(`!raw!../public/chunk-manifest.json`) + const chunkManifest = require(`!raw!../${buildDirectory}/chunk-manifest.json`) postBodyComponents.unshift(