Skip to content

Commit eeec616

Browse files
committed
feature #291 Recommend a different command for missing loaders based on the presence of yarn/npm lock files (Lyrkan)
This PR was merged into the master branch. Discussion ---------- Recommend a different command for missing loaders based on the presence of yarn/npm lock files This PR implements #288 by checking which kind of lock files are in the current directory before recommending the user a command to add missing loaders, for instance: * No lock file: `yarn add <packages> --dev` * yarn.lock: `yarn add <packages> --dev` * package-lock.json: `npm install <packages> --save-dev` * yarn.lock and packages-lock.json: `yarn add <packages> --dev` Note that it doesn't fix #57 since that error message is currently only handled by `friendly-errors-webpack-plugin`. Commits ------- f65bffa Recommend a different command for missing packages based on the presence of yarn/npm lock files
2 parents ccbae35 + f65bffa commit eeec616

File tree

8 files changed

+79
-4
lines changed

8 files changed

+79
-4
lines changed

fixtures/package-helper/empty/.gitkeep

Whitespace-only changes.

fixtures/package-helper/npm/package-lock.json

Lines changed: 5 additions & 0 deletions
Some generated files are not rendered by default. Learn more about customizing how changed files appear on GitHub.

fixtures/package-helper/yarn-npm/package-lock.json

Lines changed: 5 additions & 0 deletions
Some generated files are not rendered by default. Learn more about customizing how changed files appear on GitHub.
Lines changed: 2 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,2 @@
1+
# THIS IS AN AUTOGENERATED FILE. DO NOT EDIT THIS FILE DIRECTLY.
2+
# yarn lockfile v1
Lines changed: 2 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,2 @@
1+
# THIS IS AN AUTOGENERATED FILE. DO NOT EDIT THIS FILE DIRECTLY.
2+
# yarn lockfile v1

lib/friendly-errors/formatters/missing-loader.js

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -32,7 +32,7 @@ function formatErrors(errors) {
3232
);
3333

3434
if (packageRecommendations) {
35-
fixes.push(`${packageRecommendations.message}\n ${packageRecommendations.yarnInstall}`);
35+
fixes.push(`${packageRecommendations.message}\n ${packageRecommendations.installCommand}`);
3636
}
3737
} else {
3838
fixes.push('You may need to install and configure a special loader for this file type.');

lib/package-helper.js

Lines changed: 15 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -10,6 +10,7 @@
1010
'use strict';
1111

1212
const chalk = require('chalk');
13+
const fs = require('fs');
1314

1415
function ensurePackagesExist(packageNames, requestedFeature) {
1516
const recommendation = getPackageRecommendations(packageNames, requestedFeature);
@@ -20,10 +21,21 @@ function ensurePackagesExist(packageNames, requestedFeature) {
2021

2122
throw new Error(`
2223
${recommendation.message}
23-
${recommendation.yarnInstall}
24+
${recommendation.installCommand}
2425
`);
2526
}
2627

28+
function getInstallCommand(packages) {
29+
const hasYarnLockfile = fs.existsSync('yarn.lock');
30+
const hasNpmLockfile = fs.existsSync('package-lock.json');
31+
32+
if (hasNpmLockfile && !hasYarnLockfile) {
33+
return chalk.yellow(`npm install ${packages.join(' ')} --save-dev`);
34+
}
35+
36+
return chalk.yellow(`yarn add ${packages.join(' ')} --dev`);
37+
}
38+
2739
function getPackageRecommendations(packageNames, requestedFeature = null) {
2840
let missingPackageNames = [];
2941

@@ -48,11 +60,11 @@ function getPackageRecommendations(packageNames, requestedFeature = null) {
4860
message += ` to use ${chalk.green(requestedFeature)}`;
4961
}
5062

51-
let yarnInstall = chalk.yellow(`yarn add ${missingPackageNames.join(' ')} --dev`);
63+
const installCommand = getInstallCommand(missingPackageNames);
5264

5365
return {
5466
message,
55-
yarnInstall
67+
installCommand
5668
};
5769
}
5870

test/package-helper.js

Lines changed: 49 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,49 @@
1+
/*
2+
* This file is part of the Symfony Webpack Encore package.
3+
*
4+
* (c) Fabien Potencier <fabien@symfony.com>
5+
*
6+
* For the full copyright and license information, please view the LICENSE
7+
* file that was distributed with this source code.
8+
*/
9+
10+
'use strict';
11+
12+
const expect = require('chai').expect;
13+
const packageHelper = require('../lib/package-helper');
14+
const path = require('path');
15+
const process = require('process');
16+
17+
describe('package-helper', () => {
18+
const baseCwd = process.cwd();
19+
20+
describe('recommended install command is based on the existing lock files', () => {
21+
after(() => {
22+
process.chdir(baseCwd);
23+
});
24+
25+
it('missing packages without any lock file', () => {
26+
process.chdir(path.join(__dirname , '../fixtures/package-helper/empty'));
27+
const packageRecommendations = packageHelper.getPackageRecommendations(['foo', 'webpack', 'bar']);
28+
expect(packageRecommendations.installCommand).to.contain('yarn add foo bar');
29+
});
30+
31+
it('missing packages with package-lock.json only', () => {
32+
process.chdir(path.join(__dirname, '../fixtures/package-helper/npm'));
33+
const packageRecommendations = packageHelper.getPackageRecommendations(['foo', 'webpack', 'bar']);
34+
expect(packageRecommendations.installCommand).to.contain('npm install foo bar');
35+
});
36+
37+
it('missing packages with yarn.lock only', () => {
38+
process.chdir(path.join(__dirname, '../fixtures/package-helper/yarn'));
39+
const packageRecommendations = packageHelper.getPackageRecommendations(['foo', 'webpack', 'bar']);
40+
expect(packageRecommendations.installCommand).to.contain('yarn add foo bar');
41+
});
42+
43+
it('missing packages with both package-lock.json and yarn.lock', () => {
44+
process.chdir(path.join(__dirname, '../fixtures/package-helper/yarn-npm'));
45+
const packageRecommendations = packageHelper.getPackageRecommendations(['foo', 'webpack', 'bar']);
46+
expect(packageRecommendations.installCommand).to.contain('yarn add foo bar');
47+
});
48+
});
49+
});

0 commit comments

Comments
 (0)