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(); }; };