Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

[v2] fileAbsolutePath starts from the file system root instead of project root #7463

Closed
humphreybc opened this issue Aug 20, 2018 · 6 comments
Labels
stale? Issue that may be closed soon due to the original author not responding any more. type: question or discussion Issue discussing or asking a question about Gatsby

Comments

@humphreybc
Copy link
Contributor

Description

We have some code that creates a hierarchy based on the folder / file structure of Markdown files. We use this to create an index page of all help articles and then show the breadcrumbs when you visit an article based on frontmatter in the parent folder’s index.md file.

Previously, in Gatsby v1, allMarkdownRemark.edges[n].node.fileAbsolutePath would contain the absolute path to the Markdown file relative to the Gatsby root. For example:

src/pages/help/get-started/notes/index.md

Now, in Gatsby v2, it looks like allMarkdownRemark.edges[n].node.fileAbsolutePath contains the absolute path to the Markdown file, relative to the file system. For example:

/Users/humphreybc/Code/dovetail-website/src/pages/help/get-started/notes/index.md

Expected result

The path contained in allMarkdownRemark.edges[n].node.fileAbsolutePath should be relative to the root of the Gatsby project.

Actual result

The path contained in allMarkdownRemark.edges[n].node.fileAbsolutePath is relative to the root of my specific file system.

Environment

  System:
    OS: macOS High Sierra 10.13.5
    CPU: x64 Intel(R) Core(TM) i5-5257U CPU @ 2.70GHz
    Shell: 3.2.57 - /bin/bash
  Binaries:
    Node: 10.3.0 - /usr/local/bin/node
    Yarn: 1.7.0 - /usr/local/bin/yarn
    npm: 6.1.0 - /usr/local/bin/npm
  Browsers:
    Chrome: 68.0.3440.106
    Firefox: 62.0
    Safari: 11.1.1
  npmPackages:
    gatsby: next => 2.0.0-beta.100 
    gatsby-plugin-canonical-urls: next => 2.0.0-beta.3 
    gatsby-plugin-google-tagmanager: next => 2.0.0-beta.3 
    gatsby-plugin-nprogress: next => 2.0.0-beta.4 
    gatsby-plugin-react-helmet: next => 3.0.0-beta.4 
    gatsby-plugin-react-next: next => 2.0.1-13 
    gatsby-plugin-remove-trailing-slashes: next => 2.0.0-beta.3 
    gatsby-plugin-robots-txt: next => 1.3.0 
    gatsby-plugin-sentry: ^0.1.0 => 0.1.0 
    gatsby-plugin-sharp: next => 2.0.0-beta.7 
    gatsby-plugin-sitemap: next => 2.0.0-beta.4 
    gatsby-plugin-typescript: next => 2.0.0-beta.9 
    gatsby-remark-autolink-headers: next => 2.0.0-beta.5 
    gatsby-remark-copy-linked-files: next => 2.0.0-beta.3 
    gatsby-remark-images: next => 2.0.1-beta.10 
    gatsby-source-filesystem: next => 2.0.1-beta.10 
    gatsby-transformer-json: next => 2.1.1-beta.5 
    gatsby-transformer-remark: next => 2.1.1-beta.6 
  npmGlobalPackages:
    gatsby-cli: 1.1.58

File contents (if changed)

gatsby-config.js:

