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

refactor: migrate mc-scripts package to TypeScript #2613

Merged
merged 20 commits into from
Jun 21, 2022
Merged

Conversation

emmenko
Copy link
Member

@emmenko emmenko commented May 13, 2022

Following up some previous work #2578 and #2579

See inline comments for more information.

In general, I wanted to bundle the CLI using Preconstruct. Right now we use Babel and we produce the same files compiled, mostly because we rely on file system paths.
However, this PR changes that and we leverage code splitting to load the required chunk.

TODO:

  • Refactor commands to be loaded via dynamic import, instead of spawning a child process. This allows us to bundle the package normally without relying on relative files from the file system.
  • Bundle with Preconstruct
  • Migrate all configs (Webpack, etc.)
  • Migrate all commands
    • start, build, compile-html, serve
    • login, config:sync
  • Replace mri with cac (used by Vite CLI). This allows to define the CLI commands and options more declarative and to better handle long running commands (e.g. starting server).
  • Expose multiple entry points
  • Add deprecation warnings for imports
  • Generate GraphQL types for CLI requests
  • Migrate remaining utils for login and config:sync commands

@changeset-bot
Copy link

changeset-bot bot commented May 13, 2022

🦋 Changeset detected

Latest commit: d184a24

The changes in this PR will be included in the next version bump.

This PR includes changesets to release 9 packages
Name Type
@commercetools-frontend/mc-scripts Minor
@commercetools-frontend/assets Minor
merchant-center-application-template-starter Patch
playground Patch
@commercetools-frontend/application-components Minor
@commercetools-frontend/application-shell Minor
@commercetools-local/visual-testing-app Patch
@commercetools-website/components-playground Patch
@commercetools-frontend/cypress Minor

Not sure what this means? Click here to learn what changesets are.

Click here if you're a maintainer who wants to add another changeset to this PR

Comment on lines 19 to 27
"preconstruct": {
"entrypoints": ["./index.ts", "./application-runtime.ts"]
},
Copy link
Member Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

The application-runtime is a separate entry point so that the file can be referenced from the web pack config.

@@ -42,6 +54,7 @@
"autoprefixer": "^10.4.4",
"babel-loader": "8.2.5",
"browserslist": "^4.20.2",
"cac": "6.7.12",
Copy link
Member Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

New CLI library as a replacement for mri, as it has some nicer features.

https://www.npmjs.com/package/cac

Comment on lines 60 to 63
const startCommand = shouldUseExperimentalBundler
? await import('../commands/start-vite')
: await import('../commands/start');
await startCommand.default();
Copy link
Member Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

This is now how we load and execute the commands. The bundle then contains code-splitter chunks.

