diff --git a/packages/gatsby/src/bootstrap/index.js b/packages/gatsby/src/bootstrap/index.js index c5dc284850243..024a4d24eafd6 100644 --- a/packages/gatsby/src/bootstrap/index.js +++ b/packages/gatsby/src/bootstrap/index.js @@ -352,13 +352,14 @@ module.exports = async (args: BootstrapArgs) => { ) const browserPluginsRequires = browserPlugins - .map( - plugin => - `{ - plugin: require('${plugin.resolve}'), + .map(plugin => { + // we need a relative import path to keep contenthash the same if directory changes + const relativePluginPath = path.relative(siteDir, plugin.resolve) + return `{ + plugin: require('${slash(relativePluginPath)}'), options: ${JSON.stringify(plugin.options)}, }` - ) + }) .join(`,`) const browserAPIRunner = `module.exports = [${browserPluginsRequires}]\n` diff --git a/packages/gatsby/src/bootstrap/requires-writer.js b/packages/gatsby/src/bootstrap/requires-writer.js index 997fee990707a..62015b51618c3 100644 --- a/packages/gatsby/src/bootstrap/requires-writer.js +++ b/packages/gatsby/src/bootstrap/requires-writer.js @@ -1,6 +1,8 @@ const _ = require(`lodash`) +const path = require(`path`) const fs = require(`fs-extra`) const crypto = require(`crypto`) +const slash = require(`slash`) const { store, emitter } = require(`../redux/`) const reporter = require(`gatsby-cli/lib/reporter`) const { match } = require(`@reach/router/lib/utils`) @@ -143,12 +145,17 @@ const preferDefault = m => m && m.default || m const preferDefault = m => m && m.default || m \n` asyncRequires += `exports.components = {\n${components - .map( - c => - ` "${c.componentChunkName}": () => import("${joinPath( - c.component - )}" /* webpackChunkName: "${c.componentChunkName}" */)` - ) + .map(c => { + // we need a relative import path to keep contenthash the same if directory changes + const relativeComponentPath = path.relative( + path.join(program.directory, `.cache`), + c.component + ) + + return ` "${c.componentChunkName}": () => import("${slash( + relativeComponentPath + )}" /* webpackChunkName: "${c.componentChunkName}" */)` + }) .join(`,\n`)} }\n\n` diff --git a/packages/gatsby/src/utils/webpack-utils.js b/packages/gatsby/src/utils/webpack-utils.js index 88611b7111f5d..9ed646bc0414e 100644 --- a/packages/gatsby/src/utils/webpack-utils.js +++ b/packages/gatsby/src/utils/webpack-utils.js @@ -459,7 +459,10 @@ module.exports = async ({ loaders.css({ ...options, importLoaders: 1 }), loaders.postcss({ browsers }), ] - if (!isSSR) use.unshift(loaders.miniCssExtract({ hmr: !options.modules })) + if (!isSSR) + use.unshift( + loaders.miniCssExtract({ hmr: !PRODUCTION && !options.modules }) + ) return { use, diff --git a/packages/gatsby/src/utils/webpack.config.js b/packages/gatsby/src/utils/webpack.config.js index afe4b48085d35..f34c6c0169476 100644 --- a/packages/gatsby/src/utils/webpack.config.js +++ b/packages/gatsby/src/utils/webpack.config.js @@ -469,6 +469,10 @@ module.exports = async ( runtimeChunk: { name: `webpack-runtime`, }, + // use hashes instead of ids for module identifiers + // TODO update to deterministic in webpack 5 (hashed is deprecated) + // @see https://webpack.js.org/guides/caching/#module-identifiers + moduleIds: `hashed`, splitChunks: { name: false, chunks: `all`, @@ -497,6 +501,8 @@ module.exports = async ( test: /\.(css|scss|sass|less|styl)$/, chunks: `all`, enforce: true, + // this rule trumps all other rules because of the priority. + priority: 10, }, }, },