gatsbyjs / gatsby

The best React-based framework with performance, scalability and security built in.
https://www.gatsbyjs.com
MIT License
55.28k stars 10.31k forks source link

Gastby build failing during "Building production JavaScript and CSS bundles" step - "Callback was already called" #27891

Closed Pearce-Ropion closed 3 years ago

Pearce-Ropion commented 3 years ago

Hi, I'm running a website that is using a combination of gatsby and netlify CMS however the repo is unfortunately private. We are trying update our gatsby packages so as to use some of the new features coming out. I've updated all my gatsby packages to their latest version except for gatsby-source-apiserver.

Description

I am seeing an error when running gatsby build during the Building production Javascript and CSS bundles step. After which the process completely freezes. There is no Build Failed message nor the does the terminal return to normal forcing me to ^C. Here's the error:

/home/propion/Projects/Bifrost/bifrost/frontend/node_modules/yoga-layout-prebuilt/yoga-layout/build/Release/nbind.js:53
        throw ex;
        ^

Error: Callback was already called.
    at throwError (/home/propion/Projects/Bifrost/bifrost/frontend/node_modules/neo-async/async.js:16:11)
    at /home/propion/Projects/Bifrost/bifrost/frontend/node_modules/neo-async/async.js:2818:7
    at process._tickCallback (internal/process/next_tick.js:61:11)

My start command always runs npx gatsby clean first before running npx gatsby build. Building the development bundle works correctly with no errors.

I've found similar issues but none of their solutions have worked https://github.com/gatsbyjs/gatsby/issues/25142 https://stackoverflow.com/questions/59575264/building-gatsby-site-on-netlify-err-callback-was-already-called https://community.netlify.com/t/first-time-trying-to-deploy-netlify-cms-gatsby-starter-template-fails/12977/8

Based on the above I assume that it has something to do with gatsby-plugin-netlify-cms

I have tried:

Steps to reproduce

Unfortunately I was unable to re-produce using a minimal build using the latest versions of gatsby and gatsby-plugin-netlify-cms so I can only assume that it has something to do with the my environment that couldn't be replicated in the code-sandbox.

My gatsby-config.js, gatsby-node.js and package.json are massive so I will only be posting what I believe to the relevant sections. I would be happy to post more.

gatsby-config.js

module.exports = {
    siteMetadata: {
        siteUrl: "https://www.singlestore.com",
    },
    plugins: [
        {
            resolve: "gatsby-plugin-manifest",
            options: {
                icon: `${__dirname}/static/images/favicon/icon.png`,
                name: "SingleStore",
                short_name: "SingleStore",
                start_url: "/",
                background_color: colors.purple800,
                theme_color: colors.purple800,
                display: "standalone",
            },
        },
        {
            resolve: "gatsby-plugin-sass",
            options: {
                includePaths: [`${__dirname}/src`],
            },
        },
        "gatsby-plugin-react-helmet",
        "gatsby-transformer-json",
        "gatsby-transformer-yaml",
        {
            resolve: "gatsby-plugin-netlify-cms",
            htmlTitle: "Bifrost Content Manager",
            options: {
                manualInit: true,
                enableIdentityWidget: false,
                modulePath: `${__dirname}/src/cms/cms.js`,
                htmlTitle: "Bifrost Admin",
                customizeWebpackConfig: (config, { plugins }) => {
                    config.resolve.modules = [
                        path.resolve(__dirname, "src"),
                        "node_modules",
                    ];
                    config.plugins.push(
                        plugins.define({
                            "process.env": {
                                NODE_ENV: JSON.stringify(process.env.NODE_ENV),
                            },
                        })
                    );
                    config.devtool = false;
                },
            },
        },
        {
            resolve: "gatsby-source-filesystem",
            options: {
                name: "data",
                path: `${__dirname}/src/data/`,
            },
        },
        // A whole bunch of other source filesystem/apiserver calls
        {
            resolve: "gatsby-plugin-sentry",
            options: {
                dsn: SENTRY_DSN,
                environment: process.env.NODE_ENV,
            },
        },
        {
            resolve: "gatsby-plugin-intercom-spa",
            options: {
                app_id: INTERCOM_APP_ID,
                include_in_development: true,
            },
        },
        {
            resolve: "gatsby-plugin-sitemap",
            options: {
                exclude: ["/patents", "/datafeeds", "/org"],
                query: `
                    {
                        site {
                            siteMetadata {
                                siteUrl
                            }
                        }
                        allSitePage {
                            edges {
                                node {
                                    path
                                    context {
                                        isNoIndex
                                    }
                                }
                            }
                        }
                    }
                `,
                serialize: ({ site, allSitePage }) =>
                    allSitePage.edges
                        .filter(({ node }) => !node.context.isNoIndex)
                        .map(({ node }) => ({
                            url: site.siteMetadata.siteUrl + node.path,
                            changefreq: "daily",
                            priority: 0.7,
                        })),
            },
        },
        {
            resolve: "gatsby-plugin-robots-txt",
            options: {
                host: SITE_ORIGIN,
                sitemap: `${SITE_URL}sitemap.xml`,
                policy: [
                    {
                        userAgent: "*",
                        allow: "/",
                        disallow: ["/assets/"],
                    },
                ],
            },
        },
    ],
};

