Status of Vue 3 + Meteor?

Hi,

I opened a issue (https://github.com/meteor-vue/vue-meteor-tracker/issues/77) for vue-meteor-tracker.

Can someone check it and confirm it?

Thanks.

1 Like

Are you using the Vite integration or the integration from the repo you created the issue? The recommendation is to follow the example below created by @akryum.

I am using the Vite integration.

Hi, I was updating my app to Vue 3 (with Vite). The migration is basically complete but I am getting this error in the javascript console (browser):

Uncaught SyntaxError: Identifier 'Accounts' has already been declared (at accounts-base:15:14)

In the server console doesn’t appear anything.

I was searching the problem and I found a similar issue (it says Meteor instead of Accounts) [ERROR] Identifier Meteor has already been declared · Issue #10234 · meteor/meteor · GitHub. But I don’t have much context to solve it, so, any help would be appreciated @akryum.

My app includes the new version of Vuetify along with other libraries such as:

  • Vue Router
  • Vuex
  • Vee Validate
  • Vue Draggable
  • Vue transitions
  • Sass

So, I think it is a very good app example to test the Vite bundler. In case anyone want to try it, you can do it in this branch Feat: Update to Vue 3 by diavrank · Pull Request #5 · diavrank/theory-swe · GitHub . I am waiting for Vuetify 3.1 to include the v-data-table (since I had to change that component for v-table by the moment) and then I will merge it.

1 Like

I updated to Meteor 2.8 and now I got this error:

Uncaught SyntaxError: Unexpected token 'default' (at accounts-base:17:14)

Screen Shot 2022-11-16 at 19.02.24

I was debugging with a simpler app (the one which comes as example from the repo) and it seems that error happen when I import Accounts package in a vue component, as shown:

import { Accounts } from 'meteor/accounts-base';

However, I can still use the package in the client side (since it is a global variable) but it provokes this typescript error:
image

This is necessary to use functions from the client side such as:

  • verifyEmail
  • resetPassword
  • forgotPassword
  • changePassword

I could fix the previous issue with a temporary solution by removing the import statements of Accounts but now, I am getting a new issue, which is:

browser (page is in blank)

Profile.ts
Screen Shot 2022-11-16 at 19.48.40

Profile.ts is the file which contains the Profile collection to do find queries in the client side, like:

return ProfileCollection.find({}).fetch();

I am using Astronomy as ODM for my data layer, and it seems that Vite is complaining as well. In this case, I cannot remove that import statement because it is needed to create the profile collection as shown:

export const Profile = Class.create<ProfileType>({
	name: 'Profile',
	collection: ProfileCollection,
	fields: {
		name: String,
		description: String,
		permissions: [String]
	},
	indexes: {
		name: {
			fields: { name: 1 },
			options: { unique: true }
		}
	},
	helpers: {
		getPermissions() {
			return Meteor.roles.find({ _id: { $in: this.permissions } });
		},
		getPermissionsComplement() {
			return Meteor.roles.find({ _id: { $not: { $in: this.permissions } } });
		}
	},
	events: {
		afterUpdate(event: any) {
			if (event.oldDoc.name !== event.doc.name) {
				Meteor.users.update({ 'profile.profile': event.oldDoc.name }, {
					$set: {
						'profile.profile': event.doc.name
					}
				}, { multi: true });
			}
			const users = Meteor.users.find({ 'profile.profile': event.doc.name }, { fields: { _id: 1 } }).fetch();
			const userIds = users.map(user => user._id);
			// @ts-ignore
			Meteor.roleAssignment.remove({ 'user._id': { $in: userIds } });
			Roles.setUserRoles(userIds, event.currentTarget.permissions, event.currentTarget.name);
		}
	}
});

Any suggestion to solve it @akryum ?

I could solve the other issue by separating the model and the collection in different files, as shown:

ProfileCollection.ts

import { Mongo } from 'meteor/mongo';
import { RoleType } from '/imports/api/Permissions/Permission';

export interface ProfileType {
	_id: string;
	name: string;
	description: string;
	permissions: string[];

	getPermissions(): Mongo.Cursor<MeteorAstronomy.Model<RoleType>>;
	getPermissionsComplement(): Mongo.Cursor<MeteorAstronomy.Model<RoleType>>;
}

export const ProfileCollection = new Mongo.Collection<ProfileType>('profiles');

Profile.ts

import { AstronomyEvent, Class } from 'meteor/jagi:astronomy';
import { ProfileCollection, ProfileType } from '/imports/api/Profiles/ProfileCollection';

export const Profile = Class.create<ProfileType>({
	name: 'Profile',
	collection: ProfileCollection,
	fields: {
		name: String,
		description: String,
		permissions: [String]
	},
	indexes: {
		name: {
			fields: { name: 1 },
			options: { unique: true }
		}
	},
	helpers: {
		getPermissions() {
			return Meteor.roles.find({ _id: { $in: this.permissions } });
		},
		getPermissionsComplement() {
			return Meteor.roles.find({ _id: { $not: { $in: this.permissions } } });
		}
	},
	events: {
		afterUpdate(event: AstronomyEvent<ProfileType>) {
			if (event.oldDoc.name !== event.doc.name) {
				Meteor.users.update({ 'profile.profile': event.oldDoc.name }, {
					$set: {
						'profile.profile': event.doc.name
					}
				}, { multi: true });
			}
			const users = Meteor.users.find({ 'profile.profile': event.doc.name }, { fields: { _id: 1 } }).fetch();
			const userIds = users.map(user => user._id);
			// @ts-ignore
			Meteor.roleAssignment.remove({ 'user._id': { $in: userIds } });
			Roles.setUserRoles(userIds, event.currentTarget.permissions, event.currentTarget.name);
		}
	}
});

So, in this way, I can use the ProfileCollection in the client side to do find queries (when a subscription is made), while I have the model only available in the server side. I think that could help in the security scope (to avoid exposing the collection structure to the client side), but I’d like to know if that was the purpose by Vite? or should it support it? cc: @akryum

By the moment, I could already visualize something in my app :star_struck:

Maybe, it is just missing to fix some things for the migration to Vue 3.

2 Likes

My app is practically migrated and working correctly :heart_eyes: ! It is just missing to fix some minor parts of design (due to the migration to Vuetify 3). I have just one question related to my unit tests. When I run meteor test, it is throwing this error:

W20221120-07:00:13.029(0)? (STDERR) internal/process/esm_loader.js:74
W20221120-07:00:13.051(0)? (STDERR)     internalBinding('errors').triggerUncaughtException(
W20221120-07:00:13.052(0)? (STDERR)                               ^
W20221120-07:00:13.053(0)? (STDERR) 
W20221120-07:00:13.054(0)? (STDERR) Error [ERR_MODULE_NOT_FOUND]: Cannot find package 'vite' imported from /tmp/meteor-test-run3218uq.h76io/.meteor/local/build/programs/server/assets/packages/vite_bundler/worker-dev.mjs
W20221120-07:00:13.055(0)? (STDERR)     at new NodeError (internal/errors.js:322:7)
W20221120-07:00:13.055(0)? (STDERR)     at packageResolve (internal/modules/esm/resolve.js:732:9)
W20221120-07:00:13.056(0)? (STDERR)     at moduleResolve (internal/modules/esm/resolve.js:773:18)
W20221120-07:00:13.056(0)? (STDERR)     at Loader.defaultResolve [as _resolve] (internal/modules/esm/resolve.js:887:11)
W20221120-07:00:13.057(0)? (STDERR)     at Loader.resolve (internal/modules/esm/loader.js:89:40)
W20221120-07:00:13.058(0)? (STDERR)     at Loader.getModuleJob (internal/modules/esm/loader.js:242:28)
W20221120-07:00:13.058(0)? (STDERR)     at ModuleWrap.<anonymous> (internal/modules/esm/module_job.js:76:40)
W20221120-07:00:13.059(0)? (STDERR)     at link (internal/modules/esm/module_job.js:75:36) {
W20221120-07:00:13.060(0)? (STDERR)   code: 'ERR_MODULE_NOT_FOUND'
W20221120-07:00:13.060(0)? (STDERR) }

However, they are passing as shown:

My tests are only for the server, so, maybe vite shouldn’t run. Or is there a way to skip vite in the meteor test command? @akryum

On the other hand, I will be deploying my app and giving feedback about it.

3 Likes

Hi, I got this error in the build of my app with a docker image:

More info here: Error with Vite bundler for Meteor + Vue 3 app · Issue #129 · disney/meteor-base · GitHub

Has anyone faced the same problem?

I could deploy my app by doing the build in my computer and then, upload the bundle to the VM to use it in a custom docker image to run the app:

bundle.dockerfile

FROM node:14.20.1

COPY theory-swe.tar.gz /opt/
WORKDIR /opt
RUN tar -xzf theory-swe.tar.gz && cd bundle/programs/server && npm install && npm run install
WORKDIR /opt/bundle

ENV PORT 3000

EXPOSE 3000

RUN echo 'Starting app...'

CMD ["node", "main.js"]

So, now everything is working well in production.

2 Likes

What did you do to solve the issue with the error The requested module...?

I separated the model and the collection in different files, leaving the collection in the client side and the model in the server side. Here is the solution.