Azhop
Azhop

Reputation: 61

Shopify CLI using Typescript

I would like to test out building out a shopify app using Typescript by starting with the shopify-app-cli boilerplate, which uses Koa as a server and Nextjs for the front end react javascript. see https://github.com/Shopify/shopify-app-cli

I am having trouble getting the typescript code compiling for both the server and the nextjs frontend code.

Changes:

before

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

after

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

I can get it to compile the server.ts file, however if i change the nextjs files pages/_app.js and pages/index.js to .tsx it can't find them and has this error:

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

This is the tsconfig.json file have set up.

{
  "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"]
}

also a gist of server.ts, https://gist.github.com/azrielh/73ac202fcce5ce32f19488e4ef5df263.js

Upvotes: 4

Views: 3945

Answers (2)

amcquaid
amcquaid

Reputation: 539

Here's an updated answer for CLI 3.x. This only applies to web/frontend.

  1. Start by installing the TypeScript package.
npm i typescript --save-dev
  1. Add a tsconfig.json with the following.
{
  "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 dev & build scripts in the package.json. For dev we will run our TypeScript compiler in watch mode. For build, we can check types once before building.
"scripts": {
  "build": "tsc && vite build",
  "dev": "tsc -w ts && vite",
  "test": "vitest",
  "coverage": "vitest run --coverage"
},

Shopify uses Vite under the hood which only performs transpilation on .ts files and does NOT perform type checking. This means you'll have to lean on your IDE to point out any compilation errors as the build will still pass.

In-depth steps including adding eslint & prettier can be found here.

Upvotes: 3

Josh Anderson
Josh Anderson

Reputation: 51

I got it to work with basically the setup that you describe.

  1. I scaffolded a new app using shopify-cli version 1.5
  2. I created the tsconfig.json file you are using
  3. I renamed _app.js to _app.tsx, pages/index.js to pages/index.tsx, and server.js to server.tsx
  4. I replaced the dev command in package.json as you specified

It all runs, compiles, and sees the TSX pages as expected.

Here's my package.json:

{
  "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": {
    "@babel/core": "7.12.3",
    "@babel/polyfill": "^7.6.0",
    "@babel/preset-env": "^7.6.2",
    "@babel/register": "^7.6.2",
    "@shopify/app-bridge-react": "^1.15.0",
    "@shopify/app-cli-node-generator-helper": "^1.1.2",
    "@shopify/koa-shopify-auth": "^3.2.0",
    "@shopify/koa-shopify-graphql-proxy": "^4.0.2",
    "@shopify/koa-shopify-webhooks": "^2.5.3",
    "@shopify/polaris": "^5.3.1",
    "@zeit/next-css": "^1.0.1",
    "apollo-boost": "^0.4.4",
    "cross-env": "^7.0.2",
    "dotenv": "^8.2.0",
    "graphql": "^14.5.8",
    "isomorphic-fetch": "^3.0.0",
    "koa": "^2.8.2",
    "koa-router": "^10.0.0",
    "koa-session": "^6.1.0",
    "lodash": "^4.17.20",
    "next": "^10.0.0",
    "next-env": "^1.1.0",
    "node-fetch": "^2.6.1",
    "react": "^16.10.1",
    "react-apollo": "^3.1.3",
    "react-dom": "^16.10.1",
    "ts-node": "^9.1.1"
  },
  "devDependencies": {
    "@babel/plugin-transform-runtime": "^7.6.2",
    "@babel/preset-stage-3": "^7.0.0",
    "@types/lodash": "^4.14.165",
    "@types/node": "^12.19.5",
    "@types/react": "^16.9.56",
    "@types/react-dom": "^16.9.8",
    "@typescript-eslint/eslint-plugin": "^4.11.1",
    "@typescript-eslint/parser": "^4.11.1",
    "babel-jest": "26.6.2",
    "babel-register": "^6.26.0",
    "enzyme": "3.11.0",
    "enzyme-adapter-react-16": "1.15.5",
    "eslint": "^7.16.0",
    "husky": "^4.0.7",
    "jest": "26.6.2",
    "lint-staged": "^10.0.1",
    "nodemon": "^2.0.0",
    "prettier": "^2.1.2",
    "react-addons-test-utils": "15.6.2",
    "react-test-renderer": "16.14.0",
    "tsmon": "^0.7.3",
    "typescript": "^4.1.3"
  },
  "husky": {
    "hooks": {
      "pre-commit": "lint-staged"
    }
  },
  "lint-staged": {
    "*.{js,css,json,md}": [
      "prettier --write"
    ]
  }
}

Upvotes: 5

Related Questions