// Based on https://github.com/gatsbyjs/gatsby/blob/master/examples/using-typescript/gatsby-config.js
module.exports = {
  siteMetadata: {
    siteName: "Dovetail",
    siteUrl: process.env.GATSBY_BASE_URL ? process.env.GATSBY_BASE_URL : "https://dovetailapp.com"
  },
  plugins: [
    "gatsby-plugin-react-helmet",
    "gatsby-plugin-react-next",
    "gatsby-plugin-remove-trailing-slashes",
    "gatsby-plugin-sitemap",
    "gatsby-plugin-sharp",
    "gatsby-plugin-typescript",
    "gatsby-plugin-typestyle",
    "gatsby-transformer-json",
    {
      resolve: "gatsby-source-filesystem",
      options: {
        path: "./src/pages",
        name: "documents"
      }
    },
    {
      resolve: "gatsby-source-filesystem",
      options: {
        path: "./src/data/",
        name: "data"
      }
    },
    {
      resolve: "gatsby-transformer-remark",
      options: {
        plugins: [
          "gatsby-remark-copy-linked-files",
          {
            resolve: "gatsby-remark-images",
            options: {
              backgroundColor: "transparent",
              quality: 75,
              maxWidth: 660,
              sizeByPixelDensity: false
            }
          }
        ]
      }
    },
    {
      resolve: "gatsby-plugin-google-tagmanager",
      options: {
        id: "GTM-M2PTNW9",
        includeInDevelopment: false
      }
    },
    {
      resolve: "gatsby-plugin-sentry",
      options: {
        dsn: process.env.SENTRY_DSN || "",
        config: {
          environment: process.env.SENTRY_ENVIRONMENT,
          release: process.env.SENTRY_RELEASE,
          version: "3.24.2"
        }
      }
    },
    {
      resolve: "gatsby-plugin-nprogress",
      options: {
        color: "#512da8",
        showSpinner: false
      }
    },
    {
      resolve: "gatsby-plugin-canonical-urls",
      options: {
        siteUrl: "https://dovetailapp.com"
      }
    },
    {
      resolve: "gatsby-plugin-robots-txt",
      options:
        process.env.PREVENT_CRAWLING === "true"
          ? {
              policy: [{ userAgent: "*", disallow: ["/"] }],
              sitemap: null,
              host: null
            }
          : { policy: [{ userAgent: "*", disallow: ["/confirm", "/404", "/504", "/users/*"] }] }
    }
  ]
};

package.json:

{
  "name": "@heydovetail/website",
  "version": "1.0.0",
  "private": true,
  "description": "Dovetail’s public website",
  "homepage": "https://github.com/heydovetail/website",
  "repository": {
    "type": "git",
    "url": "git@github.com:heydovetail/website.git"
  },
  "license": "UNLICENSED",
  "author": "Benjamin Humphrey <benjamin@dovetailapp.com>",
  "contributors": ["Benjamin Humphrey <benjamin@dovetailapp.com>", "Bradley Ayers <brad@dovetailapp.com>"],
  "scripts": {
    "build": "ts-node ./node_modules/.bin/gatsby build",
    "precommit": "lint-staged",
    "develop": "ts-node ./node_modules/.bin/gatsby develop",
    "fix": "./node_modules/.bin/tslint -p tsconfig.json --fix",
    "generate:svgs": "svg-to-react src",
    "generate:types":
      "./node_modules/.bin/apollo-codegen introspect-schema --output src/graphql/schema.json http://localhost:8000/___graphql && ./node_modules/.bin/apollo-codegen print-schema --schema src/graphql/schema.json --output src/graphql/schema.graphql && ./node_modules/.bin/apollo-codegen generate --schema src/graphql/schema.json --target typescript --output src/graphql/types.tsx --tag-name graphql 'src/**/*.tsx'",
    "generate:zapier": "ts-node ./bin/fetch-zapier-templates.ts",
    "jest": "./node_modules/.bin/jest",
    "postmerge": "./bin/post-merge-update-dependencies",
    "serve": "./node_modules/.bin/gatsby serve",
    "start": "ts-node ./node_modules/.bin/gatsby develop",
    "storybook": "ts-node ./node_modules/.bin/start-storybook -p 9003 -c .storybook",
    "test":
      "./node_modules/.bin/tsc --noEmit && ./node_modules/.bin/tslint -p tsconfig.json && ./node_modules/.bin/jest --runInBand && ts-node ./node_modules/.bin/start-storybook -p 9003 -c .storybook --smoke-test"
  },
  "prettier": {
    "printWidth": 128
  },
  "jest": {
    "globals": {
      "ts-jest": {
        "tsConfigFile": "tsconfig.json"
      },
      "NODE_ENV": "test"
    },
    "moduleFileExtensions": ["js", "ts", "tsx", "json"],
    "moduleNameMapper": {
      ".*\\.(jpg|jpeg|png|gif|eot|otf|webp|svg|ttf|woff|woff2|mp4|webm|wav|mp3|m4a|aac|oga)$": "<rootDir>/.jest/imageMock.tsx",
      "@heydovetail/website/(.*)": "<rootDir>/src/$1"
    },
    "setupFiles": ["<rootDir>/.jest/setup.tsx"],
    "testRegex": "src/.*(/__specs__/.*|\\.spec)\\.tsx?$",
    "transform": {
      "\\.tsx?$": "ts-jest"
    }
  },
  "dependencies": {
    "@heydovetail/editorconfig": "^2.0.0",
    "@heydovetail/svg-to-react": "^1.1.1",
    "@heydovetail/tslint-config": "^2.1.1",
    "@heydovetail/ui-components": "^3.1.6",
    "@storybook/addon-storyshots": "^3.4.0",
    "@storybook/react": "^3.4.0",
    "@types/date-fns": "^2.6.0",
    "@types/jest": "^22.2.2",
    "@types/lodash.groupby": "^4.6.3",
    "@types/node-fetch": "^1.6.9",
    "@types/react": "^16.3.4",
    "@types/react-dom": "^16.0.4",
    "@types/react-helmet": "^5.0.5",
    "@types/react-resize-detector": "^2.1.0",
    "@types/react-test-renderer": "^16.0.1",
    "@types/react-transition-group": "^1.1.4",
    "@types/storybook__addon-actions": "^3.0.3",
    "@types/storybook__addon-storyshots": "^3.4.0",
    "@types/storybook__react": "^3.0.7",
    "@types/yargs": "^11.0.0",
    "apollo-codegen": "^0.19.1",
    "awesome-typescript-loader": "^4.0.1",
    "babel-loader": "^6.4.1",
    "date-fns": "^1.29.0",
    "gatsby": "next",
    "gatsby-plugin-canonical-urls": "next",
    "gatsby-plugin-google-tagmanager": "next",
    "gatsby-plugin-nprogress": "next",
    "gatsby-plugin-react-helmet": "next",
    "gatsby-plugin-react-next": "next",
    "gatsby-plugin-remove-trailing-slashes": "next",
    "gatsby-plugin-robots-txt": "next",
    "gatsby-plugin-sentry": "^0.1.0",
    "gatsby-plugin-sharp": "next",
    "gatsby-plugin-sitemap": "next",
    "gatsby-plugin-typescript": "next",
    "gatsby-remark-autolink-headers": "next",
    "gatsby-remark-copy-linked-files": "next",
    "gatsby-remark-images": "next",
    "gatsby-source-filesystem": "next",
    "gatsby-transformer-json": "next",
    "gatsby-transformer-remark": "next",
    "husky": "^0.14.3",
    "jest": "^22.4.3",
    "jest-cli": "^22.4.3",
    "lint-staged": "7.1.3",
    "lodash.groupby": "^4.6.0",
    "node-fetch": "^2.1.2",
    "prettier": "^1.11.1",
    "react": "^16.4.2",
    "react-dom": "^16.4.2",
    "react-helmet": "^5.2.0",
    "react-masonry-responsive": "^2.1.1",
    "react-resize-detector": "^1.1.0",
    "react-test-renderer": "^16.3.1",
    "react-transition-group": "^2.3.1",
    "storybook-router": "^0.3.4",
    "ts-jest": "^22.4.2",
    "ts-node": "^5.0.1",
    "tslib": "^1.9.0",
    "tslint": "^5.9.1",
    "typeface-rubik": "^0.0.54",
    "typescript": "^2.9.1",
    "typestyle": "^1.7.2",
    "typestyle-react": "^1.2.0",
    "yargs": "^11.0.0"
  },
  "resolutions": {
    "upath": "1.0.5"
  },
  "engines": {
    "node": "10.3.0",
    "yarn": "1.7.0"
  },
  "lint-staged": {
    "*.tsx": ["prettier --write", "tslint -p tsconfig.json --fix", "git add"]
  }
}