gatsby-node.js

exports.onCreateWebpackConfig = ({ stage, actions, plugins, loaders }) => {
    let config = {
        resolve: {
            modules: [path.resolve(__dirname, "src"), "node_modules"],
        },
        plugins: [
            plugins.provide({
                // exposes jquery as global for the Swiftype vendor library
                jQuery: "jquery",
                // ideally we should eventually remove these and instead use
                // explicit imports within files to take advantage of
                // treeshaking-friendly lodash imports
                $: "jquery",
                _: "lodash",
            }),
            plugins.define({
                PRERENDER_NAVBAR: JSON.stringify(false),
            }),
        ],
    };

    // For local development, we disable proper sourcemaps to speed up
    // performance.
    if (stage === "develop") {
        config = {
            ...config,
            devtool: "eval",
        };
    }

    if (stage === "build-javascript") {
        config = {
            ...config,
            devtool: "cheap-module-source-map",
        };

        // This suppresses the mini-css-extract-plugin warnings on build. So far
        // there are no known issues - an ideal solution is to either use CSS
        // modules or CSS-in-JS so that CSS ordering is irrelevant but either
        // solution requires a massive refactor. For more info:
        // https://github.com/webpack-contrib/mini-css-extract-plugin/issues/250
        // We use this plugin instead of webpack's stats.warningsFilter option
        // because gatsby does not respect it
        config.plugins.push(
            new FilterWarningsPlugin({
                exclude: /.*\[mini-css-extract-plugin\]\nConflicting order./,
            })
        );
    }

    if (stage === "build-html") {
        config = {
            ...config,
            module: {
                rules: [
                    {
                        // ignore these modules which rely on the window global on build phase
                        test: /jquery|js-cookie|query-string|tabbable/,
                        use: loaders.null(),
                    },
                ],
            },
        };
    }

    actions.setWebpackConfig(config);
};

exports.onCreateNode = async ({ node, actions }) => {
    const { createNodeField } = actions;
    const {
        departments,
        internal: { owner: sourceType },
    } = node;

    if (departments) {
        departments.forEach(department => {
            department.child_ids = department.child_ids.filter(
                id => !Array.isArray(id)
            );
        });
    }

    if (sourceType === "gatsby-transformer-yaml") {
        /**
         * @function reduceDeepCallback
         * @description This attempts to extract the eloqua form id from any node,
         * no matter how deep it is. When a key called elqFormId is found, the current
         * path to its parent is saved, or if the elqFormId is found at the top level,
         * the path is set to null.
         * 
         * @returns {Promise[]} An array of promises that when resolved, contains the
         * form fields and the path that the eloqua form id was found at within the node
         */
        const formPromises = await reduceDeep(
            node,
            async (acc, elqFormId, key, ctx) => {
                if (key === "elqFormId") {
                    if (_.toNumber(elqFormId) > 0) {
                        const form = await fetchElqForm(elqFormId);

                        let path = null;
                        if (ctx.depth > 1) {
                            path = ctx.parent.path;
                        }

                        const resolvedAcc = await acc;

                        resolvedAcc.push({
                            form,
                            path,
                        });
                    }
                }
                return acc;
            },
            []
        );

        if (formPromises.length) {
            const resolvedForms = await Promise.all(formPromises);
            const formFieldsName = "formFields";

            /**
             * @callback formReduceCallback
             * @description Generates the keys/values that will be used as nodes
             * in the generated graphql later on. If a form has a path, that
             * path is generated automatically to match the path that
             * elqFormId was originally found at. If multiple forms exist with similar
             * paths, the parent paths will be merged. If a form has no path,
             * form is added at the top level. @see https://lodash.com/docs/4.17.15#set
             * for a detailed description of how this is done
             */
            const fields = resolvedForms.reduce((acc, { path, form }) => {
                if (path) {
                    const pathToSet = `${path}.${formFieldsName}`;
                    _.set(acc, pathToSet, form);
                } else {
                    acc[formFieldsName] = form;
                }

                return acc;
            }, {});

            _.forEach(fields, (nodeValue, nodeName) => {
                createNodeField({
                    node,
                    name: nodeName,
                    value: nodeValue,
                });
            });
        }
    }
};

