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

Fix custom webpack config warnings #4009

Merged
merged 4 commits into from
Aug 15, 2018
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.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
9 changes: 9 additions & 0 deletions lib/core/src/server/config/interpret-files.js
Original file line number Diff line number Diff line change
Expand Up @@ -19,3 +19,12 @@ export function getInterpretedFile(pathToFile) {
.map(ext => `${pathToFile}${ext}`)
.find(candidate => fs.existsSync(candidate));
}

export function getInterpretedFileWithExt(pathToFile) {
return possibleExtensions
.map(ext => ({
path: `${pathToFile}${ext}`,
ext,
}))
.find(candidate => fs.existsSync(candidate.path));
}
88 changes: 4 additions & 84 deletions lib/core/src/server/loadCustomWebpackConfig.js
Original file line number Diff line number Diff line change
@@ -1,87 +1,7 @@
/* eslint-disable global-require, import/no-dynamic-require */
import fs from 'fs';
import path from 'path';
import interpret from 'interpret';
import { logger } from '@storybook/node-logger';
import serverRequire from './serverRequire';

// Copied and modified from
// https://github.com/webpack/webpack-cli/blob/ca504de8c7c0ea66278021b72fa6a953e3ffa43c/bin/convert-argv.js#L102-L119
function registerCompiler(moduleDescriptor) {
if (!moduleDescriptor) {
return 0;
}
const webpackConfigs = ['webpack.config', 'webpackfile'];

if (typeof moduleDescriptor === 'string') {
require(moduleDescriptor);
return 1;
}

if (!Array.isArray(moduleDescriptor)) {
moduleDescriptor.register(require(moduleDescriptor.module));
return 1;
}

let registered = 0;

for (let i = 0; i < moduleDescriptor.length; i += 1) {
try {
registered += registerCompiler(moduleDescriptor[i]);
break;
} catch (e) {
// do nothing
}
}

return registered;
}

// Copied and modified from
// https://github.com/webpack/webpack-cli/blob/ca504de8c7c0ea66278021b72fa6a953e3ffa43c/bin/convert-argv.js#L121-L137
function requireConfig(configPath) {
const config = require(configPath);

const isES6DefaultExported =
typeof config === 'object' && config !== null && typeof config.default !== 'undefined';

return isES6DefaultExported ? config.default : config;
}

// Copied and modified from
// https://github.com/webpack/webpack-cli/blob/ca504de8c7c0ea66278021b72fa6a953e3ffa43c/bin/convert-argv.js#L45-L143
export default configDir => {
const extensions = Object.keys(interpret.extensions).sort((a, b) => {
if (a === '.js') {
return -1;
}
if (b === '.js') {
return 1;
}
return a.length - b.length;
});

const customConfigCandidates = ['webpack.config', 'webpackfile']
.map(filename =>
extensions.map(ext => ({
path: path.resolve(configDir, filename + ext),
ext,
}))
)
.reduce((a, i) => a.concat(i), []);

for (let i = 0; i < customConfigCandidates.length; i += 1) {
const customConfigPath = customConfigCandidates[i].path;
if (fs.existsSync(customConfigPath)) {
if (registerCompiler(interpret.extensions[customConfigCandidates[i].ext]) === 0) {
logger.warn(`=> Custom configuration file ${customConfigPath} is detected`);
logger.warn(` but impossible to import loader for ${customConfigCandidates[i].ext}`);
}
try {
return requireConfig(customConfigPath);
} catch (e) {
// do nothing
}
}
}

return null;
};
export default configDir =>
serverRequire(webpackConfigs.map(configName => path.resolve(configDir, configName)));
95 changes: 95 additions & 0 deletions lib/core/src/server/serverRequire.js
Original file line number Diff line number Diff line change
@@ -0,0 +1,95 @@
import interpret from 'interpret';
import { logger } from '@storybook/node-logger';
import { getInterpretedFileWithExt } from './config/interpret-files';

// The code based on https://github.com/webpack/webpack-cli/blob/ca504de8c7c0ea66278021b72fa6a953e3ffa43c/bin/convert-argv

const compilersState = new Map();

function registerCompiler(moduleDescriptor) {
if (!moduleDescriptor) {
return 0;
}

const state = compilersState.get(moduleDescriptor);

if (state !== undefined) {
return state;
}

if (typeof moduleDescriptor === 'string') {
// eslint-disable-next-line import/no-dynamic-require,global-require
require(moduleDescriptor);
compilersState.set(moduleDescriptor, 1);
return 1;
}

if (!Array.isArray(moduleDescriptor)) {
// eslint-disable-next-line import/no-dynamic-require,global-require
moduleDescriptor.register(require(moduleDescriptor.module));
compilersState.set(moduleDescriptor, 1);
return 1;
}

let registered = 0;

for (let i = 0; i < moduleDescriptor.length; i += 1) {
try {
registered += registerCompiler(moduleDescriptor[i]);
break;
} catch (e) {
// do nothing
}
}

compilersState.set(moduleDescriptor, registered);
return registered;
}

function interopRequireDefault(filePath) {
// eslint-disable-next-line import/no-dynamic-require,global-require
const result = require(filePath);

const isES6DefaultExported =
typeof result === 'object' && result !== null && typeof result.default !== 'undefined';

return isES6DefaultExported ? result.default : result;
}

function getCandidate(paths) {
for (let i = 0; i < paths.length - 1; i += 1) {
const candidate = getInterpretedFileWithExt(paths[i]);

if (candidate) {
return candidate;
}
}

return undefined;
}

export default function serverRequire(filePath) {
const paths = Array.isArray(filePath) ? filePath : [filePath];
const existingCandidate = getCandidate(paths);

if (!existingCandidate) {
return null;
}

const { path: candidatePath, ext: candidateExt } = existingCandidate;

if (candidateExt === '.js') {
return interopRequireDefault(candidatePath);
}

const moduleDescriptor = interpret.extensions[candidateExt];

if (registerCompiler(moduleDescriptor) === 0) {
logger.warn(`=> File ${candidatePath} is detected`);
logger.warn(` but impossible to import loader for ${candidateExt}`);

return null;
}

return interopRequireDefault(candidatePath);
}