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

New fallback for missing dependencies and better extension management #134

Merged
merged 1 commit into from Oct 6, 2016
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Jump to
Jump to file
Failed to load files.
Diff view
Diff view
3 changes: 3 additions & 0 deletions src/context/extensions/buildExtensionTree.js
@@ -1,5 +1,6 @@
import getExtensions from './steps/getExtensions';
import processDevExports from './steps/processDevExports';
import processNormalExports from './steps/processNormalExports';
import runPostInits from './steps/runPostInits';

const log = require('debug')('roc:core:extensionBuilder');
Expand All @@ -19,6 +20,7 @@ export default function buildExtensionTree(context, packages, plugins, checkRequ
getExtensions('package')(packages),
getExtensions('plugin')(plugins),
processDevExports,
processNormalExports,
runPostInits,
completed,
].reduce(
Expand All @@ -34,6 +36,7 @@ export default function buildExtensionTree(context, packages, plugins, checkRequ
temp: {
postInits: [],
extensionsDevelopmentExports: {},
extensionsNormalExports: {},
startTime: process.hrtime(),
},

Expand Down
5 changes: 5 additions & 0 deletions src/context/extensions/helpers/processRocObject.js
Expand Up @@ -72,6 +72,11 @@ export default function processRocObject(
state.temp.extensionsDevelopmentExports[roc.name] =
state.context.dependencies.exports;
}

if (!/^.*-dev$/.test(roc.name)) {
state.temp.extensionsNormalExports[roc.name] =
state.context.dependencies.exports;
}
}

// Get possible hooks
Expand Down
39 changes: 39 additions & 0 deletions src/context/extensions/steps/processNormalExports.js
@@ -0,0 +1,39 @@
import { initSetDependencies } from '../../../require/manageDependencies';

/*
We want to make all of the dependencies that the "normal" one has available to the development one
since the development one might use some of the "normal" dependencies when running.
An example of this is where a development extension includes some code that has a dependency on something that is
provided from the "normal" extension. This could be code that wraps a dependency as an example.
*/
export default function processNormalExports(initialState) {
let dependencyContext = { ...initialState.dependencyContext };
initialState.context.usedExtensions.forEach(({ name, packageJSON }) => {
// If the name ends in -dev we will remove the -dev part and use that to find dependencies
const normalName = /-dev$/.test(name) && name.slice(0, -4);
if (normalName && initialState.temp.extensionsNormalExports[normalName]) {
dependencyContext =
initSetDependencies(dependencyContext)(
name,
{
...dependencyContext.extensionsDependencies[name],
exports: {
// We add the "normal" exports first since we do not want to overwrite something
// that comes from the development ones because that could result in different
// dependencies in development and production
...initialState.temp.extensionsNormalExports[normalName],
...dependencyContext.extensionsDependencies[name].exports,
},
},
// Remove things that are defined in the package.json directly
// This will avoid that different dependencies are used in development and production
packageJSON
);
}
});

return {
...initialState,
dependencyContext,
};
}
53 changes: 28 additions & 25 deletions src/require/resolveRequest.js
Expand Up @@ -40,33 +40,36 @@ export default function resolveRequest(exports, directory, dependencyContext) {
return request.substring(1);
}

const rocContext = getContext(context, fallback);
if (rocContext) {
log(`(${identifier}) : Checking [${request}] for [${context}]`);

const matches = pattern.exec(request);
const module = matches[1].charAt(0) === '@' ?
`${matches[1]}/${matches[2]}` :
matches[1];

if (!module || !rocContext[module]) {
return request;
}

const newRequest = rocContext[module].resolve ?
rocContext[module].resolve({
module,
request,
requestContext: context,
extensionContext: rocContext[module].context,
}) : resolve.sync(request, { basedir: rocContext[module].context });

log(`(${identifier}) : Found an alias for [${module}] => [${newRequest}]`);

return newRequest || request;
let rocContext = getContext(context, fallback);
if (!rocContext && !fallback) {
return request;
} else if (!rocContext) {
// If all other fails we will resolve in the projects context.
rocContext = exports;
}

log(`(${identifier}) : ${fallback ? '<Fallback> ' : ' '}Checking [${request}] for [${context}]`);

const matches = pattern.exec(request);
const module = matches[1].charAt(0) === '@' ?
`${matches[1]}/${matches[2]}` :
matches[1];

if (!module || !rocContext[module]) {
return request;
}

return request;
const newRequest = rocContext[module].resolve ?
rocContext[module].resolve({
module,
request,
requestContext: context,
extensionContext: rocContext[module].context,
}) : resolve.sync(request, { basedir: rocContext[module].context });

log(`(${identifier}) : Found an alias for [${module}] => [${newRequest}]`);

return newRequest || request;
};

return (request, context, fallback = false) => {
Expand Down