// We must call createPageSafely in this hook to ensure new pages created don't
// overwrite existing pages with the same path
exports.onCreatePage = ({ page, actions }) => {
    const { createPage, deletePage } = actions;

    // Pass the page path to context so it's available in page queries as
    // GraphQL variables
    const oldPage = Object.assign({}, page);

    deletePage(oldPage);
    createPageSafely(createPage, {
        ...oldPage,
        context: {
            slug: oldPage.path,
        },
    });
};

exports.createPages = ({ graphql, actions }) => {
    const dir = path.resolve("static/compiled");
    const file = path.join(dir, "blocked-email-domains.json");
    const lpUngatedAssetTemplate = path.resolve(
        "src/templates/lp-ungated-asset.js"
    );
    const lpStandardTemplate = path.resolve("src/templates/lp-standard.js");
    const lpEbookTemplate = path.resolve("src/templates/lp-ebook.js");
    const lpWebinarSeriesTemplate = path.resolve(
        "src/templates/lp-webinar-series.js"
    );
    const lpThankYouTemplate = path.resolve("src/templates/lp-thank-you.js");
    const lpBetaThankYouTemplate = path.resolve(
        "src/templates/lp-beta-thank-you.js"
    );
    const lpEventMainTemplate = path.resolve("src/templates/lp-event-main.js");
    const lpEventHappyHourTemplate = path.resolve(
        "src/templates/lp-event-happy-hour.js"
    );
    const lpEventActivityTemplate = path.resolve(
        "src/templates/lp-event-activity.js"
    );
    const lpEventRoadshowTemplate = path.resolve(
        "src/templates/lp-event-roadshow.js"
    );
    const lpComparisonTemplate = path.resolve(
        "src/templates/lp-comparisons.js"
    );
    const { createPage } = actions;

    return graphql(`{}`).then(result => { // about 600 lines of valid graphql
        if (result.errors) {
            throw result.errors;
        }

        const allResources = result.data.allResourcesCenterYaml.nodes;
        assertResourcesAreValid(allResources);

        // Create pages from the data files generated by the CMS
        result.data.allLpUngatedAssetYaml.edges.forEach(({ node }) => {
            createPageSafely(createPage, {
                path: resolveSlug(
                    node.slug,
                    node.slugPrefix,
                    "lp-ungated-asset"
                ),
                component: lpUngatedAssetTemplate,
                context: {
                    ...node,
                },
            });
        });

        result.data.allLpStandardYaml.edges.forEach(({ node }) => {
            createPageSafely(createPage, {
                path: resolveSlug(node.slug, node.slugPrefix, "lp-standard"),
                component: lpStandardTemplate,
                context: {
                    ...node,
                },
            });
        });

        result.data.allLpThankYouYaml.edges.forEach(({ node }) => {
            createPageSafely(createPage, {
                path: resolveSlug(node.slug, node.slugPrefix, "lp-thank-you"),
                component: lpThankYouTemplate,
                context: {
                    ...node,
                },
            });
        });

        result.data.allLpBetaThankYouYaml.edges.forEach(({ node }) => {
            createPageSafely(createPage, {
                path: resolveSlug(
                    node.slug,
                    node.slugPrefix,
                    "lp-beta-thank-you"
                ),
                component: lpBetaThankYouTemplate,
                context: {
                    ...node,
                },
            });
        });

        result.data.allLpEbookYaml.edges.forEach(({ node }) => {
            createPageSafely(createPage, {
                path: resolveSlug(node.slug, node.slugPrefix, "lp-ebook"),
                component: lpEbookTemplate,
                context: {
                    ...node,
                },
            });
        });

        result.data.allLpWebinarSeriesYaml.edges.forEach(({ node }) => {
            createPageSafely(createPage, {
                path: resolveSlug(
                    node.slug,
                    node.slugPrefix,
                    "lp-webinar-series"
                ),
                component: lpWebinarSeriesTemplate,
                context: {
                    ...node,
                },
            });
        });

        result.data.allLpEventMainYaml.edges.forEach(({ node }) => {
            createPageSafely(createPage, {
                path: resolveSlug(node.slug, node.slugPrefix, "lp-event-main"),
                component: lpEventMainTemplate,
                context: {
                    ...node,
                },
            });
        });

        result.data.allLpEventHappyHourYaml.edges.forEach(({ node }) => {
            createPageSafely(createPage, {
                path: resolveSlug(
                    node.slug,
                    node.slugPrefix,
                    "lp-event-happy-hour"
                ),
                component: lpEventHappyHourTemplate,
                context: {
                    ...node,
                },
            });
        });

        result.data.allLpEventActivityYaml.edges.forEach(({ node }) => {
            createPageSafely(createPage, {
                path: resolveSlug(
                    node.slug,
                    node.slugPrefix,
                    "lp-event-activity"
                ),
                component: lpEventActivityTemplate,
                context: {
                    ...node,
                },
            });
        });

        result.data.allLpEventRoadshowYaml.edges.forEach(({ node }) => {
            createPageSafely(createPage, {
                path: resolveSlug(
                    node.slug,
                    node.slugPrefix,
                    "lp-event-roadshow"
                ),
                component: lpEventRoadshowTemplate,
                context: {
                    ...node,
                },
            });
        });

        const competitors = _.keyBy(
            result.data.allCompetitorsYaml.nodes,
            ({ slug }) => slug
        );

        result.data.allCompetitorsYaml.nodes.forEach(node => {
            createPageSafely(createPage, {
                path: resolveSlug(node.slug, "comparisons", "competitors"),
                component: lpComparisonTemplate,
                context: {
                    competitors,
                    slug: node.slug,
                },
            });
        });

        // Build copy of blocked-email-domains.yml as JSON in /static
        const { blockedEmailDomains } = result.data.miscYaml;
        const domainsArray = blockedEmailDomains
            .trim()
            .split("\n")
            .map(rule => rule.toLowerCase());

        return existsPromise(dir)
            .then(exists => (exists ? Promise.resolve() : mkdirPromise(dir)))
            .then(() => writeFilePromise(file, JSON.stringify(domainsArray)));
    });
};

