Skip to content

Commit

Permalink
Merge pull request #5 from Js-Brecht/uniq-module-paths
Browse files Browse the repository at this point in the history
Unique module paths
  • Loading branch information
Js-Brecht authored May 2, 2020
2 parents c9bffa0 + a2586bb commit e92195a
Show file tree
Hide file tree
Showing 7 changed files with 107 additions and 53 deletions.
6 changes: 5 additions & 1 deletion package.json
Original file line number Diff line number Diff line change
@@ -1,6 +1,6 @@
{
"name": "gatsby-plugin-pnpm",
"version": "1.2.3",
"version": "1.2.5",
"description": "Easily add pnpm support to your Gatsby project",
"main": "index.js",
"types": "./dist/gatsby-node.js",
Expand Down Expand Up @@ -45,6 +45,7 @@
"devDependencies": {
"@jtechsvcs/eslint-config-typescript": "^2.0.3",
"@types/jest": "^25.1.2",
"@types/lodash.uniq": "^4.5.6",
"@types/node": "^12.12.26",
"@types/webpack": "^4.41.5",
"@typescript-eslint/eslint-plugin": "^2.19.0",
Expand All @@ -60,5 +61,8 @@
"type-fest": "^0.10.0",
"typedoc": "^0.15.8",
"typescript": "^3.7.5"
},
"dependencies": {
"lodash.uniq": "^4.5.0"
}
}
16 changes: 15 additions & 1 deletion pnpm-lock.yaml

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

33 changes: 21 additions & 12 deletions src/gatsby-node.ts
Original file line number Diff line number Diff line change
@@ -1,7 +1,8 @@
import * as path from 'path';
import { Configuration } from 'webpack';
import { GatsbyNode, CreateWebpackConfigArgs, PluginOptions } from 'gatsby';
import { realpath, isDir, getPkgNodeModules } from './utils';
import uniq from 'lodash.uniq';
import { isDir, getPkgNodeModules } from './utils';

