-
Notifications
You must be signed in to change notification settings - Fork 30
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
Conversation
🦋 Changeset detectedLatest commit: d184a24 The changes in this PR will be included in the next version bump. This PR includes changesets to release 9 packages
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 |
packages/mc-scripts/package.json
Outdated
"preconstruct": { | ||
"entrypoints": ["./index.ts", "./application-runtime.ts"] | ||
}, |
There was a problem hiding this comment.
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", |
There was a problem hiding this comment.
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.
packages/mc-scripts/src/bin/cli.ts
Outdated
const startCommand = shouldUseExperimentalBundler | ||
? await import('../commands/start-vite') | ||
: await import('../commands/start'); | ||
await startCommand.default(); |
There was a problem hiding this comment.
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.
packages/mc-scripts/src/bin/cli.ts
Outdated
// 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) { |
There was a problem hiding this comment.
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() { |
There was a problem hiding this comment.
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 = {}) { |
There was a problem hiding this comment.
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() { |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Nothing changed here
import createDevServerConfig from '../config/webpack-dev-server.config'; | ||
import createWebpackConfigForDevelopment from '../config/create-webpack-config-for-development'; | ||
|
||
async function run() { |
There was a problem hiding this comment.
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.
Deploy preview for merchant-center-application-kit ready! ✅ Preview Built with commit d184a24. |
}); | ||
const devServer = new WebpackDevServer(serverConfig, compiler); | ||
|
||
await devServer.start(); |
There was a problem hiding this comment.
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
import type { | ||
TCreateCustomApplicationFromCliMutation, | ||
TCreateCustomApplicationFromCliMutationVariables, | ||
TCustomApplicationDraftDataInput, | ||
TFetchCustomApplicationFromCliQuery, | ||
TFetchCustomApplicationFromCliQueryVariables, | ||
TUpdateCustomApplicationFromCliMutation, | ||
TUpdateCustomApplicationFromCliMutationVariables, | ||
} from '../generated/settings'; | ||
import type { | ||
TFetchMyOrganizationsFromCliQuery, | ||
TFetchMyOrganizationsFromCliQueryVariables, | ||
} from '../generated/core'; |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Using the generated types.
@@ -110,6 +115,8 @@ const configSync = async () => { | |||
data, | |||
}); | |||
|
|||
if (!createdCustomApplication) return; |
There was a problem hiding this comment.
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.
There was a problem hiding this comment.
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?
There was a problem hiding this comment.
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
}
}
There was a problem hiding this comment.
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?
There was a problem hiding this comment.
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.
There was a problem hiding this comment.
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 thecreateCustomApplication
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.
There was a problem hiding this comment.
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.
There was a problem hiding this 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.
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Wowzers! 🎉
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Looks great 💯
…orts more decoupled
4b66fa1
to
438fc3e
Compare
Thanks @kark |
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:
import
, instead of spawning a child process. This allows us to bundle the package normally without relying on relative files from the file system.start
,build
,compile-html
,serve
login
,config:sync
mri
withcac
(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).login
andconfig:sync
commands