Repository: apify/apify-cli (ts)

Issue:
Enable skipping installing optional packages with "apify create"
Now we're installing 90MB puppeteer dependency every time user calls "apify create". We should let them use something like `--no-optional` feature of npm. See https://github.com/apifytech/apify-js/issues/340 for details.

Pull request description:
feat: --no-optional for create command
Closes #100 

Patch:
diff --git a/src/commands/create.ts b/src/commands/create.ts
index beebd65..f4ef795 100644
--- a/src/commands/create.ts
+++ b/src/commands/create.ts
@@ -47,6 +47,11 @@ export class CreateCommand extends ApifyCommand<typeof CreateCommand> {
             required: false,
             hidden: true,
         }),
+        'omit-optional-deps': Flags.boolean({
+            aliases: ['no-optional'],
+            description: 'Skip installing optional dependencies.',
+            required: false,
+        }),
     };
 
     static override args = {
@@ -118,6 +123,11 @@ export class CreateCommand extends ApifyCommand<typeof CreateCommand> {
             }
         }
 
+        // Set this _after_ the template is resolved, so that the flag takes precedence
+        if (this.flags.omitOptionalDeps) {
+            skipOptionalDeps = true;
+        }
+
         await downloadAndUnzip({ url: templateArchiveUrl, pathTo: actFolderDir });
 
         // There may be .actor/actor.json file in used template - let's try to load it and change the name prop value to actorName


Test patch:
diff --git a/test/commands/create.test.ts b/test/commands/create.test.ts
index 44e3156..b83b8e6 100644
--- a/test/commands/create.test.ts
+++ b/test/commands/create.test.ts
@@ -80,4 +80,19 @@ describe('apify create', () => {
         expect(loadJsonFileSync<{ name: string }>(actorJsonPath)!.name).to.be.eql(actName);
         expect(loadJsonFileSync(joinPath(getLocalKeyValueStorePath(), `${KEY_VALUE_STORE_KEYS.INPUT}.json`))).to.be.eql(expectedInput);
     });
+
+    it('should skip installing optional dependencies', async () => {
+        const ACT_TEMPLATE = 'project_cheerio_crawler_js';
+        await CreateCommand.run([actName, '--template', ACT_TEMPLATE, '--no-optional'], import.meta.url);
+
+        // check files structure
+        expect(existsSync(tmpPath)).toBeTruthy();
+
+        toggleCwdBetweenFullAndParentPath();
+
+        expect(existsSync(joinPath('package.json'))).toBeTruthy();
+        expect(existsSync(joinPath('node_modules'))).toBeTruthy();
+        expect(existsSync(joinPath('node_modules', 'cheerio'))).toBeTruthy();
+        expect(existsSync(joinPath('node_modules', 'playwright'))).toBeFalsy();
+    });
 });