package.json

{
    "name": "bifrost",
    "description": "Our company website! www.singlestore.com",
    "license": "MIT",
    "scripts": {
        "clean": "npx gatsby clean",
        "start": "npm run clean && npx gatsby develop --port 9000",
        "build": "npm run clean && npx gatsby build",
        "serve": "npx gatsby serve --port 9000",
        "lint": "npx eslint src",
        "lint-fix": "npx eslint src --fix",
        "prettier": "npx prettier --config .prettierrc.json --write '{*.js, {src}/**/*.js}'",
        "prettier-check": "npx prettier --config .prettierrc.json --no-color --list-different '{*.js, {src}/**/*.js}'",
        "test": "npx jest",
        "test-ci": "npx jest --ci",
        "test-coverage": "npx jest --collect-coverage",
        "test-watch": "npx jest --watch"
    },
    "browserslist": [
        ">0.25%",
        "not dead"
    ],
    "devDependencies": {
        "@adobe/node-fetch-retry": "1.0.1",
        "@babel/core": "7.5.4",
        "@babel/plugin-proposal-class-properties": "7.7.0",
        "@babel/plugin-proposal-optional-chaining": "7.12.1",
        "@babel/plugin-syntax-dynamic-import": "7.2.0",
        "@babel/preset-env": "7.6.3",
        "@babel/preset-react": "7.6.3",
        "@cypress/browserify-preprocessor": "2.1.4",
        "@storybook/addon-a11y": "5.3.9",
        "@storybook/addon-knobs": "5.3.9",
        "@storybook/addon-storysource": "5.3.9",
        "@storybook/addon-viewport": "5.3.9",
        "@storybook/addons": "5.3.9",
        "@storybook/cli": "5.3.9",
        "@storybook/react": "5.3.9",
        "@storybook/source-loader": "5.3.9",
        "@testing-library/dom": "7.5.1",
        "@testing-library/jest-dom": "5.7.0",
        "@testing-library/react": "10.0.4",
        "@testing-library/user-event": "10.1.2",
        "autoprefixer": "8.3.0",
        "babel-eslint": "10.1.0",
        "babel-jest": "26.0.1",
        "babel-loader": "8.0.4",
        "babel-plugin-lodash": "3.3.4",
        "babel-plugin-react-docgen": "4.1.0",
        "babel-plugin-transform-react-handled-props": "2.1.0",
        "babel-plugin-transform-react-remove-prop-types": "0.4.24",
        "babel-preset-gatsby": "0.2.29",
        "btoa": "1.2.1",
        "clean-webpack-plugin": "3.0.0",
        "commander": "6.1.0",
        "css-loader": "3.4.1",
        "cypress": "3.6.1",
        "cypress-plugin-retries": "1.4.0",
        "eslint": "6.8.0",
        "eslint-config-prettier": "6.10.1",
        "eslint-plugin-babel": "5.3.0",
        "eslint-plugin-disable": "2.0.1",
        "eslint-plugin-eslint-comments": "3.1.2",
        "eslint-plugin-import": "2.20.2",
        "eslint-plugin-jest": "23.10.0",
        "eslint-plugin-jest-dom": "2.1.0",
        "eslint-plugin-prettier": "3.1.3",
        "eslint-plugin-react": "7.19.0",
        "eslint-plugin-react-hooks": "4.1.2",
        "eslint-plugin-simple-import-sort": "5.0.2",
        "eslint-plugin-switch-case": "1.1.2",
        "eslint-plugin-testing-library": "3.1.2",
        "file-loader": "2.0.0",
        "gatsby": "2.25.3",
        "gatsby-cli": "2.12.117",
        "gatsby-link": "2.4.16",
        "gatsby-plugin-intercom-spa": "0.2.0",
        "gatsby-plugin-manifest": "2.5.2",
        "gatsby-plugin-netlify-cms": "4.3.17",
        "gatsby-plugin-react-helmet": "3.3.14",
        "gatsby-plugin-robots-txt": "1.5.3",
        "gatsby-plugin-sass": "2.4.2",
        "gatsby-plugin-sentry": "1.0.1",
        "gatsby-plugin-sitemap": "2.5.1",
        "gatsby-source-apiserver": "2.1.3",
        "gatsby-source-filesystem": "2.4.2",
        "gatsby-transformer-json": "2.4.15",
        "gatsby-transformer-yaml": "2.4.15",
        "graphql": "14.6.0",
        "html-webpack-inline-source-plugin": "0.0.10",
        "html-webpack-plugin": "3.2.0",
        "jest": "26.0.1",
        "jsdom": "15.2.1",
        "lodash-webpack-plugin": "0.11.5",
        "moment-locales-webpack-plugin": "1.2.0",
        "moment-timezone-data-webpack-plugin": "1.3.0",
        "node-fetch": "2.6.1",
        "node-sass": "4.14.1",
        "prerender-loader": "1.3.0",
        "prettier": "1.19.1",
        "react-lorem-component": "0.13.0",
        "remark": "10.0.1",
        "remark-html": "9.0.0",
        "sass-loader": "8.0.0",
        "storybook-addon-react-docgen": "1.2.28",
        "style-loader": "1.1.2",
        "uglify-js": "3.3.28",
        "uglifyjs-folder": "1.5.1",
        "webpack": "4.41.5",
        "webpack-bundle-analyzer": "3.9.0",
        "webpack-cli": "3.3.10",
        "webpack-filter-warnings-plugin": "1.2.1",
        "yaml": "1.7.2",
        "yup": "0.24.1"
    },
    "dependencies": {
        "@elastic/react-search-ui": "1.4.1",
        "@elastic/search-ui-site-search-connector": "1.4.1",
        "@fortawesome/fontawesome-pro": "5.13.1",
        "@fortawesome/fontawesome-svg-core": "1.2.29",
        "@fortawesome/free-brands-svg-icons": "5.13.1",
        "@fortawesome/pro-light-svg-icons": "5.13.1",
        "@fortawesome/pro-regular-svg-icons": "5.13.1",
        "@fortawesome/pro-solid-svg-icons": "5.13.1",
        "@fortawesome/react-fontawesome": "0.1.11",
        "@reach/router": "1.3.3",
        "@segment/snippet": "4.9.0",
        "@storybook/addon-a11y": "5.3.9",
        "@storybook/addon-knobs": "5.3.9",
        "@storybook/addon-storysource": "5.3.9",
        "@storybook/addon-viewport": "5.3.9",
        "@storybook/addons": "5.3.9",
        "@storybook/cli": "5.3.9",
        "@storybook/react": "5.3.9",
        "@storybook/source-loader": "5.3.9",
        "@testing-library/cypress": "6.0.0",
        "anchorate": "1.2.3",
        "autosuggest-highlight": "3.1.1",
        "balance-text": "3.3.0",
        "classnames": "2.2.5",
        "common-tags": "1.8.0",
        "core-js": "3.6.5",
        "country-list": "2.1.1",
        "focus-trap-react": "4.0.0",
        "formik": "2.1.4",
        "google-map-react": "1.1.2",
        "googleapis": "58.0.0",
        "jquery": "3.3.1",
        "js-cookie": "2.2.0",
        "lodash": "4.17.11",
        "memoize-one": "5.1.1",
        "minisearch": "2.0.0",
        "moment": "2.22.0",
        "moment-timezone": "0.5.31",
        "netlify-cms-app": "2.12.11",
        "netlify-cms-ui-default": "2.9.5",
        "prop-types": "15.6.2",
        "query-string": "5.1.1",
        "react": "16.12.0",
        "react-add-to-calendar-hoc": "1.0.8",
        "react-anchor-link-smooth-scroll": "1.0.12",
        "react-autosuggest": "9.4.3",
        "react-compare-image": "vai0/react-compare-image#60bffe5",
        "react-copy-to-clipboard": "5.0.2",
        "react-dom": "16.12.0",
        "react-dotdotdot": "1.3.1",
        "react-helmet": "6.0.0",
        "react-html-attributes": "1.4.6",
        "react-loadable": "5.5.0",
        "react-player": "2.3.1",
        "react-popper": "1.3.7",
        "react-scrollbars-custom": "4.0.25",
        "react-select": "3.0.8",
        "react-slick": "0.24.0",
        "react-spring": "8.0.27",
        "react-truncate-html": "0.1.7",
        "react-virtualized-auto-sizer": "1.0.2",
        "react-waypoint": "8.0.3",
        "react-window": "1.6.0-alpha.1",
        "react-window-infinite-loader": "1.0.5",
        "react-youtube": "7.6.0",
        "slick-carousel": "1.8.1",
        "storybook-addon-react-docgen": "1.2.28",
        "typeface-inconsolata": "0.0.54",
        "typeface-lato": "0.0.54",
        "typeface-merriweather": "0.0.72",
        "ua-parser-js": "0.7.21",
        "uuid": "3.3.3",
        "whatwg-fetch": "2.0.4",
        "xr": "0.3.0"
    }
}

