Can I use #vercel/og without React? - vercel

I'm trying to create an API on Vercel which returns images, generated based on the request. I would like to use #vercel/og for this, because it can generate images from HTML, and it is very quick. However, it seems to require React, which seems entirely unnecessary for something serving no actual HTML at all.
I have an edge function in api/test.ts:
import { ImageResponse } from '#vercel/og';
export const config = {
runtime: 'experimental-edge',
};
export default function () {
return new ImageResponse({
type: "div",
props: {
children: "Hello, World",
style: {
backgroundColor: "black",
color: "white",
width: "100%",
height: "100%",
}
}
}, { width: 500, height: 500 });
}
This runs completely fine when deployed to Vercel, but when I use vercel dev it gives me these errors:
Failed to instantiate edge runtime.
Invalid URL: ../vendor/noto-sans-v27-latin-regular.ttf
Error: Failed to complete request to /api/test: Error: socket hang up
node_modules/#vercel/og/dist/og.d.ts:1:35 - error TS2307: Cannot find module 'react' or its corresponding type declarations.
1 import type { ReactElement } from 'react';
~~~~~~~
node_modules/satori/dist/index.d.ts:1:27 - error TS2307: Cannot find module 'react' or its corresponding type declarations.
1 import { ReactNode } from 'react';
~~~~~~~
node_modules/satori/dist/index.d.ts:14:11 - error TS2580: Cannot find name 'Buffer'. Do you need to install type definitions for node? Try `npm i --save-dev #types/node`.
14 data: Buffer | ArrayBuffer;
~~~~~~
Found 3 errors.
There are two errors saying that #vercel/og and satori can't find React. Is there a way around this? I shouldn't need react for this, right?

I worked around the React-related errors and the inability to run .tsx edge functions without Next.js by installing #types/react and defining my own JSX function and using it without JSX syntax just in a .ts file.
function h<T extends React.ElementType<any>>(
type: T,
props: React.ComponentPropsWithRef<T>,
...children: React.ReactNode[]
) {
return {
type,
key: "key" in props ? props.key : null,
props: {
...props,
children: children && children.length ? children : props.children,
},
};
}
After this you can run it in Vercel deployment preview.
However, in vercel dev locally, I'm still getting the following error.
Failed to instantiate edge runtime.
Invalid URL: ../vendor/noto-sans-v27-latin-regular.ttf
Error: Failed to complete request to /api/og: Error: socket hang up
I had also forced vercel CLI to use the newer TypeScript version with pnpm.overrides in package.json to solve some TypeScript parse errors I was getting.

Related

How do you resolve the 500 error "Navigator is not defined" when installing third-party plugins in a Nuxt 3 app?

