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

feat: adds noInstall option for Yarn packager #421

Merged
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.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
1 change: 1 addition & 0 deletions README.md
Original file line number Diff line number Diff line change
Expand Up @@ -108,6 +108,7 @@ The following `esbuild` options are automatically set.
| Option | Description | Default |
| --------- | ----------------------------------------------------------------------------------------------------- | ----------- |
| `scripts` | A string or array of scripts to be executed, currently only supports 'scripts' for npm, pnpm and yarn | `undefined` |
| `noInstall` | [Yarn only] A boolean that deactivates the install step | `false` |

#### Watch Options

Expand Down
2 changes: 1 addition & 1 deletion package.json
Original file line number Diff line number Diff line change
Expand Up @@ -107,4 +107,4 @@
"engines": {
"node": ">=14.18.0"
}
}
}
4 changes: 3 additions & 1 deletion src/index.ts
Original file line number Diff line number Diff line change
Expand Up @@ -250,13 +250,15 @@ class EsbuildServerlessPlugin implements ServerlessPlugin {
exclude: ['aws-sdk'],
nativeZip: false,
packager: 'npm',
packagerOptions: {
noInstall: false,
},
installExtraArgs: [],
watch: {
pattern: './**/*.(js|ts)',
ignore: [WORK_FOLDER, 'dist', 'node_modules', BUILD_FOLDER],
},
keepOutputDirectory: false,
packagerOptions: {},
platform: 'node',
outputFileExtension: '.js',
};
Expand Down
2 changes: 1 addition & 1 deletion src/pack-externals.ts
Original file line number Diff line number Diff line change
Expand Up @@ -265,7 +265,7 @@ export async function packExternalModules(this: EsbuildServerlessPlugin) {
assert(packageJsonPath, 'packageJsonPath is not defined');

// Determine and create packager
const packager = await getPackager.call(this, this.buildOptions.packager);
const packager = await getPackager.call(this, this.buildOptions.packager, this.buildOptions.packagerOptions);

// Fetch needed original package.json sections
const sectionNames = packager.copyPackageSectionNames;
Expand Down
2 changes: 1 addition & 1 deletion src/pack.ts
Original file line number Diff line number Diff line change
Expand Up @@ -145,7 +145,7 @@ export async function pack(this: EsbuildServerlessPlugin) {
assertIsString(this.buildOptions?.packager, 'packager is not a string');

// 2) If individually is set, we'll optimize files and zip per-function
const packager = await getPackager.call(this, this.buildOptions.packager);
const packager = await getPackager.call(this, this.buildOptions.packager, this.buildOptions.packagerOptions);

// get a list of every function bundle
const { buildResults } = this;
Expand Down
16 changes: 10 additions & 6 deletions src/packagers/index.ts
Original file line number Diff line number Diff line change
Expand Up @@ -10,10 +10,10 @@ import { memoizeWith } from 'ramda';
import { isPackagerId } from '../type-predicate';

import type EsbuildServerlessPlugin from '../index';
import type { PackagerId } from '../types';
import type { PackagerId, PackagerOptions } from '../types';
import type { Packager } from './packager';

const packagerFactories: Record<PackagerId, () => Promise<Packager>> = {
const packagerFactories: Record<PackagerId, (packgerOptions: PackagerOptions) => Promise<Packager>> = {
async npm() {
const { NPM } = await import('./npm');

Expand All @@ -24,10 +24,10 @@ const packagerFactories: Record<PackagerId, () => Promise<Packager>> = {

return new Pnpm();
},
async yarn() {
async yarn(packgerOptions) {
const { Yarn } = await import('./yarn');

return new Yarn();
return new Yarn(packgerOptions);
},
};

Expand All @@ -40,7 +40,11 @@ const packagerFactories: Record<PackagerId, () => Promise<Packager>> = {
*/
export const getPackager = memoizeWith(
(packagerId) => packagerId,
async function (this: EsbuildServerlessPlugin, packagerId: PackagerId): Promise<Packager> {
async function (
this: EsbuildServerlessPlugin,
packagerId: PackagerId,
packgerOptions: PackagerOptions
): Promise<Packager> {
this.log.debug(`Trying to create packager: ${packagerId}`);

if (!isPackagerId(packagerId)) {
Expand All @@ -49,7 +53,7 @@ export const getPackager = memoizeWith(
throw new this.serverless.classes.Error(`Could not find packager '${packagerId}'`);
}

const packager = await packagerFactories[packagerId]();
const packager = await packagerFactories[packagerId](packgerOptions);

this.log.debug(`Packager created: ${packagerId}`);

Expand Down
12 changes: 11 additions & 1 deletion src/packagers/yarn.ts
Original file line number Diff line number Diff line change
@@ -1,7 +1,7 @@
import { any, isEmpty, reduce, replace, split, startsWith } from 'ramda';
import { satisfies } from 'semver';

import type { DependenciesResult, DependencyMap } from '../types';
import type { DependenciesResult, DependencyMap, PackagerOptions } from '../types';
import { SpawnError, spawnProcess } from '../utils';
import type { Packager } from './packager';
import { isString } from '../helper';
Expand Down Expand Up @@ -39,6 +39,12 @@ const getNameAndVersion = (name: string): { name: string; version: string } => {
* ignoreScripts (false) - Do not execute scripts during install
*/
export class Yarn implements Packager {
private packagerOptions: PackagerOptions;

constructor(packagerOptions: PackagerOptions) {
this.packagerOptions = packagerOptions;
}

get lockfileName() {
return 'yarn.lock';
}
Expand Down Expand Up @@ -220,6 +226,10 @@ export class Yarn implements Packager {
}

async install(cwd: string, extraArgs: Array<string>, useLockfile = true) {
if (this.packagerOptions.noInstall) {
return;
}

const command = /^win/.test(process.platform) ? 'yarn.cmd' : 'yarn';

const args = useLockfile
Expand Down
2 changes: 1 addition & 1 deletion src/tests/packagers/index.test.ts
Original file line number Diff line number Diff line change
Expand Up @@ -10,7 +10,7 @@ describe('getPackager()', () => {
} as unknown as EsbuildServerlessPlugin;

it('Returns a Packager instance', async () => {
const npm = await getPackager.call(mockPlugin, 'npm');
const npm = await getPackager.call(mockPlugin, 'npm', {});

expect(npm).toEqual(expect.any(Object));
});
Expand Down
11 changes: 10 additions & 1 deletion src/tests/packagers/yarn.test.ts
Original file line number Diff line number Diff line change
Expand Up @@ -6,7 +6,7 @@ import * as utils from '../../utils';

jest.mock('process');
describe('Yarn Packager', () => {
const yarn = new Yarn();
const yarn = new Yarn({});
const path = './';

let spawnSpy: jest.SpyInstance;
Expand Down Expand Up @@ -231,4 +231,13 @@ describe('Yarn Packager', () => {

expect(result).toStrictEqual(expectedResult);
});

it('should skip install if the noInstall option is true', async () => {
const yarnWithoutInstall = new Yarn({
noInstall: true,
});

await expect(yarnWithoutInstall.install(path, [], false)).resolves.toBeUndefined();
expect(spawnSpy).toBeCalledTimes(0);
});
});
3 changes: 2 additions & 1 deletion src/types.ts
Original file line number Diff line number Diff line change
Expand Up @@ -13,6 +13,7 @@ export interface WatchConfiguration {

export interface PackagerOptions {
scripts?: string[] | string;
noInstall?: boolean;
}

interface NodeExternalsOptions {
Expand All @@ -24,14 +25,14 @@ export type EsbuildOptions = Omit<BuildOptions, 'watch' | 'plugins'>;
export interface Configuration extends EsbuildOptions {
concurrency?: number;
packager: PackagerId;
packagerOptions: PackagerOptions;
packagePath: string;
exclude: '*' | string[];
nativeZip: boolean;
watch: WatchConfiguration;
installExtraArgs: string[];
plugins?: string | Plugin[];
keepOutputDirectory?: boolean;
packagerOptions?: PackagerOptions;
disableIncremental?: boolean;
outputWorkFolder?: string;
outputBuildFolder?: string;
Expand Down