Environment

System:
    OS: Linux 4.19 Debian GNU/Linux 10 (buster) 10 (buster)
    CPU: (8) x64 Intel(R) Core(TM) i7-8650U CPU @ 1.90GHz
    Shell: 5.7.1 - /usr/bin/zsh
  Binaries:
    Node: 14.15.0 - ~/.nvm/versions/node/v14.15.0/bin/node
    Yarn: 1.21.1 - /usr/bin/yarn
    npm: 6.14.8 - ~/.nvm/versions/node/v14.15.0/bin/npm
  Languages:
    Python: 2.7.16 - /usr/bin/python
  Browsers:
    Chrome: 83.0.4103.116
    Firefox: 78.3.0esr
  npmPackages:
    gatsby: 2.25.3 => 2.25.3 
    gatsby-cli: 2.12.117 => 2.12.117 
    gatsby-link: 2.4.16 => 2.4.16 
    gatsby-plugin-intercom-spa: 0.2.0 => 0.2.0 
    gatsby-plugin-manifest: 2.5.2 => 2.5.2 
    gatsby-plugin-netlify-cms: 4.3.17 => 4.3.17 
    gatsby-plugin-react-helmet: 3.3.14 => 3.3.14 
    gatsby-plugin-robots-txt: 1.5.3 => 1.5.3 
    gatsby-plugin-sass: 2.4.2 => 2.4.2 
    gatsby-plugin-sentry: 1.0.1 => 1.0.1 
    gatsby-plugin-sitemap: 2.5.1 => 2.5.1 
    gatsby-source-apiserver: 2.1.3 => 2.1.3 
    gatsby-source-filesystem: 2.4.2 => 2.4.2 
    gatsby-transformer-json: 2.4.15 => 2.4.15 
    gatsby-transformer-yaml: 2.4.15 => 2.4.15 
