-
Notifications
You must be signed in to change notification settings - Fork 412
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
Support NPM 8 #1083
Comments
I managed to find missing deps by running this script: const { spawn } = require('child_process');
const { readFileSync } = require('fs');
const { satisfies } = require('semver');
function spawnProcess(command, args, options) {
return new Promise((resolve, reject) => {
const child = spawn(command, args, options);
let stdout = '';
let stderr = '';
// Configure stream encodings
child.stdout.setEncoding('utf8');
child.stderr.setEncoding('utf8');
// Listen to stream events
child.stdout.on('data', (data) => {
stdout += data;
});
child.stderr.on('data', (data) => {
stderr += data;
});
child.on('error', (err) => {
reject(err);
});
child.on('close', (exitCode) => {
if (exitCode !== 0 || stderr.length > 0) {
reject(new Error(`${command} ${args.join(' ')} failed with code ${exitCode}:\n========== STD OUT ==========\n${stdout}\n========== STD ERR ==========\n${stderr}`, stdout, stderr));
} else {
resolve(stdout);
}
});
});
}
async function getDependencyGraph(pkg) {
const out = await spawnProcess('npm', ['ls', '-a', '--json', '-prod', '--package-lock-only', '-w', pkg]);
return JSON.parse(out);
}
function isResolved(module) {
return Boolean(module?.resolved);
}
function findDepModules(graph, pkg, version) {
const deps = Object.keys(graph.dependencies);
if (isResolved(graph.dependencies?.[pkg]) && graph.dependencies[pkg].version === version) {
return graph.dependencies[pkg].dependencies ?? {};
}
for (const dep of deps) {
if (graph.dependencies[dep].dependencies) {
const found = findDepModules(graph.dependencies[dep], pkg, version);
if (found) {
return found;
}
}
}
return {};
}
function getRequiredDeps(graph, pkg, version) {
const required = [];
const depModules = findDepModules(graph, pkg, version);
const deps = Object.keys(depModules);
for (const dep of deps) {
if (dep.startsWith('@nugit/')) {
required.push(...getRequiredDeps(graph, dep, depModules[dep].version));
} else {
required.push(`${dep}@${depModules[dep].version}`);
}
}
return required;
}
async function ensurePeerDepsAreInstalled(packagePath) {
const missing = new Set();
const pckJson = JSON.parse(readFileSync(packagePath, 'utf8'));
const graph = await getDependencyGraph(pckJson.name);
const deps = getRequiredDeps(graph, pckJson.name, pckJson.version);
for (const dep of deps) {
const parts = dep.split('@');
const pkg = parts.slice(0, -1).join('@');
const version = parts[parts.length - 1];
const constraint = pckJson.devDependencies?.[pkg]
?? pckJson.dependencies?.[pkg];
if (constraint === null) {
missing.add(`${pkg}@^${version}`);
} else if (!satisfies(version, constraint)) {
throw new Error(`Peer dependency ${dep} does not match version in package.json ${constraint}`);
}
}
if (missing.size > 0) {
const command = `npm install --save -w ${pckJson.name} ${Array.from(missing).join(' ')}`;
throw new Error(`Could not find peer dependency in package.json for ${Array.from(missing).join(' ')}. You can run ${command} to install them.`);
}
}
ensurePeerDepsAreInstalled('./packages/api/package.json'); |
FYI, npm8 broke serverless-webpack compilation, at our corporate office, we're being forced to move away from webpack to esbuild because of the lack of urgency on fixing this issue. Moroine has put out a fix that I've tested and works, I would urge the serverless team be more vigilant on this bug. |
FYI, it seems more easy to revert to NPM7 instead of rewrote your build system using esbuild. |
@paroxysm it's almost ready. I'm working on unit tests... Starting to go crazy on this, I've migrated to |
True, however we are using a base set of images that are opinionated on npm8 ,coming from the architects(I would've loved to switch back to npm7). We couldn't control getting this fix merged sooner, but we can control migrating to esbuild to unblock our deployments.... |
Or you can use |
We're looking into publishing that package into our private npm repo for the time being. It would be 1 of two solutions |
|
ty! This should help some of the teams that are still behind on migration! |
This is a Bug Report
Description
With NPM 8, peer-dependencies are now automatically installed. We decided to move to NPM 8, because we found it easier to manage peer-dependencies.
Unfortunately,
serverless-webpack
will not find peer-dependencies. I try to take a look at the implementation, and I found some potentials:packExternalModules
we could try to find the installed module version recursively (with NPM 8, peer-dependency cannot conflict by default).webpack
stat data, to find the modulepath
on disk then look for installed versionCurrently, I'm facing
warning
, and because it uses""
as the default version when not found it leads to invalid generatedpackage.json
.Here is the generated
package.json
:Additional Data
The text was updated successfully, but these errors were encountered: