pluvial / svelte-adapter-deno

A SvelteKit adapter for Deno
https://svelte-adapter-deno.deno.dev/
MIT License
313 stars 14 forks source link

Dynamic import is not enabled in this context (deno-deploy) #40

Open ThibaudMZN opened 1 year ago

ThibaudMZN commented 1 year ago

Hi, I tried using the adapter and push my code to deno deploy but I'm getting this error when loading the published site :

TypeError: Dynamic import is not enabled in this context.
    at async Promise.all (index 0)
    at async respond (file:///src/build/server/index.js:3420:23)
    at async ssr (file:///src/build/handler.js:34:19)
    at async handler (file:///src/build/handler.js:80:11)
    at async dispatch (https://deno.land/x/oak@v11.1.0/middleware.ts:18:13)
    at async allowedMethods (https://deno.land/x/oak@v11.1.0/router.ts:350:13)
    at async dispatch (https://deno.land/x/oak@v11.1.0/middleware.ts:18:13)
    at async dispatch (https://deno.land/x/oak@v11.1.0/middleware.ts:18:13)
    at async Application.#handleRequest (https://deno.land/x/oak@v11.1.0/application.ts:198:17)

I was wondering if you ever encountered this problem ?

jpaquim commented 1 year ago

@ThibaudMZN thanks for your feedback, I'm also getting the same error on one of my websites on Deno Deploy, it's most likely related to the esbuild->rollup migration or some misconfiguration, I'll work on fixing it.

ThibaudMZN commented 1 year ago

Thanks for your quick answer !

ThibaudMZN commented 1 year ago

Is this due to oak itself ? Would it be better to use http serve instead ?

ashxdev commented 1 year ago

@jpaquim I can confirm that on version 0.9.0, I have the same error, and I don't have errors on 0.8.2.

jessiejs commented 1 year ago

I am running into the same error, any fixes?

jpaquim commented 1 year ago

@CodeLikeCrazE I haven't had the time to look into this yet, but it's likely related to differences between esbuild and rollup or a rollup misconfiguration. I'll try to dig deeper into this over the coming week.

wesley-mccann commented 1 year ago

+1 on this. I've tried to deploy the basic demo app to test this adapter and deno deploy, but ran into this issue.

zicklag commented 1 year ago

I also ran into this and was able to fix it by downgrading from v0.9.0 to v0.8.2. Thanks for the tip @ashxdev!

zicklag commented 1 year ago

Oh, and it may also be worth noting that I didn't run into the issue until I added an import from import { env } from '$env/dynamic/private'; in this commit: https://github.com/zicklag/easy-pages/commit/2b3ceacbabb96d38834a585bbce33b13357fa2d3.

dbushell commented 1 year ago

This issue is that Deno Deploy cannot dynamically import modules. Rollup generates code like:

const component = async () => (await import('./_page.svelte.js')).default;

The await import('...') throws an error in Deno Deploy. I could not find Rollup options to avoid this.

I looked at how the Netlify adapter works for Netlify Edge functions because those actually run on Deno Deploy. It is using esbuild instead of Rollup and bundling a single file combining the server and manifest.

A simple Deno Deploy adapter I have working:

import {writeFileSync} from 'fs';
import {build} from 'esbuild';

export default function (opts = {}) {
  const {out = 'build'} = opts;

  return {
    name: 'deno-deploy-adapter',

    async adapt(builder) {
      const tmp = builder.getBuildDirectory('deno-deploy-adapter');

      builder.rimraf(out);
      builder.rimraf(tmp);
      builder.mkdirp(tmp);

      const outDir = `${out}/static/${builder.config.kit.paths.base}`;
      builder.writeClient(outDir);
      builder.writePrerendered(outDir);

      builder.writeServer(`${tmp}/server`);

      const manifest = builder.generateManifest({
        relativePath: './'
      });

      writeFileSync(
        `${tmp}/server/manifest.js`,
        `export const manifest = ${manifest};\n\nexport const prerendered = new Set(${JSON.stringify(
          builder.prerendered.paths
        )});\n`
      );

      writeFileSync(
        `${tmp}/server.js`,
        `
import {Server} from './server/index.js';
import {manifest} from './server/manifest.js';
const server = new Server(manifest);
export default server;
`
      );

      build({
        entryPoints: [`${tmp}/server.js`],
        outfile: `${out}/server.js`,
        bundle: true,
        format: 'esm',
        target: 'esnext'
      }).catch((err) => {
        console.error(err);
        process.exit(1);
      });
    }
  };
}

And the actual Deno Deploy entry point:

import {serve} from 'https://deno.land/std@0.188.0/http/server.ts';
import {serveDir} from 'https://deno.land/std@0.188.0/http/file_server.ts';
import server from './build/server.js';

const initialized = server.init({env: Deno.env.toObject()});

serve(async (request, context) => {
  const response = await serveDir(request, {
    fsRoot: 'build/static',
    quiet: true
  });
  if (response && (response.ok || response.status < 400)) {
    const url = new URL(request.url);
    if (url.pathname.startsWith('/_app/immutable/')) {
      response.headers.set(
        'cache-control',
        'public, max-age=31536000, immutable'
      );
    }
    return response;
  }

  await initialized;
  return server.respond(request, {
    platform: {context},
    getClientAddress() {
      return context.remoteAddr.hostname;
    }
  });
});

I'm not sure the best way to integrate such a "fix" for the svelte-adapter-deno project because the requirements for Deno Deploy lead to a very different build process.

dbushell commented 1 year ago

I'm working on a Deno Deploy compatible adapter here: https://github.com/dbushell/sveltekit-adapter-deno

Based on the code above but with a few fixes and improvements.

jpaquim commented 1 year ago

Hey @dbushell! Thank you for looking into this issue, unfortunately I haven't really been using Deno or Deno Deploy lately, so I haven't had the time to look into this. As mentioned above, this breaking change in compatibility in the 0.9 release was due to migrating from esbuild to rollup, which I think I'll just end up reverting. Feel free to propose any change to this repo, I'll take a look at your repo as well.