sidharthachatterjee commented 3 years ago

Is neo-async a package you're using? Can you run yarn why neo-async to see what package depends on it? If you're using it, can you try removing it?

Pearce-Ropion commented 3 years ago

@sidharthachatterjee Im definitely not using neo-async directly. It looks like it is used in a couple of gatsby packages.

=> Found "neo-async@2.6.2"
info Reasons this module exists
   - "sass-loader" depends on it
   - Hoisted from "sass-loader#neo-async"
   - Hoisted from "webpack#neo-async"
   - Hoisted from "@storybook#cli#jscodeshift#neo-async"
   - Hoisted from "gatsby-plugin-sass#sass-loader#neo-async"
   - Hoisted from "webpack#watchpack#neo-async"
   - Hoisted from "babel-plugin-react-docgen#react-docgen#neo-async"
   - Hoisted from "@storybook#react#webpack#neo-async"
   - Hoisted from "gatsby#webpack#neo-async"
   - Hoisted from "gatsby-plugin-netlify-cms#webpack#neo-async"
   - Hoisted from "@storybook#cli#@storybook#codemod#jscodeshift#neo-async"
   - Hoisted from "@storybook#react#@storybook#core#webpack#neo-async"
   - Hoisted from "@storybook#react#@storybook#core#corejs-upgrade-webpack-plugin#webpack#neo-async"
info Disk size without dependencies: "752KB"
info Disk size with unique dependencies: "752KB"
info Disk size with transitive dependencies: "752KB"
info Number of shared dependencies: 0

