Skip to content

Commit

Permalink
rework externals for perf (#176)
Browse files Browse the repository at this point in the history
  • Loading branch information
guybedford authored and rauchg committed Dec 19, 2018
1 parent 6aa2c4c commit 132bda3
Show file tree
Hide file tree
Showing 2 changed files with 34 additions and 34 deletions.
62 changes: 30 additions & 32 deletions src/index.js
Expand Up @@ -8,6 +8,9 @@ const terser = require("terser");
const tsconfigPaths = require("tsconfig-paths");
const TsconfigPathsPlugin = require("tsconfig-paths-webpack-plugin");
const shebangRegEx = require('./utils/shebang');
const { pkgNameRegEx } = require("./utils/get-package-base");

const nodeBuiltins = new Set([...require("repl")._builtinLibs, "constants", "module", "timers", "console", "_stream_writable", "_stream_readable", "_stream_duplex"]);

// overload the webpack parser so that we can make
// acorn work with the node.js / commonjs semantics
Expand All @@ -21,37 +24,7 @@ WebpackParser.parse = function(source, opts = {}) {
});
};

const SUPPORTED_EXTENSIONS = [".ts", ".tsx", ".js", ".mjs", ".json", ".node"];

function resolveModule(matchPath, context, request, callback, forcedExternals = []) {
const resolveOptions = {
basedir: context,
preserveSymlinks: true,
extensions: SUPPORTED_EXTENSIONS
};

if (new Set(forcedExternals).has(request)) {
console.error(`ncc: Skipping bundling "${request}" per config`);
return callback(null, `commonjs ${request}`);
}

resolve(request, resolveOptions, err => {
if (err) {
// check tsconfig paths before erroring
if (matchPath && matchPath(request, undefined, undefined, SUPPORTED_EXTENSIONS)) {
callback();
return;
}

console.error(
`ncc: Module directory "${context}" attempted to require "${request}" but could not be resolved, assuming external.`
);
return callback(null, `commonjs ${request}`);
}

callback();
});
}
const SUPPORTED_EXTENSIONS = [".js", ".json", ".node", ".mjs", ".ts", ".tsx"];

module.exports = async (
entry,
Expand Down Expand Up @@ -80,6 +53,8 @@ module.exports = async (
}
} catch (e) {}

const externalSet = new Set(externals);

const compiler = webpack({
entry,
optimization: {
Expand All @@ -103,7 +78,30 @@ module.exports = async (
},
// https://github.com/zeit/ncc/pull/29#pullrequestreview-177152175
node: false,
externals: (...args) => resolveModule(tsconfigMatchPath, ...[...args, externals]),
externals: async (context, request, callback) => {
if (externalSet.has(request)) return callback(null, `commonjs ${request}`);
if (request[0] === "." && (request[1] === "/" || request[1] === "." && request[2] === "/")) {
if (request.startsWith("./node_modules/")) request = request.substr(15);
else if (request.startsWith("../node_modules/")) request = request.substr(16);
else return callback();
}
if (request[0] === "/" || nodeBuiltins.has(request) ||
tsconfigMatchPath && tsconfigMatchPath(request, undefined, undefined, SUPPORTED_EXTENSIONS))
return callback();
const pkgNameMatch = request.match(pkgNameRegEx);
if (pkgNameMatch) request = pkgNameMatch[0];
let pkgPath = context + '/node_modules/' + request;
do {
if (await new Promise((resolve, reject) =>
fs.stat(pkgPath, (err, stats) =>
err && err.code !== 'ENOENT' ? reject(err) : resolve(stats ? stats.isDirectory() : false)
)
))
return callback();
} while (pkgPath.length > (pkgPath = pkgPath.substr(0, pkgPath.lastIndexOf('/', pkgPath.length - 15 - request.length)) + '/node_modules/' + request).length);
console.error(`ncc: Module directory "${context}" attempted to require "${request}" but could not be resolved, assuming external.`);
return callback(null, `commonjs ${request}`);
},
module: {
rules: [
{
Expand Down
6 changes: 4 additions & 2 deletions src/utils/get-package-base.js
@@ -1,6 +1,6 @@
// returns the base-level package folder based on detecting "node_modules"
// package name boundaries
const pkgNameRegEx = /(@[^\\\/]+[\\\/])?[^\\\/]+/;
const pkgNameRegEx = /^(@[^\\\/]+[\\\/])?[^\\\/]+/;
module.exports = function (id) {
const pkgIndex = id.lastIndexOf('node_modules');
if (pkgIndex !== -1 &&
Expand All @@ -10,4 +10,6 @@ module.exports = function (id) {
if (pkgNameMatch)
return id.substr(0, pkgIndex + 13 + pkgNameMatch[0].length);
}
};
};

module.exports.pkgNameRegEx = pkgNameRegEx;

0 comments on commit 132bda3

Please sign in to comment.