学习教程

第一步,文件夹里创建项目

npm init -y

第二步,新建pages文件夹,新建index.js文件,文件内容如下:

const Index = () => {
    return <div>Welcome</div>
}

export default Index

注意:key和secret在shopify partner页面里新建app后就会出现
新建app时需要有一个ngrok的外网映射,需要做以下步骤:

先安装ngrok

npm i ngrok -g
// 注意要全局安装

然后创建一个映射

ngrok http 3000

就可以获得一个URL,把URL填到创建app时的App URL处,在Allowed redirection URL(s)填这个地址并且在后面跟/auth/callback

第三步,安装react和相关依赖包

npm i --save next react react-dom/server koa @shopify/koa-shopify-auth dotenv koa-router@^8.0.8 isomorphic-fetch

第四步,创建一个.env文件,内容如下:

SHOPIFY_API_KEY='XXX'
SHOPIFY_API_SECRET='XXX'
SHOPIFY_API_SCOPES=read_products,write_products
SHOPIFY_API_URL='https://8760-2409-8a00-2450-9940-69c5-bbfa-f871-8a2c.ngrok.io'

第五步,创建server.js文件,内容如下:

require('isomorphic-fetch')
const dotenv = require('dotenv')
const Koa = require('koa')
const next = require('next')
const { default: createShopifyAuth } = require('@shopify/koa-shopify-auth')
const { verifyRequest } = require('@shopify/koa-shopify-auth')
const { default: Shopify, ApiVersion } = require('@shopify/shopify-api')
const Router = require('koa-router')

dotenv.config()

Shopify.Context.initialize({
    API_KEY: process.env.SHOPIFY_API_KEY,
    API_SECRET_KEY: process.env.SHOPIFY_API_SECRET,
    SCOPES: process.env.SHOPIFY_API_SCOPES.split(","),
    HOST_NAME: process.env.SHOPIFY_API_URL.replace(/https:\/\//, ""),
    API_VERSION: ApiVersion.October20,
    IS_EMBEDDED_APP: true,
    SESSION_STORAGE: new Shopify.Session.MemorySessionStorage()
})

const port = parseInt(process.env.PORT, 10) || 3000
const dev = process.env.NODE_ENV !== 'production'
const app = next({ dev })
const handle = app.getRequestHandler()

const ACTIVE_SHOPIFY_SHOPS = {}

app.prepare().then(() => {
    const server = new Koa()
    const router = new Router()
    server.keys = [Shopify.Context.API_SECRET_KEY]

    server.use(
        createShopifyAuth({
            afterAuth(ctx) {
                const { shop, scope } = ctx.state.shopify
                ACTIVE_SHOPIFY_SHOPS[shop] = scope
                
                if ( ACTIVE_SHOPIFY_SHOPS[shop] ) {
                    ctx.redirect(`https://${shop}/admin/apps`)
                } else {
                    ctx.redirect(`/?shop=${shop}`)
                }
            }
        })
    )

    const handleRequest = async (ctx) => {
        await handle(ctx.req, ctx.res)
        ctx.respond = false
        ctx.res.statusCode = 200
    }

    router.get("/", async (ctx) => {
        const shop = ctx.query.shop

        if (ACTIVE_SHOPIFY_SHOPS[shop] === undefined) {
            ctx.redirect(`/auth?shop=${shop}`)
        } else {
            await handleRequest(ctx)
        }
    })

    router.get("(.*)", handleRequest)

    router.get("(/_next/static/.*)", handleRequest)
    router.get("/_next/webpack-hmr", handleRequest)
    router.get("(.*)", verifyRequest(), handleRequest)

    server.use(router.allowedMethods())
    server.use(router.routes())

    server.listen(port, () => {
        console.log(`> Ready on http://localhost:${port}`)
    })
})

第六步,修改package.json文件

  "scripts": {
    "test": "echo \"Error: no test specified\" && exit 1",
    "dev": "node server.js",
    "build": "next build",
    "start": "NODE_ENV=production node server.js"
  },

第七步,运行

npm run dev

第八步,在app的页面里,有一个test your app,点击select store,然后在商店名称的右边点击install app

就可以看到你的index.js里的return的内容了。

总结:

  1. 视频教程里,index.js里没有写return,会导致以下错误:

    Error: Index(...): Nothing was returned from render. This usually means a return statement is missing. Or, to render nothing, return null.
  2. ngrok内网穿透反应有点慢
  3. server.js里的内容比较复杂,大概就是获取授权的事情,不知道vue能不能做到
  4. 这些东西,其实用shopify-cli一键生成就可以了,之所以跟着follow一次,是希望大概知道是怎么回事
最后编辑:2021年10月14日 ©著作权归作者所有

发表评论