const utils = require('./utils');
|
|
const scopedModuleRegex = new RegExp(
|
'@[a-zA-Z0-9][\\w-.]+/[a-zA-Z0-9][\\w-.]+([a-zA-Z0-9./]+)?',
|
'g'
|
);
|
|
function getModuleName(request, includeAbsolutePaths) {
|
let req = request;
|
const delimiter = '/';
|
|
if (includeAbsolutePaths) {
|
req = req.replace(/^.*?\/node_modules\//, '');
|
}
|
// check if scoped module
|
if (scopedModuleRegex.test(req)) {
|
// reset regexp
|
scopedModuleRegex.lastIndex = 0;
|
return req.split(delimiter, 2).join(delimiter);
|
}
|
return req.split(delimiter)[0];
|
}
|
|
module.exports = function nodeExternals(options) {
|
options = options || {};
|
const mistakes = utils.validateOptions(options) || [];
|
if (mistakes.length) {
|
mistakes.forEach((mistake) => {
|
utils.error(mistakes.map((mistake) => mistake.message));
|
utils.log(mistake.message);
|
});
|
}
|
const webpackInternalAllowlist = [/^webpack\/container\/reference\//];
|
const allowlist = []
|
.concat(webpackInternalAllowlist)
|
.concat(options.allowlist || []);
|
const binaryDirs = [].concat(options.binaryDirs || ['.bin']);
|
const importType = options.importType || 'commonjs';
|
const modulesDir = options.modulesDir || 'node_modules';
|
const modulesFromFile = !!options.modulesFromFile;
|
const includeAbsolutePaths = !!options.includeAbsolutePaths;
|
const additionalModuleDirs = options.additionalModuleDirs || [];
|
|
// helper function
|
function isNotBinary(x) {
|
return !utils.contains(binaryDirs, x);
|
}
|
|
// create the node modules list
|
let nodeModules = modulesFromFile
|
? utils.readFromPackageJson(options.modulesFromFile)
|
: utils.readDir(modulesDir).filter(isNotBinary);
|
additionalModuleDirs.forEach(function (additionalDirectory) {
|
nodeModules = nodeModules.concat(
|
utils.readDir(additionalDirectory).filter(isNotBinary)
|
);
|
});
|
|
// return an externals function
|
return function (...args) {
|
const [arg1, arg2, arg3] = args;
|
// let context = arg1;
|
let request = arg2;
|
let callback = arg3;
|
// in case of webpack 5
|
if (arg1 && arg1.context && arg1.request) {
|
// context = arg1.context;
|
request = arg1.request;
|
callback = arg2;
|
}
|
const moduleName = getModuleName(request, includeAbsolutePaths);
|
if (
|
utils.contains(nodeModules, moduleName) &&
|
!utils.containsPattern(allowlist, request)
|
) {
|
if (typeof importType === 'function') {
|
return callback(null, importType(request));
|
}
|
// mark this module as external
|
// https://webpack.js.org/configuration/externals/
|
return callback(null, importType + ' ' + request);
|
}
|
callback();
|
};
|
};
|