Skip to content
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

CLI: Improve webpack version and add detection of nextjs #18220

Merged
merged 2 commits into from
May 18, 2022
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Jump to
Jump to file
Failed to load files.
Diff view
Diff view
53 changes: 53 additions & 0 deletions lib/cli/src/detect-nextjs.test.ts
Original file line number Diff line number Diff line change
@@ -0,0 +1,53 @@
import { detectNextJS } from './detect-nextjs';

test('detect nothing if it fails', () => {
const out = detectNextJS({
type: 'npm',
executeCommand: () => {
throw new Error('test error');
},
});
expect(out).toEqual(false);
});

test('detect from npm ls', () => {
const outputFromCommand = `
/path/to/cwd
└── next@12.0.7
`;
const out = detectNextJS({ type: 'npm', executeCommand: () => outputFromCommand });
expect(out).toEqual(12);
});

test('detect from npm why', () => {
const outputFromCommand = `
next@12.0.7
node_modules/next
next@"^12.0.7" from the root project
peer next@">=10.2.0" from eslint-config-next@12.0.7
node_modules/eslint-config-next
dev eslint-config-next@"^12.0.7" from the root project
`;
const out = detectNextJS({ type: 'npm', executeCommand: () => outputFromCommand });
expect(out).toEqual(12);
});

test('detect from yarn why', () => {
const outputFromCommand = `
yarn why v1.22.18
[1/4] 🤔 Why do we have the module "next"...?
[2/4] 🚚 Initialising dependency graph...
[3/4] 🔍 Finding dependency...
[4/4] 🚡 Calculating file sizes...
=> Found "next@12.0.7"
info Has been hoisted to "next"
info This module exists because it's specified in "dependencies".
info Disk size without dependencies: "XX.XXMB"
info Disk size with unique dependencies: "XX.XXMB"
info Disk size with transitive dependencies: "XX.XXMB"
info Number of shared dependencies: XXX
✨ Done in 0.XXs.
`;
const out = detectNextJS({ type: 'npm', executeCommand: () => outputFromCommand });
expect(out).toEqual(12);
});
30 changes: 30 additions & 0 deletions lib/cli/src/detect-nextjs.ts
Original file line number Diff line number Diff line change
@@ -0,0 +1,30 @@
import { JsPackageManager } from './js-package-manager';

const regex = /[\s"\n]next.*?(\d+).*/;

export const detectNextJS = (
packageManager: Pick<JsPackageManager, 'type' | 'executeCommand'>
): number | false => {
try {
let out = '';
if (packageManager.type === 'npm') {
try {
// npm <= v7
out = packageManager.executeCommand('npm', ['ls', 'next']);
} catch (e2) {
// npm >= v8
out = packageManager.executeCommand('npm', ['why', 'next']);
}
} else {
out = packageManager.executeCommand('yarn', ['why', 'next']);
}

const [, version] = out.match(regex);

return version && parseInt(version, 10) ? parseInt(version, 10) : false;
} catch (err) {
//
}

return false;
};
32 changes: 32 additions & 0 deletions lib/cli/src/detect-webpack.ts
Original file line number Diff line number Diff line change
@@ -0,0 +1,32 @@
import type { JsPackageManager } from './js-package-manager';

export const detectWebpack = (packageManager: JsPackageManager): number | false => {
try {
let out = '';
if (packageManager.type === 'npm') {
try {
// npm <= v7
out = packageManager.executeCommand('npm', ['ls', 'webpack']);
} catch (e2) {
// npm >= v8
out = packageManager.executeCommand('npm', ['why', 'webpack']);
}
} else {
out = packageManager.executeCommand('yarn', ['why', 'webpack']);
}

// if the user has BOTH webpack 4 and 5 installed already, we'll pick the safest options (4)
if (out.includes('webpack@4') || out.includes('webpack@npm:4')) {
return 4;
}

// the user has webpack 4 installed, but not 5
if (out.includes('webpack@5') || out.includes('webpack@npm:5')) {
return 5;
}
} catch (err) {
//
}

return false;
};
32 changes: 12 additions & 20 deletions lib/cli/src/detect.ts
Original file line number Diff line number Diff line change
Expand Up @@ -14,6 +14,8 @@ import {
} from './project_types';
import { getBowerJson, paddedLog } from './helpers';
import { PackageJson, readPackageJson, JsPackageManager } from './js-package-manager';
import { detectWebpack } from './detect-webpack';
import { detectNextJS } from './detect-nextjs';

const viteConfigFiles = ['vite.config.ts', 'vite.config.js', 'vite.config.mjs'];

Expand Down Expand Up @@ -112,31 +114,21 @@ export function detectBuilder(packageManager: JsPackageManager) {
return CoreBuilder.Vite;
}

try {
let out = '';
if (packageManager.type === 'npm') {
try {
// npm <= v7
out = packageManager.executeCommand('npm', ['ls', 'webpack']);
} catch (e2) {
// npm >= v8
out = packageManager.executeCommand('npm', ['why', 'webpack']);
}
} else {
out = packageManager.executeCommand('yarn', ['why', 'webpack']);
}

// if the user has BOTH webpack 4 and 5 installed already, we'll pick the safest options (4)
if (out.includes('webpack@4') || out.includes('webpack@npm:4')) {
const nextJSVersion = detectNextJS(packageManager);
if (nextJSVersion) {
if (nextJSVersion >= 11) {
return CoreBuilder.Webpack5;
}
}

// the user has webpack 4 installed, but not 5
if (out.includes('webpack@5') || out.includes('webpack@npm:5')) {
const webpackVersion = detectWebpack(packageManager);
yannbf marked this conversation as resolved.
Show resolved Hide resolved
if (webpackVersion) {
if (webpackVersion <= 4) {
return CoreBuilder.Webpack4;
}
if (webpackVersion >= 5) {
return CoreBuilder.Webpack5;
}
} catch (err) {
//
}

// Fallback to webpack4
Expand Down