// Load dotenv files into the process environment.
// This is essentially what `dotenv-cli` does, but it's now built into this CLI.
// Inspired also by https://create-react-app.dev/docs/adding-custom-environment-variables/#what-other-env-files-can-be-used
function loadDotEnvFiles(globalOptions: TCliGlobalOptions) {
Copy link
Member Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Nothing changed here

const WARN_AFTER_BUNDLE_GZIP_SIZE = 512 * 1024;
const WARN_AFTER_CHUNK_GZIP_SIZE = 1024 * 1024;

async function run() {
Copy link
Member Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Nothing much changed here, besides wrapping the logic into the run function and using more async/await


const appDirectory = fs.realpathSync(process.cwd());

async function run(options: TCliCommandCompileHtmlOptions = {}) {
Copy link
Member Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Nothing changed here


const port = 3001;

async function run() {
Copy link
Member Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Nothing changed here

@github-actions github-actions bot temporarily deployed to Preview May 13, 2022 20:31 Destroyed
import createDevServerConfig from '../config/webpack-dev-server.config';
import createWebpackConfigForDevelopment from '../config/create-webpack-config-for-development';

async function run() {
Copy link
Member Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Nothing much changed here, besides wrapping into run function, using async/await and cleaning up a bit.

@github-actions
Copy link
Contributor

github-actions bot commented May 13, 2022

Deploy preview for merchant-center-application-kit ready!

✅ Preview
https://merchant-center-application-nlizjbn80-commercetools.vercel.app
https://appkit-sha-c23d08f79dde28221aee518a90be143b9e3e9455.commercetools.vercel.app
https://appkit-pr-2613.commercetools.vercel.app

Built with commit d184a24.
This pull request is being automatically deployed with vercel-action

});
const devServer = new WebpackDevServer(serverConfig, compiler);

await devServer.start();
Copy link
Member Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

We're using a promise now

@github-actions github-actions bot temporarily deployed to Preview May 13, 2022 20:32 Destroyed
Comment on lines +6 to +18
import type {
TCreateCustomApplicationFromCliMutation,
TCreateCustomApplicationFromCliMutationVariables,
TCustomApplicationDraftDataInput,
TFetchCustomApplicationFromCliQuery,
TFetchCustomApplicationFromCliQueryVariables,
TUpdateCustomApplicationFromCliMutation,
TUpdateCustomApplicationFromCliMutationVariables,
} from '../generated/settings';
import type {
TFetchMyOrganizationsFromCliQuery,
TFetchMyOrganizationsFromCliQueryVariables,
} from '../generated/core';
Copy link
Member Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Using the generated types.

@emmenko emmenko self-assigned this May 13, 2022
@github-actions github-actions bot temporarily deployed to Preview May 13, 2022 21:08 Destroyed
@github-actions github-actions bot temporarily deployed to Preview May 14, 2022 19:47 Destroyed
@emmenko emmenko force-pushed the nm-ts-mc-scripts branch from 5f62e81 to a784174 Compare May 17, 2022 11:19
@github-actions github-actions bot temporarily deployed to Preview May 17, 2022 11:27 Destroyed
@github-actions github-actions bot temporarily deployed to Preview May 24, 2022 16:55 Destroyed
@github-actions github-actions bot temporarily deployed to Preview May 24, 2022 17:09 Destroyed
@github-actions github-actions bot temporarily deployed to Preview May 27, 2022 09:21 Destroyed
@github-actions github-actions bot temporarily deployed to Preview May 27, 2022 12:57 Destroyed
@emmenko emmenko marked this pull request as ready for review May 27, 2022 18:39
@emmenko emmenko force-pushed the nm-ts-mc-scripts branch from 7dd2f5e to 81f5dd9 Compare June 3, 2022 09:57
@emmenko emmenko requested a review from a team June 3, 2022 09:58
@github-actions github-actions bot temporarily deployed to Preview June 3, 2022 10:02 Destroyed
@@ -110,6 +115,8 @@ const configSync = async () => {
data,
});

if (!createdCustomApplication) return;
Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Not sure about this line. I don't know when the createCustomApplication can return a null value and have not raised an error.
Even in that scenario, we would just exit the process and not tell the use what happened.

I guess we would need to know when this use case can happen and, if it really exists, add an explanatory message before exiting the process.

Copy link
Member Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

The graphql client throws an error, so we don't need to explicitly handle this case.
Not sure if this check is really necessary. Maybe TS complains about something? Could you double check?

Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

So, that line was included in this commit due to some Typescript checking;

createdCustomApplication is the result of calling createCustomApplication function which returns an optional object.

This is the function implementation:


const createCustomApplication = async ({
  mcApiUrl,
  token,
  organizationId,
  data,
}: TCreateCustomApplicationOptions) => {
  const variables = {
    organizationId,
    data,
  };

  try {
    const createdCustomAppData = await graphQLClient(mcApiUrl, token).request<
      TCreateCustomApplicationFromCliMutation,
      TCreateCustomApplicationFromCliMutationVariables
    >(CreateCustomApplicationFromCli, variables);
    return createdCustomAppData.createCustomApplication;
  } catch (error) {
    if (error instanceof Error) {
      throw new Error(error.message);
    }
    throw error;
  }
};

And this is the definition for the TCreateCustomApplicationFromCliMutation type:

export type TCreateCustomApplicationFromCliMutation = {
  __typename?: 'Mutation';
  createCustomApplication?: {
    __typename?: 'RestrictedCustomApplicationForOrganization';
    id: string;
  } | null;
};

So, the return statement createdCustomAppData.createCustomApplication can be technically null.

If we are sure that sending the create mutation will either work or raise an error, perhaps we can change the type definition to state createCustomApplication field is not optional.

This is the mutation sent:

mutation CreateCustomApplicationFromCli(
  $organizationId: String!
  $data: CustomApplicationDraftDataInput!
) {
  createCustomApplication(organizationId: $organizationId, data: $data) {
    id
  }
}

Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

@Rhotimee What's your take about updating the TCreateCustomApplicationFromCliMutation so the createCustomApplication is not optional?

Copy link
Member Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

These types are generated so we can't change them. I'll check again if we can make the return type non optional.

Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

@Rhotimee What's your take about updating the TCreateCustomApplicationFromCliMutation so the createCustomApplication is not optional?

Sorry, I missed the tagged comment.

The line is not necessary, IMO. It was just added because of the type check error.
I don't think it matters what we return there because an error will be thrown anyway if the custom application is not created.

Copy link
Member Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

I pushed a commit with some small improvements: 4b66fa1

Making the type non optional is a bit tricky and I don't think it's worth the effort in this case. I left a comment with a note about the need for the check.

Copy link
Contributor

@CarlosCortizasCT CarlosCortizasCT left a comment

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

What a huge work in this PR 😮 💪

I just left a single comment to double check something I didn't fully understand.

Copy link
Contributor

@kark kark left a comment

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Wowzers! 🎉

packages/mc-scripts/src/commands/build.ts Show resolved Hide resolved
packages/mc-scripts/src/cli.ts Show resolved Hide resolved
packages/mc-scripts/src/commands/compile-html.ts Outdated Show resolved Hide resolved
Copy link
Contributor

@Rhotimee Rhotimee left a comment

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Looks great 💯

@emmenko emmenko force-pushed the nm-ts-mc-scripts branch from 4b66fa1 to 438fc3e Compare June 21, 2022 12:29
@emmenko
Copy link
Member Author

emmenko commented Jun 21, 2022

Thanks @kark

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
None yet
Projects
None yet
Development

Successfully merging this pull request may close these issues.

5 participants