Exploring TypeScript in the world of Shopify Command Line Interface

Exploring the process of developing a Shopify app using Typescript starting with the shopify-app-cli boilerplate, which utilizes Koa for the server and Nextjs for the frontend in React JavaScript. see

https://github.com/Shopify/shopify-app-cli

Encountering difficulty in compiling the Typescript code for both the server and the Next.js frontend.

Modifications:

  • Changing all file extensions to either .tsx or .ts instead of .js

  • In package.json, updating "dev" script to use ts-node instead of nodemon

Initial Setting:

"dev": "NODE_ENV=development nodemon ./server/index.js --watch ./server/index.js",

Updated Setting:

"dev": "NODE_ENV=development ts-node server/server.ts",

Able to compile the server.ts file successfully. However, upon changing the Next.js files like pages/_app.js and pages/index.js to .tsx, encountering this error:

[ event ] client pings, but there's no entry for page: /

Here is the content of the tsconfig.json file being used:

{
  "compilerOptions": {
    "target": "es6",
    "lib": ["dom", "dom.iterable", "esnext"],
    "allowJs": true,
    "skipLibCheck": true,
    "strict": false,
    "forceConsistentCasingInFileNames": true,
    "noEmit": true,
    "esModuleInterop": true,
    "module": "commonjs",
    "moduleResolution": "node",
    "resolveJsonModule": true,
    "isolatedModules": true,
    "jsx": "react"
  },
  "exclude": ["node_modules"],
  "include": ["next-env.d.ts", "**/*.ts", "**/*.tsx"]
}

Link to the server.ts gist: https://gist.github.com/azrielh/73ac202fcce5ce32f19488e4ef5df263.js

Answer №1

Following the steps you outlined, I was able to get everything up and running smoothly.

  1. I started by creating a new app using shopify-cli version 1.5
  2. I implemented the same tsconfig.json configuration as yours
  3. I made sure to rename _app.js to _app.tsx, pages/index.js to pages/index.tsx, and server.js to server.tsx
  4. I updated the dev script in package.json according to your instructions

Everything is functioning as expected, with all TSX pages compiling successfully.

Below is a snippet of my package.json file for reference:

{
  "name": "shopify-app-node",
  "version": "1.0.0",
  "description": "Shopify's node app for CLI tool",
  "scripts": {
    "test": "jest",
    "oldDev": "cross-env NODE_ENV=development nodemon ./server/index.js --watch ./server/index.js",
    "dev": "NODE_ENV=development ts-node server/server.ts",
    "build": "NEXT_TELEMETRY_DISABLED=1 next build",
    "start": "cross-env NODE_ENV=production node ./server/index.js"
  },
  "repository": {
    "type": "git",
    "url": "git+https://github.com/Shopify/shopify-app-node.git"
  },
  "author": "Shopify Inc.",
  "license": "MIT",
  "bugs": {
    "url": "https://github.com/shopify/shopify-app-node/issues"
  },
  // Dependencies
  ...
}

Answer №2

Here is the latest guide for CLI 3.x pertaining to web/frontend.

  1. To begin, install the TypeScript package.
npm i typescript --save-dev
  1. Create a tsconfig.json file with the following configuration.
{
  "compilerOptions": {
    "module": "esnext",
    "allowJs": false,
    "lib": [
      "dom",
      "dom.iterable",
      "esnext"
    ],
    "esModuleInterop": true,
    "target": "esnext",
    "noImplicitAny": true,
    "moduleResolution": "node",
    "sourceMap": true,
    "skipLibCheck": true,
    "allowSyntheticDefaultImports": true,
    "outDir": "dist",
    "baseUrl": ".",
    "noEmit": true,
    "paths": {
      "*": [
        "node_modules/*"
      ]
    },
    "resolveJsonModule": true,
    "isolatedModules": true,
    "jsx": "react-jsx"
  },
  "include": [
    "**/*.ts",
    "**/*.tsx"
  ],
  "exclude": [
    "node_modules/**"
  ]
}
  1. Update the dev and build scripts in the package.json. In the dev script, we will run the TypeScript compiler in watch mode. For the build script, we can check types before building.
"scripts": {
  "build": "tsc && vite build",
  "dev": "tsc -w ts && vite",
  "test": "vitest",
  "coverage": "vitest run --coverage"
},

Shopify utilizes Vite internally, which only transpiles .ts files without performing type checking. Therefore, your IDE will need to highlight any compilation errors as the build process still succeeds.

For detailed instructions on including eslint and prettier, visit this link.

Similar questions

If you have not found the answer to your question or you are interested in this topic, then look at other similar questions below or use the search

Trouble occurs in the HTML code when trying to access a property from an inherited interface in Angular

Currently, I am working with Angular 17 and have encountered a specific query: In my project, there is an IDetails interface containing certain properties: export interface IDetails { summary: Summary; description: string; } Additionally, there is an ...

What is the best way to incorporate this in a callback function?