Also our storybook is built separately so we can remove all references to storybook as suspect from the list above as well as babel-plugin-react-docgen which is also used for our storybook.

Edit: Had another quick look and we use sass-loader as well as webpack directly but also only in our storybook. Otherwise any webpack usage comes from gatsby.

Pearce-Ropion commented 3 years ago

I just confirmed that this issue pertains specifically to gatsby-plugin-netlify-cms. I tried removing the plugin from the gatsby-config and re-building and was able to build just fine.

I think the issue may have something to do with how the CSS is handled in gatsby-plugin-netlify-cms. I found this thread: https://stackoverflow.com/questions/61799995/running-webpack-throws-callback-was-already-called-error Which states that the css shouldn't be <link>'d to but rather imported. Unfortunately Im not really sure how the plugin is getting the correct assets into place.

I can confirm that our implementation does import scss directly into our cms.js file which is then handled by gatsby-plugin-sass and exported as cms.css which is then picked up by netlify-cms and registered correctly. https://github.com/gatsbyjs/gatsby/blob/master/packages/gatsby-plugin-netlify-cms/src/cms.js#L25

I've read some of gatsby-plugin-netlify-cms's code and know that it messes around with the CSS rules in the onCreateWebpackConfig quite a bit so something in there might be the culprit.

Here is a snippet of our cms.js file just in case

import CMS from "netlify-cms-app";

import "typeface-lato";
import "typeface-inconsolata";

import config from "cms/config";
import { BASE_URL } from "config";

import "scss/global.scss";
import "./cms.scss";

global.___loader = {
    enqueue: () => {},
    hovering: () => {},
};

global.__PATH_PREFIX__ = "";

window.___navigate = pathname => {
    alert(`This would navigate to: https://www.${BASE_URL}${pathname}`);
};

CMS.init({
    config,
});
Pearce-Ropion commented 3 years ago

I was able to fix this. Although I never found the exact cause, I believe it has to do with version mismatches between the package versions of babel/webpack loaders that were in my package.json and the versions that gatsby specifies. I believe it was specifically due to css-loader which was a full major version ahead in our site.

I fixed this by going through the package.json of each of the gatsby packages that we use and matching any babel/webpack loader's versions.

marharyta commented 3 years ago

@Pearce-Ropion I can confirm that your description is accurate:

@Pearce-Ropion still no luck, which css packages you have?

Pearce-Ropion commented 3 years ago

@Pearce-Ropion I can confirm that your description is accurate:

  • if I disable gatsby-plugin-netlify-cms the error goes away, but I need it, so

  • I enabled it back but removed all css/scss imports and the error went away, so something to do with sass loader was the

  • reason

  • I removed all <link/> declarations

  • downgraded to node-sass to 4.12 since i was using node 12

@Pearce-Ropion still no luck, which css packages you have?

Basically this problem occurs due to a mismatch in package versions between the packages required in your package.json and the packages required by by any of the other packages that your project uses. Specifically the packages that are used for building (webpack, sass, etc)

I've actually experienced this problem twice now (the second time was about a month after I closed this issue). Here are a few of the things that I found that you should watch out for:

Ultimately, I still believe that the 2 times this happened were separate errors (ie. unrelated errors that attempted to call the same callback fn) but overall, managing the versions of babel/webpack/webpack loaders in order to make them at least resemble the versions used in gatsby and any other build processes you have will fix this issue.

Feel free to pm me if you need more help.

marharyta commented 3 years ago

Interesting, especially considering I did not have either storybook, nor was I importing any sass packages aside from the standard gatsby-plugin-sass. Thanks a lot for coming back to me @Pearce-Ropion , how should I pm you?

marharyta commented 3 years ago

jus in case, here is my setup:

package.json

{
  "name": "gatsby-starter-hello-world",
  "private": true,
  "description": "A simplified bare-bones starter for Gatsby",
  "version": "0.1.0",
  "license": "0BSD",
  "scripts": {
    "build": "gatsby build",
    "develop": "npm run clean && gatsby develop",
    "format": "prettier --write \"**/*.{js,jsx,ts,tsx,json,md}\"",
    "start": "npm run develop",
    "serve": "gatsby serve",
    "clean": "gatsby clean",
    "test": "echo \"Write tests! -> https://gatsby.dev/unit-testing\" && exit 1"
  },
  "dependencies": {
    "dart-sass": "^1.25.0",
    "gatsby": "^2.32.3",
    "gatsby-cli": "^2.19.1",
    "gatsby-image": "^2.11.0",
    "gatsby-plugin-netlify-cms": "^4.10.0",
    "gatsby-plugin-react-helmet": "^3.10.0",
    "gatsby-plugin-sass": "^3.2.0",
    "gatsby-plugin-sharp": "^2.14.1",
    "gatsby-remark-images": "^3.11.0",
    "gatsby-remark-relative-images": "^2.0.2",
    "gatsby-source-filesystem": "^2.11.0",
    "gatsby-transformer-remark": "^2.16.0",
    "gatsby-transformer-sharp": "^2.12.0",
    "netlify-cms-app": "^2.14.18",
    "react-helmet": "^6.1.0"
  },
  "repository": {
    "type": "git",
    "url": "https://github.com/gatsbyjs/gatsby-starter-hello-world"
  },
  "bugs": {
    "url": "https://github.com/gatsbyjs/gatsby/issues"
  }
}
/**
 * Configure your Gatsby site with this file.
 *
 * See: https://www.gatsbyjs.org/docs/gatsby-config/
 */

