I'm attempting to create an apollo client plugin for a Nuxt 3 application. It's currently throwing an error regarding a package called ts-invariant:
file:///Users/[my name]/Repositories/[project]/node_modules/#apollo/client/utilities/globals/fix-graphql.js:1
import { remove } from "ts-invariant/process/index.js";
^^^^^^
SyntaxError: Named export 'remove' not found. The requested module 'ts-invariant/process/index.js' is a CommonJS module, which may not support all module.exports as named exports.
CommonJS modules can always be imported via the default export, for example using:
import pkg from 'ts-invariant/process/index.js';
const { remove } = pkg;
at ModuleJob._instantiate (node:internal/modules/esm/module_job:124:21)
at async ModuleJob.run (node:internal/modules/esm/module_job:181:5)
at async Promise.all (index 0)
at async ESMLoader.import (node:internal/modules/esm/loader:281:24)
at async __instantiateModule__ (file:///Users/[my name]/Repositories/[project]/.nuxt/dist/server/server.mjs:4550:3)
[vite dev] Error loading external "/Users/[my name]/Repositories/[project]/node_modules/#apollo/client/core/index.js".
at file://./.nuxt/dist/server/server.mjs:3170:289
at async __instantiateModule__ (file://./.nuxt/dist/server/server.mjs:4550:3)
I feel like I know enough about this error to know it has something to do with how Nuxt 3 deals with ESM, but I can't be for certain.
Here's the nuxt plugin:
plugins/apollo-client.js
import { defineNuxtPlugin } from "#app"
import { ApolloClient, InMemoryCache } from "#apollo/client/core"
import { DefaultApolloClient } from "#vue/apollo-composable"
export default defineNuxtPlugin((nuxtApp) => {
const config = useRuntimeConfig()
const apolloClient = new ApolloClient({
uri: config.PUBLIC_API_ENDPOINT,
cache: new InMemoryCache(),
})
nuxtApp.vueApp.provide(DefaultApolloClient, apolloClient)
})
In a normal scenario, I might use the nuxt-apollo community module, but it is currently afk regarding a nuxt 3 port, so a plugin it is.
Here's some documentation I relied on for my plugin:
https://v4.apollo.vuejs.org/guide-composable/setup.html#vue-3
https://v3.nuxtjs.org/docs/directory-structure/plugins
Solved by including #apollo/client and ts-invariant/process into the nuxt build transpile like so:
// nuxt.config.js
// ...
build: {
postcss: {
postcssOptions: require('./postcss.config.js')
},
transpile: [
'#apollo/client',
'ts-invariant/process',
],
},
// ...
I think I've pinpointed the underlying issue. Apollo Client (3.5.10 at the time of writing early 2022) is using "module":"index.js" to declare the path of the ESM exports.
However it seems that Webpack 5 based bundlers do not support this. Using exports in the package.json fixes it for good for me.
You should upvote this feature request.
And here is my palliative until then, using a small script to alter the package.json.
Related
I have a Preact project using Vite. I want to use the nexmo-client SDK from vonage but when I import using the ES method it breaks my project.
// app.tsx
import NexmoClient from 'nexmo-client';
I get the following error in the console.
index.js:19 Uncaught ReferenceError: global is not defined
at index.js:19:19
at index.js:12:22
at node_modules/nexmo-client/dist/index.js (index.js:16:1)
at __require (chunk-J43GMYXM.js?v=f3505250:11:50)
at dep:nexmo-client:1:16
However if I import it using via a script tag it works just fine.
// index.html
<script src="node_modules/nexmo-client/dist/nexmoClient.js"></script>
// app.tsx
const NexmoClient = window.NexmoClient;
OK, there are two problems here.
Firstly, NexmoClient tries to use global which is not available on the browser.
Secondly, NexmoClient has a dependency on socket.io-client, for some reason Vite imports a Node version of the socket.io-client that again tries to use modules that are not available on the browser, namely 'child_process'.
To fix both issues you can provide the following config to Vite, this should make sure the resulting build is compatible with the brother.
// vite.config.js or vite.config.ts
import { defineConfig } from 'vite'
import preact from '#preact/preset-vite'
export default defineConfig({
plugins: [preact()],
define: {
global: {},
},
resolve: {
alias: {
"xmlhttprequest-ssl": "./node_modules/engine.io-client/lib/xmlhttprequest.js"
}
}
})
I am using #googlemaps/js-api-loader in my Nuxt 3 website. Everything works fine in local development, but when I try to build the project with nuxt generate (no matter if locally or on Vercel) I'm getting following error:
[nuxt] [request error] Named export 'Loader' not found. The requested module 'file:///path/to/website/node_modules/#googlemaps/js-api-loader/dist/index.umd.js' is a CommonJS module, which may not support all module.exports as named exports. CommonJS modules can always be imported via the default export, for example using:
The important part of loading script looks like this:
import { Loader } from '#googlemaps/js-api-loader';
const loader = new Loader({
apiKey: config.googleMapsApiKey,
version: 'weekly',
});
onMounted(async() => {
await loader
.load()
...
so I tried to import this package differently, e.g.:
import * as gmaps from '#googlemaps/js-api-loader';
const { Loader } = gmaps;
and the previous error disappeared, but now I'm getting
[Vue warn]: Unhandled error during execution of setup function
at <DynamicLocations class="contact__map" locations= [
{
id: 1,
...
[nuxt] [request error] gmaps.Loader is not a constructor
at setup (./.nuxt/prerender/chunks/app/server.mjs:5536:20)
at _sfc_main$t.setup (./.nuxt/prerender/chunks/app/server.mjs:5582:25)
at callWithErrorHandling (./.nuxt/prerender/chunks/renderer.mjs:2654:23)
at setupStatefulComponent (./.nuxt/prerender/chunks/renderer.mjs:9548:30)
at setupComponent (./.nuxt/prerender/chunks/renderer.mjs:9503:12)
at renderComponentVNode (./.nuxt/prerender/chunks/renderer.mjs:12068:17)
at Object.ssrRenderComponent (./.nuxt/prerender/chunks/renderer.mjs:12504:12)
at ./.nuxt/prerender/chunks/app/server.mjs:5628:36
at renderComponentSubTree (./.nuxt/prerender/chunks/renderer.mjs:12149:13)
at renderComponentVNode (./.nuxt/prerender/chunks/renderer.mjs:12084:16)
I also can't import package by default export. Do you have any ideas what's going on and how can I fix this?
I found a documentation page related to this problem and there is the following information:
If you encounter these errors, the issue is almost certainly with the upstream library. They need to fix their library to support being imported by Node.
Although they provide a solution to get rid of errors by adding the package to build.transpile:
build: {
transpile: ['#googlemaps/js-api-loader'],
},
It worked for me
I've got a working svelte webapp running with rollup.js. On extending it, I learnt of SvelteKit and realise that it's a better match for my project. How can I migrate from rollup.js to SvelteKit?
Here is the updated URL for migrating to sveltekit from sapper:
https://kit.svelte.dev/docs/migrating
The key point you're probably looking for is to move configuration from your rollup.config.js to svelte.config.js
Preprocessor options are there under config.preprocess
So your svelte.config.js might end up looking like this:
import adapter from '#sveltejs/adapter-auto';
import preprocess from 'svelte-preprocess';
import image from "svelte-image";
/** #type {import('#sveltejs/kit').Config} */
const config = {
// Consult https://github.com/sveltejs/svelte-preprocess
// for more information about preprocessors
preprocess: [
preprocess(),
image(),
],
kit: {
adapter: adapter(),
// Override http methods in the Todo forms
methodOverride: {
allowed: ['PATCH', 'DELETE']
}
}
};
export default config;
I'm trying to learn nativescript-vue where I'm using the Nativescript's Playground to tryout my sample codes. I'm trying to use nativescript-localstorage package so that I can store some of the information into local storage:
Whenever I'm trying to save project it is giving use compilation error
and following is the error:
An error occurred while transpiling nativescript-localstorage/localstorage.js.
unknown: We found a path that isn't a NodePath instance. Possiblly due to bad serialisation.
I followed the tutorials and added the package as it was instructed my code looks like:
import Vue from 'nativescript-vue';
import Vuex from 'vuex';
import localStorage from 'nativescript-localstorage';
import userStore from './user-store';
//For local storage of vuex tools
const NSVuexPersistent = store => {
// Init hook.
let storageStr = localStorage.getItem('ns-vuex-persistent');
if (storageStr) {
store.replaceState(JSON.parse(storageStr))
}
store.subscribe((mutation, state) => {
// Subscribe hook.
localStorage.setItem('ns-vuex-persistent', JSON.stringify(state));
})
};
Vue.use(Vuex);
const debug = process.env.NODE_ENV !== 'production';
export default new Vuex.Store({
modules: {
userStore
},
strict: debug,
plugins: [NSVuexPersistent]
})
Since the project is not getting saved so I've not shared the link. Help me out with it. Thanks.
nativescript-vue is packaged within the Preview APK, so it can be imported as
import Vue from 'nativescript-vue'
But nativescript-localstorage is something you have installed in your project, so while at Playground you should use relative path to import the module, something like
import * as localStorage from "../nativescript-localstorage"
// Or
const localStorage = require("../nativescript-localstorage");
You can use import name from "package" only when the package has marked something as default in its exports, the syntax is commonly used in ES6 & Vue plugins. nativescript-localstorage has not exported anything as default.
I created an NPM package that uses Webpack and Babel for transpiling/bundling.
In my package.json, I've got main set to "main": "build/index.js". And in my Webpack config, I have entry set to entry: { app: './src/index.js' }. My entry file is shown below.
Everything works fine when the package is installed. However, with this setup, two import paths are exposed for every helper:
This is a problem for editors that support auto imports, since they will sometimes auto import from 'my-package/build/utils/helper1' rather than the preferred path of 'my-package'.
So, two questions:
Is there any way to prevent the longer import path from being exposed?
What is considered best practice when creating NPM packages. Is my setup acceptable, or should I be doing something different?
Entry File:
import helper1 from './utils/helper1';
import helper2 from './utils/helper2';
export {
helper1,
helper2,
};
const myPackage = {
helper1,
helper2,
};
export default myPackage;
you can utilize Webpack resolve
I often use the first way:
export {
helper1,
helper2,
};
Recently, I found that we can use Object.freeze() to export. This is a good article.
I would suggest probably merge your helper1 and helper2 in one file and name it helpers, then you can put them in the class myPackage so that you then export them as a module like this
import myPackage from './utils/helper';
// OR import {helper1, helper2} from './utils/helpers';
export default class myPackage {
helper1,
helper2,
};
OR
import {myPackage} from './utils/helpers';
// OR import {helper1, helper2} from './utils/helpers';
module.exports.myPackage = (helper1, helper2) => {
this.helper1 = helper1;
this.helper2 = helper2;
};
I hope this helps.