Utilizing a third-party component requires creating an object for configuration, such as itemMovementOptions in the given code sample. export class AppComponent implements OnInit { readonly itemMovementOptions = { threshold: { horizontal: ...

An easy way to create an input field after clicking a button

When I try to add a field on Button Click, the default field is not showing and does not get added upon button click I have put in my best effort but I cannot figure out what the problem is. I have added functions and used Math to generate a unique id. Th ...

Is there a way to add an event listener to dynamically generated HTML using the v-html directive?

I have a string variable named log.htmlContent that contains some HTML content. This variable is passed into a div to be displayed using v-html. The particular div will only be displayed if log.htmlContent includes an img tag (http: will only be present in ...

Incorporate keyboard input functionality into an object wrapper

Adding typing to a class that encapsulates objects and arrays has been a bit tricky. Typing was easily implemented for objects, but ran into issues with arrays. interface IObject1 { value1: string, } interface IObject2 { myObject: IObject1, ...

What issue arises with the useSelector() hook function?

I've encountered an issue with my code while working on a todo app. I'm trying to implement a function to filter between completed and incomplete missions using the useSelector() hook. The problem arises when I execute the completed function succ ...

Utilizing the dialogue feature within Angular 6

Situation: I am managing two sets of data in JSON format named customers and workers: customers: [ { "cusId": "01", "customerName": "Customer One", "email": "<a href="/cdn-cgi/l/email-protection" class="__cf_email__" data- ...

Example client for Sanity.io with Next.js (next-sanity)

I am currently in the process of migrating from sanity version 4, which also involves upgrading from nextjs 13.4 to next 14 and next-sanity v7. The main challenge I'm facing is transitioning from version 4 to version 5. To assist with this migration, ...

Issue with React hook forms and shadcn/ui element's forwardRef functionality

Greetings! I am currently in the process of creating a form using react-hook-form along with the help of shadcn combobox. In this setup, there are two essential files that play crucial roles. category-form.tsx combobox.tsx (This file is utilized within ...

Comparing the cost of memory and performance between using classes and interfaces

As I delve into writing TypeScript for my Angular project, one burning question arises — should I use an Interface or a Class to create my domain objects? My quest is to uncover solid data regarding the actual implications of opting for the Class route. ...

Retrieving data from a remote source repeatedly based on user selections on a single page

In my current project, I am utilizing next js to build a web application. One of the pages in this app has the following structure: <page> <component_1> This component fetches data from a remote server using `getInitialProps` (alternat ...

React: Content has not been refreshed

MarketEvent.tsx module is a centralized controller: import * as React from 'react'; import EventList from './EventList'; import FullReduce from './FullReduce'; import './MarketEvent.less' export default class Mark ...

Ways to verify if a value corresponds to a particular data type

Is there a more elegant way for TypeScript to check if a value matches a specific type without actually invoking it, instead of the method described below? Consider the following example: import { OdbEventProcessorFunc } from "./OdbEventProcessor&quo ...

The use of React hooks in an application saga led to an issue where, despite using history.push, the component

Thank you for checking out this question. I have created a login demo using react hooks and TypeScript. I have some concerns: 1. When the login is successful, I use history.push('/home') to navigate to the home page, but the page also renders a N ...

Seeking advice on ways to exceed the 4.5MB body size limit of Vercel Serverless Functions

Currently, I am working on a project that involves a NestJS backend and a frontend in Next.js. I have been encountering a "413 Payload Too Large" error when trying to send videos to the NestJS backend via server actions of Next.js. Upon further investigat ...

What is the most effective method for implementing a pricing system for gold products on an eCommerce site using MERN development?

In the MERN project, there are gold and diamond jewelry items with a complex formula for calculating the prices based on the current gold rate, weight, and making charges. As an ecommerce website, what would be the best approach to display product prices? ...

Error: A stream was expected, but instead you provided an object that is invalid. Acceptable options include an Observable, Promise, Array, or Iterable

I attempted to use map with a service call and encountered an error. After checking this post about 'subscribe is not defined in angular 2', I learned that for subscribing, we need to return from within the operators. Despite adding return statem ...

Issue: The function "MyDocument.getInitialProps()" needs to return an object containing an "html" prop with a properly formatted HTML string

Check out my project on GitHub at https://github.com/Talita1996/NLW4 To start the project, I used the command yarn create next-app project_name I made changes to some files by modifying their extensions and adding new code Next, I added typescript to the ...

Strange Typescript Issue: Dependency Imports Not Recognized as Top-Level Module

Attempting to move a custom token from one account to another by following this detailed tutorial. Facing an issue with four errors showing up for all imports from the @solana/spl-token package. Tried removing the node-modules folder and reinstalling npm ...

Get rid of the TypeScript error in the specified function

I am currently working on implementing a "Clear" button for a select element that will reset the value to its default state. Here is a snippet of my code: const handleChange = (e: React.ChangeEvent<HTMLSelectElement>) => { onChange( ...