Skip to content

Commit

Permalink
Merge pull request #1 from tjx666/dev
Browse files Browse the repository at this point in the history
  • Loading branch information
余腾靖 committed May 29, 2023
2 parents 1ac42f5 + 0c131ed commit 4bc14d2
Show file tree
Hide file tree
Showing 6 changed files with 105 additions and 80 deletions.
4 changes: 1 addition & 3 deletions .github/workflows/unit-test.yml
Original file line number Diff line number Diff line change
Expand Up @@ -2,9 +2,7 @@ name: Unit Test

on:
push:
branches: [main]
pull_request:
branches: [main]
branches: ['**']

jobs:
lint:
Expand Down
13 changes: 0 additions & 13 deletions CHANGELOG.md

This file was deleted.

4 changes: 3 additions & 1 deletion package.json
Original file line number Diff line number Diff line change
@@ -1,6 +1,6 @@
{
"name": "unplugin-detect-duplicated-deps",
"version": "0.1.0",
"version": "0.1.1",
"description": "Detect duplicate packaged dependencies",
"keywords": [
"unplugin",
Expand Down Expand Up @@ -67,7 +67,9 @@
"vite": "^4.3"
},
"dependencies": {
"@rollup/pluginutils": "^5.0.2",
"consola": "^3.1.0",
"mem": "^9.0.2",
"p-memoize": "^7.1.1",
"picocolors": "^1.0.0",
"semver": "^7.5.1",
Expand Down
42 changes: 29 additions & 13 deletions pnpm-lock.yaml

Some generated files are not rendered by default. Learn more about how customized files appear on GitHub.

121 changes: 71 additions & 50 deletions src/index.ts
Original file line number Diff line number Diff line change
@@ -1,7 +1,9 @@
import fs from 'node:fs/promises';
import path from 'node:path';

import { normalizePath } from '@rollup/pluginutils';
import consola from 'consola';
import mem from 'mem';
import pMemoize from 'p-memoize';
import c from 'picocolors';
import { gt } from 'semver';
Expand All @@ -11,19 +13,24 @@ import { workspaceRoot } from 'workspace-root';

export interface Options {}

const workspaceRootFolder = await workspaceRoot();
let workspaceRootFolder = await workspaceRoot();
if (workspaceRootFolder) {
workspaceRootFolder = normalizePath(workspaceRootFolder);
}

function parsePackageNameFromModulePath(id: string) {
const parsePackageNameFromModulePath = mem((id: string) => {
id = normalizePath(id);
const packageNameRegex = /.*\/node_modules\/((?:@[^/]+\/)?[^/]+)/;
const match = id.match(packageNameRegex);
const packageName = match ? match[1] : id;
if (workspaceRootFolder && packageName.startsWith(workspaceRootFolder)) {
return packageName.slice(workspaceRootFolder.length + 1);
}
return packageName;
}
});

const getPackageInfo = pMemoize(async (id: string) => {
id = normalizePath(id);
const packagePathRegex = /.*\/node_modules\/(?:@[^/]+\/)?[^/]+/;
const match = id.match(packagePathRegex);
if (match) {
Expand All @@ -43,10 +50,13 @@ const getPackageInfo = pMemoize(async (id: string) => {

export default createUnplugin<Options | undefined>(() => {
const name = 'unplugin-detect-duplicated-deps';
let isVitePlugin = false;

/**
* Map{
* 'axios': Map{
* '0.0.1': Set['tests/fixtures/mono/packages/pkg2/index.js', 'axios-mock-adapter']
* Map(1) {
* 'axios' => Map(2) {
* '1.4.0' => Set(2) { 'tests/fixtures/mono/packages/pkg1/index.js', 'axios' },
* '0.27.2' => Set(2) { 'tests/fixtures/mono/packages/pkg2/index.js', 'axios' }
* }
* }
*/
Expand Down Expand Up @@ -85,58 +95,69 @@ export default createUnplugin<Options | undefined>(() => {
}
};

const buildEnd: RollupPlugin['buildEnd'] = function () {
const duplicatedPackages: string[] = [];
for (const [packageName, versionsMap] of packageToVersionsMap.entries()) {
if (versionsMap.size > 1) {
duplicatedPackages.push(packageName);
}
}
if (duplicatedPackages.length === 0) return;

const formattedDuplicatedPackageNames = duplicatedPackages
.map((name) => c.magenta(name))
.join(', ');
const warningMessages = [
`multiple versions of ${formattedDuplicatedPackageNames} is bundled!`,
];

for (const duplicatedPackage of duplicatedPackages) {
warningMessages.push(`\n ${c.magenta(duplicatedPackage)}:`);

const sortedVersions = [...packageToVersionsMap.get(duplicatedPackage)!.keys()].sort(
(a, b) => (gt(a, b) ? 1 : -1),
);

let longestVersionLength = Number.NEGATIVE_INFINITY;
sortedVersions.forEach((v) => {
if (v.length > longestVersionLength) {
longestVersionLength = v.length;
}
});

for (const version of sortedVersions) {
const importers = Array.from(
packageToVersionsMap.get(duplicatedPackage)!.get(version)!,
);
const formattedVersion = c.bold(
c.yellow(version.padEnd(longestVersionLength, ' ')),
);
const formattedImporters = importers
.filter((name) => name !== duplicatedPackage)
.map((name) => c.green(name))
.join(', ');
warningMessages.push(` - ${formattedVersion} imported by ${formattedImporters}`);
}
}
// remove vite output dim colorize
// eslint-disable-next-line unicorn/escape-case, unicorn/no-hex-escape
process.stdout.write(`\x1b[0m${isVitePlugin ? '\n' : ''}`);
consola.warn(warningMessages.join('\n'));
};

return {
name,
vite: {
enforce: 'pre',
config() {
isVitePlugin = true;
},
resolveId,
buildEnd,
},
rollup: {
resolveId,
},
buildEnd() {
const duplicatedPackages: string[] = [];
for (const [packageName, versionsMap] of packageToVersionsMap.entries()) {
if (versionsMap.size > 1) {
duplicatedPackages.push(packageName);
}
}
if (duplicatedPackages.length === 0) return;

const formattedDuplicatedPackageNames = duplicatedPackages
.map((name) => c.magenta(name))
.join(', ');
consola.warn(`multiple versions of ${formattedDuplicatedPackageNames} is bundled!`);

for (const duplicatedPackage of duplicatedPackages) {
console.warn(` ${c.magenta(duplicatedPackage)}:`);

const sortedVersions = [
...packageToVersionsMap.get(duplicatedPackage)!.keys(),
].sort((a, b) => (gt(a, b) ? 1 : -1));

let longestVersionLength = Number.NEGATIVE_INFINITY;
sortedVersions.forEach((v) => {
if (v.length > longestVersionLength) {
longestVersionLength = v.length;
}
});

for (const version of sortedVersions) {
const importers = Array.from(
packageToVersionsMap.get(duplicatedPackage)!.get(version)!,
);
const formattedVersion = c.bold(
c.yellow(version.padEnd(longestVersionLength, ' ')),
);
const formattedImporters = importers
.filter((name) => name !== duplicatedPackage)
.map((name) => c.green(name))
.join(', ');
console.warn(` - ${formattedVersion} imported by ${formattedImporters}`);
}
}
process.stdout.write('\n');
buildEnd,
},
};
});
1 change: 1 addition & 0 deletions tests/fixtures/mono/app/package.json
Original file line number Diff line number Diff line change
Expand Up @@ -14,6 +14,7 @@
"@rollup/plugin-commonjs": "^25.0.0",
"@rollup/plugin-json": "^6.0.0",
"@rollup/plugin-node-resolve": "^15.0.2",
"axios": "^1.4.0",
"rimraf": "^5.0.1",
"rollup": "^3.23.0",
"vite": "^4.3.9"
Expand Down

0 comments on commit 4bc14d2

Please sign in to comment.