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

Cloudflare Pages! #2

Open
Aslemammad opened this issue Dec 28, 2021 · 2 comments
Open

Cloudflare Pages! #2

Aslemammad opened this issue Dec 28, 2021 · 2 comments

Comments

@Aslemammad
Copy link
Owner

We better discuss this with you all! please give me your suggestions!

@travis-r6s
Copy link

After struggling with multiple different bundlers, I have managed to find a way to do this 🙃

I have used esbuild to bundle the worker, and it's then just a case of configuring the pages site correctly.

Dev Packages

esbuild
@esbuild-plugins/node-modules-polyfill
wrangler@beta # Used for local previews
@cloudflare/workers-types # Optional

Worker

worker/index.ts

import { createPageRenderer } from 'vite-plugin-ssr'
import '../dist/server/importBuild.js'

const renderPage = createPageRenderer({ isProduction: true })

interface EnvironmentVariables {
  EXAMPLE_SECRET: string
}

type FetchFunction = EventContext<EnvironmentVariables, '', unknown>

export default {
  async fetch (request: FetchFunction['request'], env: FetchFunction['env']) {
    // Keep browser requests happy during testing
    if (request.url.includes('favicon')) return new Response('', { status: 200 })

    if (request.url.includes('/api/')) {
      // TODO: Add your custom /api/* logic here.
      return new Response('Ok')
    }

    // Handle Asset requests
    if (request.url.includes('/assets')) return env.ASSETS.fetch(request)

    // Otherwise pass to SSR handler
    const pageContextInit = {
      url: request.url,
      fetch: (...args: [RequestInfo, RequestInit]) => fetch(...args)
    }
    const pageContext = await renderPage(pageContextInit)
    const { httpResponse } = pageContext
    if (httpResponse) {
      const { body, statusCode, contentType } = httpResponse
      return new Response(body, {
        headers: { 'content-type': contentType },
        status: statusCode
      })
    }
  }
}

Build Script

build.js

const esbuild = require('esbuild')
const { default: nodeModulesPolyfills } = require('@esbuild-plugins/node-modules-polyfill')

esbuild.build({
  entryPoints: ['./worker/index.js'],
  sourcemap: false,
  outfile: './dist/client/_worker.js',
  minify: true,
  logLevel: 'info',
  platform: 'browser',
  plugins: [nodeModulesPolyfills()],
  format: 'esm',
  target: 'es2020',
  bundle: true
}).then(() => {
  console.log(`Successfully built worker.`)
}).catch(error => {
  console.error(`There was an error whilst building this worker:`)
  console.error(error)
})

Pages

Make sure to set the Build output directory to /dist/client, as otherwise asset requests will fail because the browser is requesting /assets/some.js, whereas the actual stored asset path would be /client/assets/some.js.

You will then need to add a build script in package.json to first build the Vite app, run vite-plugin-ssr, and then run the build.js script.

"scripts": {
    "build": "npm run build:site && npm run build:worker",
    "build:site": "vite build && vite build --ssr",
    "build:worker": "node build.js",
    "serve": "wrangler pages dev ./dist/client"
  }

You can also preview the site locally, by running the build script and then the serve script.

Potential Issues

The esbuild --minify option is pretty decent, but even with this basic project the built _worker.js file comes out around 600kB - the Worker limit being 1MB. So any larger projects, with a number of pages/packages etc. will probably go over this limit quite quickly. There is talk of this limit being raised however, and there is a form to request an increase (although I don't know if this is just for the Workers platform, or whether it includes Pages Functions (which is what the above uses).

@Aslemammad
Copy link
Owner Author

Thank you @thetre97, I appreciate this!

I'll read it precisely in the next days, so I can improve this package! I'll let you know if I needed anything!

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

No branches or pull requests

2 participants