export interface IPluginOptions extends Omit<PluginOptions, 'plugins'> {
include?: string[];
Expand All @@ -24,8 +25,16 @@ export interface IPluginOptions extends Omit<PluginOptions, 'plugins'> {
* | projectPath | **OPTIONAL**: The path to your project; i.e. the folder containing your `package.json`. This will be used when locating package names included in `include`, and for resolving your project's `node_modules` directory |
* | strict | **OPTIONAL**: Defaults to true. `true` = Resolve modules using the `pnpm` philosophy of limiting the module scope of your project. `false` = Use `node`'s module resolution, which looks in every `node_modules` walking up your directory tree. |
*/
export const onCreateWebpackConfig: GatsbyNode['onCreateWebpackConfig'] = async ({ actions, reporter }: CreateWebpackConfigArgs, options: IPluginOptions = {} as IPluginOptions): Promise<void> => {
const { setWebpackConfig } = actions;
export const onCreateWebpackConfig: GatsbyNode['onCreateWebpackConfig'] = async (
{
actions,
reporter,
getConfig,
}: CreateWebpackConfigArgs,
options: IPluginOptions = {} as IPluginOptions,
): Promise<void> => {
const webpackConfig: Configuration = getConfig();
const { replaceWebpackConfig } = actions;
const {
include,
projectPath = process.cwd(),
Expand Down Expand Up @@ -76,14 +85,14 @@ export const onCreateWebpackConfig: GatsbyNode['onCreateWebpackConfig'] = async
}
}

const config: Configuration = {
resolve: {
modules: modulePaths,
},
resolveLoader: {
modules: modulePaths,
},
};
if (!webpackConfig.resolve) webpackConfig.resolve = {};
if (!webpackConfig.resolveLoader) webpackConfig.resolveLoader = {};

setWebpackConfig(config);
const compareResolvePaths = webpackConfig.resolve.modules || [];
const compareResolveLoaderPaths = webpackConfig.resolveLoader.modules || [];

webpackConfig.resolve.modules = uniq([...modulePaths, ...compareResolvePaths]);
webpackConfig.resolveLoader.modules = uniq([...modulePaths, ...compareResolveLoaderPaths]);

replaceWebpackConfig(webpackConfig);
};
2 changes: 1 addition & 1 deletion src/utils.ts
Original file line number Diff line number Diff line change
Expand Up @@ -28,7 +28,7 @@ export const isDir = async (pathname: string): Promise<Boolean> => {

export const walkBack = async (startPath: string): Promise<string> => {
const procPath = path.resolve(startPath);
const sep = '[\\/]';
const sep = '[\\\\/]';
const matches = new RegExp(`(.*${sep}node_modules)(?:${sep}.+?$|${sep}?$)`, 'i').exec(procPath);
if (matches && matches[1]) return matches[1];
return '';
Expand Down
38 changes: 21 additions & 17 deletions tests/gatsby-node.test.ts
Original file line number Diff line number Diff line change
@@ -1,6 +1,8 @@
import * as path from 'path';
import { realpath, walkBack } from '../src/utils';
import uniq from 'lodash.uniq';
import { CreateWebpackConfigArgs as _CreateWebpackConfigArgs } from 'gatsby';
import { Configuration as WebpackConfig } from 'webpack';
import { realpath, walkBack } from '../src/utils';
import { onCreateWebpackConfig as _onCreateWebpackConfig, IPluginOptions } from '../src/gatsby-node';

const reporter = {
Expand All @@ -10,40 +12,42 @@ const reporter = {

interface CreateWebpackConfigArgs {
actions: {
setWebpackConfig: jest.Mock<WebpackConfig, [WebpackConfig]>;
replaceWebpackConfig: jest.Mock<WebpackConfig, [WebpackConfig]>;
};
reporter: typeof reporter;
getConfig: _CreateWebpackConfigArgs['getConfig'];
}
type IOnCreateWebpackConfig = (actions: CreateWebpackConfigArgs, options?: IPluginOptions) => Promise<void>;

const getConfigResults = (resolutions: string[]): WebpackConfig => {
return {
resolve: {
modules: resolutions,
modules: uniq(resolutions),
},
resolveLoader: {
modules: resolutions,
modules: uniq(resolutions),
},
};
};

describe('Defining module/loader resolutions', () => {

const onCreateWebpackConfig = _onCreateWebpackConfig as unknown as IOnCreateWebpackConfig;
const setWebpackConfig: CreateWebpackConfigArgs['actions']['setWebpackConfig'] = jest.fn((config) => config);
const replaceWebpackConfig: CreateWebpackConfigArgs['actions']['replaceWebpackConfig'] = jest.fn((config) => config);
const actions: CreateWebpackConfigArgs['actions'] = {
setWebpackConfig,
replaceWebpackConfig,
};
const args: CreateWebpackConfigArgs = {
actions,
reporter,
getConfig: () => ({}),
};

const curDir = process.cwd();

describe('Resolves with default options accurately', () => {
beforeEach(() => {
setWebpackConfig.mockReset();
replaceWebpackConfig.mockReset();
});
it('With default options', async () => {
const resolutions = [
Expand All @@ -54,13 +58,13 @@ describe('Defining module/loader resolutions', () => {
];
const shouldEqual = getConfigResults(resolutions);
await onCreateWebpackConfig(args);
expect(setWebpackConfig).toHaveBeenLastCalledWith(shouldEqual);
expect(replaceWebpackConfig).toHaveBeenLastCalledWith(shouldEqual);
});
});

describe('Resolves with include options accurately', () => {
beforeEach(() => {
setWebpackConfig.mockReset();
replaceWebpackConfig.mockReset();
Object.entries(reporter).forEach(([key, fn]) => {
fn.mockReset();
});
Expand All @@ -80,7 +84,7 @@ describe('Defining module/loader resolutions', () => {
'jest',
],
});
expect(setWebpackConfig).toHaveBeenLastCalledWith(shouldEqual);
expect(replaceWebpackConfig).toHaveBeenLastCalledWith(shouldEqual);
});

it('With directory', async () => {
Expand All @@ -99,7 +103,7 @@ describe('Defining module/loader resolutions', () => {
'./node_modules',
],
});
expect(setWebpackConfig).toHaveBeenLastCalledWith(shouldEqual);
expect(replaceWebpackConfig).toHaveBeenLastCalledWith(shouldEqual);
});

it('Warns with non-existant package', async () => {
Expand All @@ -124,7 +128,7 @@ describe('Defining module/loader resolutions', () => {

describe('Resolves with strict mode correctly', () => {
beforeEach(() => {
setWebpackConfig.mockReset();
replaceWebpackConfig.mockReset();
Object.entries(reporter).forEach(([key, fn]) => {
fn.mockReset();
});
Expand All @@ -142,7 +146,7 @@ describe('Defining module/loader resolutions', () => {
await onCreateWebpackConfig(args, {
strict: true,
});
expect(setWebpackConfig).toHaveBeenLastCalledWith(shouldEqual);
expect(replaceWebpackConfig).toHaveBeenLastCalledWith(shouldEqual);
});
it('With strict off', async () => {
process.chdir(__dirname);
Expand All @@ -156,7 +160,7 @@ describe('Defining module/loader resolutions', () => {
await onCreateWebpackConfig(args, {
strict: false,
});
expect(setWebpackConfig).toHaveBeenLastCalledWith(shouldEqual);
expect(replaceWebpackConfig).toHaveBeenLastCalledWith(shouldEqual);
});
it('Panics with strict on, and no Gatsby', async () => {
process.chdir(__dirname);
Expand All @@ -169,7 +173,7 @@ describe('Defining module/loader resolutions', () => {

describe('Resolves with projectPath correctly', () => {
beforeEach(() => {
setWebpackConfig.mockReset();
replaceWebpackConfig.mockReset();
Object.entries(reporter).forEach(([key, fn]) => {
fn.mockReset();
});
Expand All @@ -195,7 +199,7 @@ describe('Defining module/loader resolutions', () => {
],
projectPath: __dirname,
});
expect(setWebpackConfig).toHaveBeenLastCalledWith(shouldEqual);
expect(replaceWebpackConfig).toHaveBeenLastCalledWith(shouldEqual);
});

it('With strict off, and package and directory includes', async () => {
Expand All @@ -220,7 +224,7 @@ describe('Defining module/loader resolutions', () => {
],
projectPath: __dirname,
});
expect(setWebpackConfig).toHaveBeenLastCalledWith(shouldEqual);
expect(replaceWebpackConfig).toHaveBeenLastCalledWith(shouldEqual);
});

});
Expand Down
30 changes: 17 additions & 13 deletions tests/silo/tests/silo-node.test.ts
Original file line number Diff line number Diff line change
@@ -1,6 +1,8 @@
import * as path from 'path';
import { realpath, walkBack } from '../../../src/utils';
import uniq from 'lodash.uniq';
import { Configuration as WebpackConfig } from 'webpack';
import { CreateWebpackConfigArgs as _CreateWebpackConfigArgs } from 'gatsby';
import { realpath, walkBack } from '../../../src/utils';
import { onCreateWebpackConfig as _onCreateWebpackConfig, IPluginOptions } from '../../../src/gatsby-node';

const reporter = {
Expand All @@ -10,33 +12,35 @@ const reporter = {

interface CreateWebpackConfigArgs {
actions: {
setWebpackConfig: jest.Mock<WebpackConfig, [WebpackConfig]>;
replaceWebpackConfig: jest.Mock<WebpackConfig, [WebpackConfig]>;
};
reporter: typeof reporter;
getConfig: _CreateWebpackConfigArgs['getConfig'];
}
type IOnCreateWebpackConfig = (actions: CreateWebpackConfigArgs, options?: IPluginOptions) => Promise<void>;

const getConfigResults = (resolutions: string[]): WebpackConfig => {
return {
resolve: {
modules: resolutions,
modules: uniq(resolutions),
},
resolveLoader: {
modules: resolutions,
modules: uniq(resolutions),
},
};
};

describe('Defining module/loader resolutions in silo', () => {

const onCreateWebpackConfig = _onCreateWebpackConfig as unknown as IOnCreateWebpackConfig;
const setWebpackConfig: CreateWebpackConfigArgs['actions']['setWebpackConfig'] = jest.fn((config) => config);
const replaceWebpackConfig: CreateWebpackConfigArgs['actions']['replaceWebpackConfig'] = jest.fn((config) => config);
const actions: CreateWebpackConfigArgs['actions'] = {
setWebpackConfig,
replaceWebpackConfig,
};
const args: CreateWebpackConfigArgs = {
actions,
reporter,
getConfig: () => ({}),
};

const curDir = process.cwd();
Expand All @@ -47,7 +51,7 @@ describe('Defining module/loader resolutions in silo', () => {

describe('Resolves with strict mode correctly', () => {
beforeEach(() => {
setWebpackConfig.mockReset();
replaceWebpackConfig.mockReset();
Object.entries(reporter).forEach(([key, fn]) => {
fn.mockReset();
});
Expand All @@ -65,7 +69,7 @@ describe('Defining module/loader resolutions in silo', () => {
await onCreateWebpackConfig(args, {
strict: false,
});
expect(setWebpackConfig).toHaveBeenLastCalledWith(shouldEqual);
expect(replaceWebpackConfig).toHaveBeenLastCalledWith(shouldEqual);
});
it('With strict off, include package name', async () => {
const resolutions = [
Expand All @@ -82,7 +86,7 @@ describe('Defining module/loader resolutions in silo', () => {
'jest',
],
});
expect(setWebpackConfig).toHaveBeenLastCalledWith(shouldEqual);
expect(replaceWebpackConfig).toHaveBeenLastCalledWith(shouldEqual);
});
it('With strict off, include package name and directory', async () => {
const resolutions = [
Expand All @@ -101,7 +105,7 @@ describe('Defining module/loader resolutions in silo', () => {
'../../../node_modules',
],
});
expect(setWebpackConfig).toHaveBeenLastCalledWith(shouldEqual);
expect(replaceWebpackConfig).toHaveBeenLastCalledWith(shouldEqual);
});

it('Panics with strict on, and no Gatsby', async () => {
Expand All @@ -115,7 +119,7 @@ describe('Defining module/loader resolutions in silo', () => {

describe('Resolves with projectPath correctly', () => {
beforeEach(() => {
setWebpackConfig.mockReset();
replaceWebpackConfig.mockReset();
Object.entries(reporter).forEach(([key, fn]) => {
fn.mockReset();
});
Expand All @@ -139,7 +143,7 @@ describe('Defining module/loader resolutions in silo', () => {
],
projectPath: testsDir,
});
expect(setWebpackConfig).toHaveBeenLastCalledWith(shouldEqual);
expect(replaceWebpackConfig).toHaveBeenLastCalledWith(shouldEqual);
});

it('With strict on, and package and directory includes', async () => {
Expand All @@ -162,7 +166,7 @@ describe('Defining module/loader resolutions in silo', () => {
],
projectPath: rootDir,
});
expect(setWebpackConfig).toHaveBeenLastCalledWith(shouldEqual);
expect(replaceWebpackConfig).toHaveBeenLastCalledWith(shouldEqual);
});

it('With strict on, and panic with no Gatsby', async () => {
Expand Down
Loading

0 comments on commit e92195a

Please sign in to comment.