gatsby-node.js:

import * as path from "path";

export async function createPages({ actions, graphql }) {
  const { createPage } = actions;
  await createDocumentPages(createPage, graphql);
  await createIntegrationPages(createPage, graphql);
}

// Create the pages for /help, /legal, /guides
async function createDocumentPages(createPage, graphql) {
  const template = path.resolve(`src/templates/document.tsx`);
  const documents = await graphql(`
    query CreateDocumentPages {
      allMarkdownRemark(sort: { order: DESC, fields: [frontmatter___date] }, limit: 1000) {
        edges {
          node {
            fileAbsolutePath
            frontmatter {
              path
              title
              weight
              breadcrumbOnly
            }
          }
        }
      }
    }
  `);

  if (documents.errors) {
    throw new Error(documents.errors);
  }

  // Build a mapping of breadcrumbs (paths) to titles:
  //
  //     {
  //       "help/billing-and-payments": "Billing and payments",
  //       "help/billing-and-payments/billing": "Add or update your billing details",
  //       "help/billing-and-payments/cancel": "Cancel your subscription"
  //     }
  //
  const relPathDirInfo = {};
  for (const { node } of documents.data.allMarkdownRemark.edges) {
    const relPath = path.relative("src/pages", node.fileAbsolutePath);
    const relPathDir = path.dirname(relPath);
    relPathDirInfo[relPathDir] = {
      title: node.frontmatter.title,
      path: node.frontmatter.path
    };
  }

  function getBreadcrumb(relPath) {
    const result = [];

    while (relPath !== ".") {
      if (relPath in relPathDirInfo) {
        result.splice(0, 0, relPathDirInfo[relPath]);
      }
      relPath = path.dirname(relPath);
    }

    // Skip the last component of the breadcrumb, as this is the page itself and
    // would be shown in a page title instead of breadcrumb.
    result.pop();

    return result;
  }

  documents.data.allMarkdownRemark.edges.forEach(({ node }) => {
    if (node.frontmatter.path && node.frontmatter.breadcrumbOnly !== true) {
      const breadcrumb = getBreadcrumb(path.relative("src/pages", node.fileAbsolutePath));

      createPage({
        path: node.frontmatter.path,
        component: template,
        context: {
          breadcrumb
        }
      });
    }
  });
}

