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: resolve packages entrypoints and paths with extensions #1370

Closed
wants to merge 1 commit into from
Closed
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
1 change: 1 addition & 0 deletions packages/razzle-dev-utils/package.json
Expand Up @@ -20,6 +20,7 @@
"chalk": "3.0.0",
"jest-message-util": "^24.9.0",
"react-dev-utils": "^10.2.0",
"resolve": "1.17.0",
"strip-ansi": "6.0.0"
}
}
12 changes: 12 additions & 0 deletions packages/razzle-dev-utils/resolveRequest.js
@@ -0,0 +1,12 @@
const resolve = require('resolve');
const path = require('path');

function resolveRequest(req, issuer) {
const basedir =
issuer.endsWith(path.posix.sep) || issuer.endsWith(path.win32.sep)
? issuer
: path.dirname(issuer);
return resolve.sync(req, { basedir });
};

module.exports = resolveRequest;
96 changes: 85 additions & 11 deletions packages/razzle/config/createConfigAsync.js
Expand Up @@ -19,6 +19,7 @@ const WebpackBar = require('webpackbar');
const ManifestPlugin = require('webpack-manifest-plugin');
const modules = require('./modules');
const postcssLoadConfig = require('postcss-load-config');
const resolveRequest = require('razzle-dev-utils/resolveRequest');
const logger = require('razzle-dev-utils/logger');
const razzlePaths = require('razzle/config/paths');
const getCacheIdentifier = require('react-dev-utils/getCacheIdentifier');
Expand Down Expand Up @@ -138,6 +139,89 @@ module.exports = (
const additionalAliases = modulesConfig.additionalAliases || {};
const additionalIncludes = modulesConfig.additionalIncludes || [];

const nodeExternalsFunc = experimental.newExternals ?
(context, request, callback) => {

if ((experimental.newExternals.notExternalModules || []).indexOf(request) !== -1) {
return callback()
}

const isLocal =
request.startsWith('.') ||
// Always check for unix-style path, as webpack sometimes
// normalizes as posix.
path.posix.isAbsolute(request) ||
// When on Windows, we also want to check for Windows-specific
// absolute paths.
(process.platform === 'win32' && path.win32.isAbsolute(request))

// Relative requires don't need custom resolution, because they
// are relative to requests we've already resolved here.
// Absolute requires (require('/foo')) are extremely uncommon, but
// also have no need for customization as they're already resolved.
if (isLocal) {
return callback()
}

let res;
try {
res = resolveRequest(request, `${context}/`)
} catch (err) {
// If the request cannot be resolved, we need to tell webpack to
// "bundle" it so that webpack shows an error (that it cannot be
// resolved).
return callback();
}
// Same as above, if the request cannot be resolved we need to have
// webpack "bundle" it so it surfaces the not found error.
if (!res) {
return callback()
}
// This means we need to make sure its request resolves to the same
// package that'll be available at runtime. If it's not identical,
// we need to bundle the code (even if it _should_ be external).
let baseRes = null;
try {
baseRes = resolveRequest(request, `${paths.appPath}/`)
} catch (err) {
baseRes = null
}

// Same as above: if the package, when required from the root,
// would be different from what the real resolution would use, we
// cannot externalize it.
if (baseRes !== res) {
return callback()
}
// Anything else that is standard JavaScript within `node_modules`
// can be externalized.
if (res.match(/node_modules[/\\].*\.js$/)) {
const externalRequest =
path.posix.join(
paths.appPath,
path
.relative(
paths.appPath,
res
)
// Windows path normalization
.replace(/\\/g, '/')
)
return callback(undefined, `commonjs ${externalRequest}`)
}

// Default behavior: bundle the code!
return callback()
} : nodeExternals({
whitelist: [
IS_DEV ? 'webpack/hot/poll?300' : null,
/\.(eot|woff|woff2|ttf|otf)$/,
/\.(svg|png|jpg|jpeg|gif|ico)$/,
/\.(mp4|mp3|ogg|swf|webp)$/,
/\.(css|scss|sass|sss|less)$/,
].filter(x => x),
});

// This is our base webpack config.
let config = {
// Set webpack mode:
Expand Down Expand Up @@ -296,17 +380,7 @@ module.exports = (
};

// We need to tell webpack what to bundle into our Node bundle.
config.externals = [
nodeExternals({
whitelist: [
IS_DEV ? 'webpack/hot/poll?300' : null,
/\.(eot|woff|woff2|ttf|otf)$/,
/\.(svg|png|jpg|jpeg|gif|ico)$/,
/\.(mp4|mp3|ogg|swf|webp)$/,
/\.(css|scss|sass|sss|less)$/,
].filter(x => x),
}),
];
config.externals = [nodeExternalsFunc];

// Specify webpack Node.js output path and filename
config.output = {
Expand Down
2 changes: 1 addition & 1 deletion yarn.lock
Expand Up @@ -14926,7 +14926,7 @@ resolve@1.1.7:
resolved "https://registry.yarnpkg.com/resolve/-/resolve-1.1.7.tgz#203114d82ad2c5ed9e8e0411b3932875e889e97b"
integrity sha1-IDEU2CrSxe2ejgQRs5ModeiJ6Xs=

resolve@^1.1.6, resolve@^1.10.0, resolve@^1.12.0, resolve@^1.13.1, resolve@^1.15.1, resolve@^1.17.0, resolve@^1.3.2, resolve@^1.8.1:
resolve@1.17.0, resolve@^1.1.6, resolve@^1.10.0, resolve@^1.12.0, resolve@^1.13.1, resolve@^1.15.1, resolve@^1.17.0, resolve@^1.3.2, resolve@^1.8.1:
version "1.17.0"
resolved "https://registry.yarnpkg.com/resolve/-/resolve-1.17.0.tgz#b25941b54968231cc2d1bb76a79cb7f2c0bf8444"
integrity sha512-ic+7JYiV8Vi2yzQGFWOkiZD5Z9z7O2Zhm9XMaTxdJExKasieFCr+yXZ/WmXsckHiKl12ar0y6XiXDx3m4RHn1w==
Expand Down