Skip to content

Commit

Permalink
feat(gatsby): add pnp resolving by passing rootdir in pkg resolving (#…
Browse files Browse the repository at this point in the history
…12163)

## Description

The current resolution algorithm takes loads the plugins using `require.resolve` via `gatsby`, meaning that PnP will block them unless they're listed in `gatsby`'s dependencies. This diff ensures that the plugins are loaded from the package that contains the configuration.

## Related Issues

#10245
  • Loading branch information
arcanis authored and pieh committed Mar 6, 2019
1 parent 8b7d831 commit 72e0d6f
Show file tree
Hide file tree
Showing 4 changed files with 31 additions and 9 deletions.
2 changes: 1 addition & 1 deletion packages/gatsby/src/bootstrap/index.js
Original file line number Diff line number Diff line change
Expand Up @@ -108,7 +108,7 @@ module.exports = async (args: BootstrapArgs) => {

activity = report.activityTimer(`load plugins`)
activity.start()
const flattenedPlugins = await loadPlugins(config)
const flattenedPlugins = await loadPlugins(config, program.directory)
activity.end()

// onPreInit
Expand Down
4 changes: 2 additions & 2 deletions packages/gatsby/src/bootstrap/load-plugins/index.js
Original file line number Diff line number Diff line change
Expand Up @@ -37,9 +37,9 @@ const flattenPlugins = plugins => {
return flattened
}

module.exports = async (config = {}) => {
module.exports = async (config = {}, rootDir = null) => {
// Collate internal plugins, site config plugins, site default plugins
const plugins = loadPlugins(config)
const plugins = loadPlugins(config, rootDir)

// Create a flattened array of the plugins
let flattenedPlugins = flattenPlugins(plugins)
Expand Down
19 changes: 13 additions & 6 deletions packages/gatsby/src/bootstrap/load-plugins/load.js
Original file line number Diff line number Diff line change
Expand Up @@ -8,6 +8,7 @@ const { warnOnIncompatiblePeerDependency } = require(`./validate`)
const { store } = require(`../../redux`)
const existsSync = require(`fs-exists-cached`).sync
const createNodeId = require(`../../utils/create-node-id`)
const createRequireFromPath = require(`../../utils/create-require-from-path`)

function createFileContentHash(root, globPattern) {
const hash = crypto.createHash(`md5`)
Expand Down Expand Up @@ -46,9 +47,11 @@ const createPluginId = (name, pluginObject = null) =>
* This can be a name of a local plugin, the name of a plugin located in
* node_modules, or a Gatsby internal plugin. In the last case the pluginName
* will be an absolute path.
* @param {string} rootDir
* This is the project location, from which are found the plugins
* @return {PluginInfo}
*/
function resolvePlugin(pluginName) {
function resolvePlugin(pluginName, rootDir) {
// Only find plugins when we're not given an absolute path
if (!existsSync(pluginName)) {
// Find the plugin in the local plugins folder
Expand Down Expand Up @@ -81,7 +84,11 @@ function resolvePlugin(pluginName) {
* which should be located in node_modules.
*/
try {
const resolvedPath = slash(path.dirname(require.resolve(pluginName)))
const requireSource =
rootDir !== null
? createRequireFromPath(`${rootDir}/:internal:`)
: require
const resolvedPath = slash(path.dirname(requireSource.resolve(pluginName)))

const packageJSON = JSON.parse(
fs.readFileSync(`${resolvedPath}/package.json`, `utf-8`)
Expand All @@ -101,7 +108,7 @@ function resolvePlugin(pluginName) {
}
}

module.exports = (config = {}) => {
module.exports = (config = {}, rootDir = null) => {
// Instantiate plugins.
const plugins = []

Expand All @@ -110,7 +117,7 @@ module.exports = (config = {}) => {
// Also test adding to redux store.
const processPlugin = plugin => {
if (_.isString(plugin)) {
const info = resolvePlugin(plugin)
const info = resolvePlugin(plugin, rootDir)

return {
...info,
Expand Down Expand Up @@ -145,7 +152,7 @@ module.exports = (config = {}) => {
}
}

const info = resolvePlugin(plugin.resolve)
const info = resolvePlugin(plugin.resolve, rootDir)

return {
...info,
Expand Down Expand Up @@ -190,7 +197,7 @@ module.exports = (config = {}) => {
const program = store.getState().program
plugins.push(
processPlugin({
resolve: `gatsby-plugin-page-creator`,
resolve: require.resolve(`gatsby-plugin-page-creator`),
options: {
path: slash(path.join(program.directory, `src/pages`)),
pathCheck: false,
Expand Down
15 changes: 15 additions & 0 deletions packages/gatsby/src/utils/create-require-from-path.js
Original file line number Diff line number Diff line change
@@ -0,0 +1,15 @@
const Module = require(`module`)
const path = require(`path`)

// Polyfill Node's `Module.createRequireFromPath` if not present (added in Node v10.12.0)
module.exports =
Module.createRequireFromPath ||
function(filename) {
const mod = new Module(filename, null)

mod.filename = filename
mod.paths = Module._nodeModulePaths(path.dirname(filename))
mod._compile(`module.exports = require;`, filename)

return mod.exports
}

0 comments on commit 72e0d6f

Please sign in to comment.