I am currently unable to use third-party plugins in my Nuxt 3 application. Here's what my code/setup looks like:
In my package.json I have the following dependency: "#braze/web-sdk": "^4.6.1"
In my plugins/ directory, I have a braze.client.js file
Within the braze.client.js file, I have the following:
import * as braze from '#braze/web-sdk'
export default defineNuxtPlugin(() => {
braze.initialize(apiKey, {
baseUrl: apiEndpoint
})
return {
provide: {
openSession
}
}
})
Within my nuxt.config.ts, I added the following (since my project has Vite, I followed Braze's documentation here: https://www.braze.com/docs/developer_guide/platform_integration_guides/web/initial_sdk_setup/#vite):
optimizeDeps: {
exclude: ['#braze/web-sdk']
}
Then within my <script> tags within the page/component, I have the following:
const { $openSession } = useNuxtApp()
onMounted(() => {
$openSession()
})
All the steps above continue to create a "500 navigator is not defined" error and I'm stumped with how I can resolve it.
I tried using beforeOnMount, not using as lifecycle hook, as well as placing $openSession() within an if statement:
if (process.client) {
}
Yet no matter what, it still renders the 500 error.

Quasar 2 + Apollo: Error: Apollo client with id default not found. Use provideApolloClient() if you are outside of a component setup

followed the steps in https://github.com/quasarframework/app-extension-apollo/tree/v2 to install Apollo extension to Quasar 2.4.9:
"devDependencies": {
"#babel/eslint-parser": "^7.13.14",
"#quasar/app": "^3.0.0",
"#quasar/quasar-app-extension-apollo": "^2.0.0-beta.3",
"eslint": "^7.14.0",
"eslint-config-prettier": "^8.1.0",
"eslint-plugin-vue": "^7.0.0",
"eslint-webpack-plugin": "^2.4.0"
},
found two files generated which are related to apollo:
src/boot/apollo.js
src/apollo/index.js, where I modified the process.env.GRAPHQL_URI to be mine GraphQL server endpoint
I also created apollo.provider.js under root manually with :
// apollo.config.js
module.exports = {
client: {
service: {
name: "my-app",
// URL to the GraphQL API
url: "http://localhost:4000/graphql",
},
// Files processed by the extension
includes: ["src/**/*.vue", "src/**/*.js"],
},
};
in My Vue file, I have the following code:
<script>
import { useQuery } from "#vue/apollo-composable";
import gql from "graphql-tag";
export default {
setup() {
const { result } = useQuery(gql`
query GetAllBooks {
getAllBooks {
id
name
}
}
`);
},
...
However, running this code led to the following error:
index.esm.js?0df5:48 Uncaught (in promise) Error: Apollo client with id default not found. Use provideApolloClient() if you are outside of a component setup.
at resolveClient (index.esm.js?0df5:48:1)
at start (index.esm.js?0df5:277:1)
at immediate (index.esm.js?0df5:493:1)
at callWithErrorHandling (runtime-core.esm-bundler.js?9e79:6737:1)
at callWithAsyncErrorHandling (runtime-core.esm-bundler.js?9e79:6746:1)
at job (runtime-core.esm-bundler.js?9e79:7154:1)
at doWatch (runtime-core.esm-bundler.js?9e79:7199:1)
at watch (runtime-core.esm-bundler.js?9e79:7040:1)
at useQueryImpl (index.esm.js?0df5:491:1)
at useQuery (index.esm.js?0df5:228:1)
Any idea which part's wrong?
I found this post I am using vue 3 with apollo/client but getting an error, seems Ricky Vadala's also using Quasar and following the same steps. However, the following doesn't work:
import { apolloClients } from 'src/extensions/apollo/boot'
as 'src/extensions/apollo/boot' does not exist.
Also, I cannot find your-app\node_modules#quasar\quasar-app-extension-apollo\README.md. Maybe Ricky Vadala was using an older version?
Please kindly shed some light on this. Surprisingly I cannot find an example of Quasar 2 + Apollo from the Internet.
Got help from Scott in here.
End of the day, it's an RTFM issue. I didn't read README carefully:
The extension will add a configuration file into src/apollo and a boot file. You'll need to manually register the latter into quasar.conf.js > boot.
Translate that to real-world action, I need to modify quasr.conf.js, find the boot part, and modify it to be:
boot: ["apollo.js"],
After that, the error went away, and I could see the call to my GraphQL endpoint from Chrome dev tools.

Load vue component (truly) dynamically from local file

Is it possible to load a vue component dynamically at runtime (in an electron app to build a plugin system)?
The component is in a specific file
Its path is only known at runtime
The component can either be precompiled (if that is possible, don't know) or is compiled at runtime
A simple example component is listed below
I tried the following approaches, both failing:
Require component
<template>
<component :is="currentComp"></component>
</template>
<script>
...
methods: {
loadComponent(path) {
const dynComp = eval('require(path)'); // use eval to prevent webpackresolving the require
this.currentComp = dynComp;
}
},
...
</script>
The import works, but the line this.currentComp = dynComp; Fails with error message:
Error in data(): "Error: An object could not be cloned."
Using the code presented here, but replace url with a local path
Fails with error message:
Failed to resolve async component: function MyComponent() {
return externalComponent('/path/to/Component.vue');
}
Reason: TypeError: Chaining cycle detected for promise #<Promise>
The used example component is the following:
// Example component
module.exports = {
template: `
<div>
<input v-model="value"/>
<button #click="clear">Clear</button>
<div>{{ value }}</div>
</div>`,
name: 'Example',
data() {
return {
value: '',
};
},
watch: {
value(value) {
console.log('change!');
},
},
methods: {
clear() {
this.value = '';
},
},
};
I found a solution:
Create the vue component as a SFC in a separate file (here src/Component.vue). I didn't try, but probably it works for inline components, too.
Precompile the component using vue-cli-service, which is already a dev dependency, if the project is created using vue-cli (It's nice to use vue-cli here, since the required loaders are already included):
yarn vue-cli-service build --target lib src/Command.vue
The component is compiled to different bundle types in the dist directory. The file [filename].umd.min.js can be imported now.
Import the component dynamically at runtime:
let MyComponent = eval(`require('/absolute/path/to/[filename].umd.min.js')`);
Vue.component('MyComponent', MyComponent);
The require is wrapped inside an eval to prevent webpack of trying to include the import in its bundle and transforming the require into a webpack__require.
(Optional) If the SFC component contains a <style>...</style> tag, the resulting css is compiled to a separate file. The css can be inlined in the js file by adding the following lines to the vue.config.js in the components project root:
module.exports = {
...
css: {
extract: false,
},
};
You can probably look into async loading:
https://v2.vuejs.org/v2/guide/components-dynamic-async.html#Async-Components
and see this for a webpack lazy load example:
https://vuedose.tips/dynamic-imports-in-vue-js-for-better-performance/#the-meat%3A
These are just some things I would research for your requirements.

How to config Nuxt.js runing on ie 11

I using Nuxt.js # v2.13.2 and I try to config my project working with ie 11
The doc say:
The default targets of #nuxt/babel-preset-app are ie: '9' in the client build, and node: 'current' in the server build.
Here is my nuxt.config.js
build: {
babel: {
presets({ isServer }, [ preset, options ]) {
// change options directly
options.buildTarget = 'client'
options.targets = {
ie: 11,
}
}
}
}
And my pages
import Amplify from 'aws-amplify';
import awsconfig from './aws-exports';
Amplify.configure(awsconfig);
But it not working in ie 11
[object Error]{description: "Syntax error", message: "Syntax error", name: "SyntaxError", number: -2146827286, stack: "SyntaxError...", Symbol(amplify_default)_i.icdaor5bqh3: undefined, Symbol(extensions)_k.icdaor5bqh3: undefined, Symbol(observable)_j.icdaor5bqh3: undefined, Symbol(react.element)_h.icdaor5bqh3: undefined
How to do that thank.
As far as I can tell, the issue is that the Symbol polyfill does not and cannot support cross-realm native functionality.
More detail here: https://github.com/zloirock/core-js/issues/834

TypeORM with React Native

I created a new dummy app with react-native init test, and then followed the instructions to add typeorm. In my App.js I included import {getManager} from 'typeorm', and then ran react-native run-ios.
I see the following error in metro-bundler:
Error: Unable to resolve module path from /Users/amit/Code/test/node_modules/typeorm/platform/PlatformTools.js: Module path does not exist in the Haste module map
Here's a sample repository to show the problem: enter link description here
Not sure if I missed something in the setup! Any help is really welcome!
Unfortunately import from 'typeorm' module does not work because react-native projects does not use node platform excatly. Imports from 'typeorm/browser' will work. Here is a sample project.: https://github.com/typeorm/react-native-example
Make sure you create a connection object that does not use any references to project file system. Avoid using something like:
import { CountSession } from '../biopro-mobile-database/entities/count_session';
const connection = await createConnection({
name: 'liteDb_3',
type: 'react-native',
database: 'biopro_mobile.sqlite',
location: 'default',
synchronize: false,
logging: true,
entities: ["../biopro-mobile-database/entities/**/*.ts"],
})
Avoid entities: ["../biopro-mobile-database/entities//*.ts"],**
Instead use something like:
import { EquipmentCounted } from '../biopro-mobile-database/entities/equipment_counted';
import { CountSession } from '../biopro-mobile-database/entities/count_session';
const connection = await createConnection({
name: 'liteDb_3',
type: 'react-native',
database: 'biopro_mobile.sqlite',
location: 'default',
synchronize: false,
logging: true,
entities: [
CountSession,
EquipmentCounted,
],
})