// Create the pages for /integrations
async function createIntegrationPages(createPage, graphql) {
  const template = path.resolve(`src/templates/integration.tsx`);
  const integrations = await graphql(`
    query CreateIntegrationPages {
      allIntegrationsJson {
        edges {
          node {
            path
          }
        }
      }
    }
  `);

  if (integrations.errors) {
    throw new Error(integrations.errors);
  }

  integrations.data.allIntegrationsJson.edges.forEach(({ node }) => {
    if (node.path) {
      createPage({
        path: node.path,
        component: template
      });
    }
  });
}

export function onCreateWebpackConfig({ actions, stage }) {
  actions.setWebpackConfig({
    resolve: {
      alias: {
        "@heydovetail/website": path.resolve(__dirname, "./src")
      }
    }
  });
}

gatsby-browser.js: N/A
gatsby-ssr.js: N/A

@grallc
Copy link

grallc commented Aug 20, 2018

Hello,

I think an absolute paths starts to the system's root, so the real problem were on version 1.0.
Please tell me if i'm wrong.

@Chuloo Chuloo added the type: question or discussion Issue discussing or asking a question about Gatsby label Aug 21, 2018
@humphreybc
Copy link
Contributor Author

@grallc I would have expected the absolute path to start from the project root otherwise you'd have all sorts of problems when building in different environements. Regardless, if this change is intended, it would be nice if it were documented somewhere.

One thing I have noticed is that node.fileAbsolutePath seems to be different during gatsby build vs gatsby develop (or when JS kicks in after running gatsby serve after a build).

During build, the path is what it used to be (relative to the project root) but when running gatsby develop the path is absolute to the file system.

@humphreybc
Copy link
Contributor Author

I had time today to investigate this some more. It turns out that node.fileAbsolutePath is fine and unchanged from v1. The problem is with using relative from the path module:

import { dirname, relative } from "path";

let fileRelPath = relative(absoluteFilePathPrefix, dirname(fileAbsolutePath));

…where absoluteFilePathPrefix is something like src/pages/help.

When this code is run during the server build, fileRelPath ends up being get-started/notes. However when this same line is run by the browser it ends up being a long relative path: ../../../Users/humphreybc/Code/dovetail-website/src/pages/help/get-started/notes.

Something has changed between Gatsby v1 and v2 which means that relative returns different things depending on whether it's being called during the server build or run in-browser.

In my case, I ended up fixing it with a hacky workaround:

if (fileRelPath.includes("pages")) {
  fileRelPath = fileRelPath.split(absoluteFilePathPrefix)[1].replace(/^\/+/g, "");
}

@gatsbot gatsbot bot added the stale? Issue that may be closed soon due to the original author not responding any more. label Dec 25, 2018
@gatsbot
Copy link

gatsbot bot commented Dec 25, 2018

Old issues will be closed after 30 days of inactivity. This issue has been quiet for 20 days and is being marked as stale. Reply here or add the label "not stale" to keep this issue open!

@gatsbot
Copy link

gatsbot bot commented Jan 5, 2019

This issue is being closed due to inactivity. Is this a mistake? Please re-open this issue or create a new issue.

@gatsbot gatsbot bot closed this as completed Jan 5, 2019
@webOS101
Copy link
Contributor

Ugh. I'd love to see some action on this since I would prefer to not leak private information about build machines to our public site.

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
stale? Issue that may be closed soon due to the original author not responding any more. type: question or discussion Issue discussing or asking a question about Gatsby
Projects
None yet
Development

No branches or pull requests

4 participants