Skip to content
This repository was archived by the owner on Sep 12, 2019. It is now read-only.

Commit f6fbb9c

Browse files
author
sw-yx
committed
add finders.js
1 parent 27da118 commit f6fbb9c

File tree

2 files changed

+194
-4
lines changed

2 files changed

+194
-4
lines changed

src/utils/finders.js

+189
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,189 @@
1+
const path = require("path");
2+
const fs = require("fs");
3+
const packList = require("npm-packlist");
4+
const precinct = require("precinct");
5+
const resolve = require("resolve");
6+
const readPkgUp = require("read-pkg-up");
7+
const requirePackageName = require("require-package-name");
8+
const alwaysIgnored = new Set(["aws-sdk"]);
9+
const debug = require("debug")("@netlify/zip-it-and-ship-it:finders");
10+
11+
const ignoredExtensions = new Set([
12+
".log",
13+
".lock",
14+
".html",
15+
".md",
16+
".map",
17+
".ts",
18+
".png",
19+
".jpeg",
20+
".jpg",
21+
".gif",
22+
".css",
23+
".patch"
24+
]);
25+
26+
function ignoreMissing(dependency, optional) {
27+
return alwaysIgnored.has(dependency) || (optional && dependency in optional);
28+
}
29+
30+
function includeModuleFile(packageJson, moduleFilePath) {
31+
if (packageJson.files) {
32+
return true;
33+
}
34+
35+
return !ignoredExtensions.has(path.extname(moduleFilePath));
36+
}
37+
38+
function getDependencies(filename, basedir) {
39+
const servicePath = basedir;
40+
41+
const filePaths = new Set();
42+
const modulePaths = new Set();
43+
const pkgs = {};
44+
45+
const modulesToProcess = [];
46+
const localFilesToProcess = [filename];
47+
48+
function handle(name, basedir, optionalDependencies) {
49+
const moduleName = requirePackageName(name.replace(/\\/, "/"));
50+
51+
if (alwaysIgnored.has(moduleName)) {
52+
return;
53+
}
54+
55+
try {
56+
const pathToModule = resolve.sync(path.join(moduleName, "package.json"), {
57+
basedir
58+
});
59+
const pkg = readPkgUp.sync({ cwd: pathToModule });
60+
61+
if (pkg) {
62+
modulesToProcess.push(pkg);
63+
}
64+
} catch (e) {
65+
if (e.code === "MODULE_NOT_FOUND") {
66+
if (ignoreMissing(moduleName, optionalDependencies)) {
67+
debug(`WARNING missing optional dependency: ${moduleName}`);
68+
return null;
69+
}
70+
try {
71+
// this resolves the requested import also against any set up NODE_PATH extensions, etc.
72+
const resolved = require.resolve(name);
73+
localFilesToProcess.push(resolved);
74+
return;
75+
} catch (e) {
76+
throw new Error(`Could not find "${moduleName}" module in file: ${filename.replace(
77+
path.dirname(basedir),
78+
""
79+
)}.
80+
81+
Please ensure "${moduleName}" is installed in the project.`);
82+
}
83+
}
84+
throw e;
85+
}
86+
}
87+
88+
while (localFilesToProcess.length) {
89+
const currentLocalFile = localFilesToProcess.pop();
90+
91+
if (filePaths.has(currentLocalFile)) {
92+
continue;
93+
}
94+
95+
filePaths.add(currentLocalFile);
96+
precinct
97+
.paperwork(currentLocalFile, { includeCore: false })
98+
.forEach(dependency => {
99+
if (dependency.indexOf(".") === 0) {
100+
const abs = resolve.sync(dependency, {
101+
basedir: path.dirname(currentLocalFile)
102+
});
103+
localFilesToProcess.push(abs);
104+
} else {
105+
handle(dependency, servicePath);
106+
}
107+
});
108+
}
109+
110+
while (modulesToProcess.length) {
111+
const currentModule = modulesToProcess.pop();
112+
const currentModulePath = path.join(currentModule.path, "..");
113+
const packageJson = currentModule.pkg;
114+
115+
if (modulePaths.has(currentModulePath)) {
116+
continue;
117+
}
118+
modulePaths.add(currentModulePath);
119+
pkgs[currentModulePath] = packageJson;
120+
["dependencies", "peerDependencies", "optionalDependencies"].forEach(
121+
key => {
122+
const dependencies = packageJson[key];
123+
124+
if (dependencies) {
125+
Object.keys(dependencies).forEach(dependency => {
126+
handle(
127+
dependency,
128+
currentModulePath,
129+
packageJson.optionalDependencies
130+
);
131+
});
132+
}
133+
}
134+
);
135+
}
136+
137+
modulePaths.forEach(modulePath => {
138+
const packageJson = pkgs[modulePath];
139+
let moduleFilePaths;
140+
141+
moduleFilePaths = packList.sync({ path: modulePath });
142+
143+
moduleFilePaths.forEach(moduleFilePath => {
144+
if (includeModuleFile(packageJson, moduleFilePath)) {
145+
filePaths.add(path.join(modulePath, moduleFilePath));
146+
}
147+
});
148+
});
149+
150+
// TODO: get rid of this
151+
const sizes = {};
152+
filePaths.forEach(filepath => {
153+
const stat = fs.lstatSync(filepath);
154+
const ext = path.extname(filepath);
155+
sizes[ext] = (sizes[ext] || 0) + stat.size;
156+
});
157+
debug("Sizes per extension: ", sizes);
158+
159+
return Array.from(filePaths);
160+
}
161+
162+
function findModuleDir(dir) {
163+
let basedir = dir;
164+
while (!fs.existsSync(path.join(basedir, "package.json"))) {
165+
const newBasedir = path.dirname(basedir);
166+
if (newBasedir === basedir) {
167+
return null;
168+
}
169+
basedir = newBasedir;
170+
}
171+
return basedir;
172+
}
173+
174+
function findHandler(functionPath) {
175+
if (fs.lstatSync(functionPath).isFile()) {
176+
return functionPath;
177+
}
178+
179+
const handlerPath = path.join(
180+
functionPath,
181+
`${path.basename(functionPath)}.js`
182+
);
183+
if (!fs.existsSync(handlerPath)) {
184+
return;
185+
}
186+
return handlerPath;
187+
}
188+
189+
module.exports = { getDependencies, findModuleDir, findHandler };

src/utils/serveFunctions.js

+5-4
Original file line numberDiff line numberDiff line change
@@ -7,10 +7,11 @@ const path = require("path");
77
const getPort = require("get-port");
88
const chokidar = require("chokidar");
99
const chalk = require("chalk");
10-
11-
const NETLIFYDEVLOG = `${chalk.greenBright("◈")}`;
12-
const NETLIFYDEVWARN = `${chalk.yellowBright("◈")}`;
13-
const NETLIFYDEVERR = `${chalk.redBright("◈")}`;
10+
const {
11+
NETLIFYDEVLOG,
12+
NETLIFYDEVWARN,
13+
NETLIFYDEVERR
14+
} = require("netlify-cli-logo");
1415

1516
const { findModuleDir, findHandler } = require("./finders");
1617

0 commit comments

Comments
 (0)