require("dotenv").config({
  path: `.env.${process.env.NODE_ENV}`,
})

module.exports = {
  siteMetadata: {
    title: 'Gatsby + Netlify CMS Starter',
    siteUrl: "https://daruvisuals.com",
    description:
      'This repo contains an example business website that is built with Gatsby, and Netlify CMS.It follows the JAMstack architecture by using Git as a single source of truth, and Netlify for continuous deployment, and CDN distribution.',
  },
  plugins: [
    'gatsby-plugin-sharp',
    'gatsby-transformer-sharp',
    {
      resolve: `gatsby-transformer-remark`,
      options: {
        plugins: [
          {
            resolve: `gatsby-remark-relative-images`,
          },
          {
            resolve: `gatsby-remark-images`,
            options: {
              // It's important to specify the maxWidth (in pixels) of
              // the content container as this plugin uses this as the
              // base for generating different widths of each image.
              maxWidth: 2048,
            },
          },
        ],
      },
    },
    'gatsby-plugin-react-helmet',
    {
      resolve: `gatsby-plugin-sass`,
      options: {
        implementation: require("dart-sass"),
      },
    },
    {
      resolve: 'gatsby-source-filesystem',
      options: {
        path: `${__dirname}/static/img`,
        name: 'uploads',
      },
    },
    {
      resolve: 'gatsby-source-filesystem',
      options: {
        path: `${__dirname}/src/pages`,
        name: 'pages',
      },
    },
    {
      resolve: 'gatsby-source-filesystem',
      options: {
        path: `${__dirname}/src/img`,
        name: 'images',
      },
    },
    {
      resolve: 'gatsby-plugin-netlify-cms',
      options: {
        modulePath: `${__dirname}/src/cms/cms.js`,
      },
    },
  ]
}
marharyta commented 3 years ago

Ok, as of now, I tried removing gatsby-plugin-sass and used gatsby-plugin-postcss and got the same problem still, next going through the list from here: https://blog.logrocket.com/10-gatsby-styling-methods/

update: creating a project with gatsby-starter-netlify-cms template fro a scratch and using scss files there gives same problem

marharyta commented 3 years ago

After further investigation I figured that maybe indeed something is off with yoga-layout package version here, or the way it works in conjunction with css.

ghost commented 3 years ago

I had this same issue when i cloned the gatsby-starter-netlify-cms and updated the packages (i think the break occured because of gatsby package passed from version "^2.20.35" to the latest "^2.32.3". Before the update the build did not fail. I confirm this issue is somehow related to gatsby-plugin-netlify-cms.

To solve the issue i removed the option of plugin gatsby-plugin-netlify-cms from gatsby-config.js, so instead of:

    {
      resolve: 'gatsby-plugin-netlify-cms',
      options: {
        modulePath: `${__dirname}/src/cms/cms.js`,
      },
    },

i went with:

'gatsby-plugin-netlify-cms',

This was the plugin module file cms.js:

import CMS from 'netlify-cms-app'
import cloudinary from 'netlify-cms-media-library-cloudinary'

import AboutPagePreview from './preview-templates/AboutPagePreview'
import BlogPostPreview from './preview-templates/BlogPostPreview'
import ProductPagePreview from './preview-templates/ProductPagePreview'
import IndexPagePreview from './preview-templates/IndexPagePreview'

CMS.registerMediaLibrary(cloudinary)

CMS.registerPreviewTemplate('index', IndexPagePreview)
CMS.registerPreviewTemplate('about', AboutPagePreview)
CMS.registerPreviewTemplate('products', ProductPagePreview)
CMS.registerPreviewTemplate('blog', BlogPostPreview)

This way my build is OK. Unfortunately, i can not use the module file cms.js to configure the plugin anymore, so if anyone knows a workaround is welcome :)

Also, i'm referencing other issues spread across github which i think are related to this one: #24577 #25466