diff --git a/tools/cli/commands.js b/tools/cli/commands.js
index b4d9d9d567..d81c03ffb5 100644
--- a/tools/cli/commands.js
+++ b/tools/cli/commands.js
@@ -1203,71 +1203,85 @@ main.registerCommand({
toIgnore.push(/(\.html|\.js|\.css)/);
}
- try {
- // Prototype option should use local skeleton.
- // Maybe we should use a different skeleton for prototype
- if (options.prototype) throw new Error("Using prototype option");
- // if using the release option we should use the default skeleton
- // using it as it was before 2.x
- if (release.explicit) throw new Error("Using release option");
+ const copyFromLocalSkeleton = async () => {
+ await files.cp_r(
+ skeletonPath,
+ appPath,
+ {
+ transformFilename: function (f) {
+ return transform(f);
+ },
+ transformContents: function (contents, f) {
+ // check if this app is just for prototyping if it is then we need to add autopublish and insecure in the packages file
+ if (/packages/.test(f)) {
+ const prototypePackages = () =>
+ "autopublish # Publish all data to the clients (for prototyping)\n" +
+ "insecure # Allow all DB writes from clients (for prototyping)";
- await setupExampleByURL(`https://github.com/meteor/skel-${skeleton}`);
- } catch (e) {
+ // XXX: if there is the need to add more options maybe we should have a better abstraction for this if-else
+ if (options.prototype) {
+ return Buffer.from(
+ contents.toString().replace(/~prototype~/g, prototypePackages())
+ );
+ } else {
+ return Buffer.from(contents.toString().replace(/~prototype~/g, ""));
+ }
+ }
+ if (/(\.html|\.[jt]sx?|\.css)/.test(f)) {
+ return Buffer.from(transform(contents.toString()));
+ } else {
+ return contents;
+ }
+ },
+ ignore: toIgnore,
+ preserveSymlinks: true,
+ }
+ );
+ };
- if (
- e.message !== "Using prototype option" &&
- e.message !== "Using release option"
- ) {
- // something has happened while creating the app using git clone
- Console.error(
- `Something has happened while creating your app using git clone.
+ // Check if the local skeleton path exists
+ const skeletonPath = files.pathJoin(
+ __dirnameConverted,
+ "..",
+ "static-assets",
+ `skel-${skeleton}`
+ );
+
+ const useLocalSkeleton = files.exists(skeletonPath) ||
+ options.prototype ||
+ release.explicit;
+ if (useLocalSkeleton) {
+ // Use local skeleton
+ await copyFromLocalSkeleton();
+ } else {
+ try {
+ // Prototype option should use local skeleton.
+ // Maybe we should use a different skeleton for prototype
+ if (options.prototype) throw new Error("Using prototype option");
+ // if using the release option we should use the default skeleton
+ // using it as it was before 2.x
+ if (release.explicit) throw new Error("Using release option");
+
+ // If local skeleton doesn't exist, use setupExampleByURL
+ await setupExampleByURL(`https://github.com/meteor/skel-${skeleton}`);
+ } catch (e) {
+ if (
+ e.message !== "Using prototype option" &&
+ e.message !== "Using release option"
+ ) {
+ // something has happened while creating the app using git clone
+ Console.error(
+ `Something has happened while creating your app using git clone.
Will use cached version of skeletons.
Error message: `,
- e.message
- );
+ e.message
+ );
+ }
+ // For prototype or release options, use local skeleton
+ await copyFromLocalSkeleton();
}
-
- // TODO: decide if this should stay here or not.
- await files.cp_r(
- files.pathJoin(
- __dirnameConverted,
- "..",
- "static-assets",
- `skel-${skeleton}`
- ),
- appPath,
- {
- transformFilename: function (f) {
- return transform(f);
- },
- transformContents: function (contents, f) {
- // check if this app is just for prototyping if it is then we need to add autopublish and insecure in the packages file
- if (/packages/.test(f)) {
- const prototypePackages = () =>
- "autopublish # Publish all data to the clients (for prototyping)\n" +
- "insecure # Allow all DB writes from clients (for prototyping)";
-
- // XXX: if there is the need to add more options maybe we should have a better abstraction for this if-else
- if (options.prototype) {
- return Buffer.from(
- contents.toString().replace(/~prototype~/g, prototypePackages())
- );
- } else {
- return Buffer.from(contents.toString().replace(/~prototype~/g, ""));
- }
- }
- if (/(\.html|\.[jt]sx?|\.css)/.test(f)) {
- return Buffer.from(transform(contents.toString()));
- } else {
- return contents;
- }
- },
- ignore: toIgnore,
- preserveSymlinks: true,
- }
- );
- await setupMessages();
}
+ await setupMessages();
Console.info("");
});
diff --git a/tools/static-assets/skel-solid/client/entry-meteor.js b/tools/static-assets/skel-solid/client/entry-meteor.js
index e69de29bb2..0ec3ddc121 100644
--- a/tools/static-assets/skel-solid/client/entry-meteor.js
+++ b/tools/static-assets/skel-solid/client/entry-meteor.js
@@ -0,0 +1,14 @@
+/**
+ * Entrypoint for the Meteor client
+ *
+ * Generally, this file can be left empty. Vite will add imports for
+ * lazy-loaded Meteor packages to this file to ensure they aren't omitted from
+ * the final production bundle.
+ *
+ * Use ./main.js as the primary entrypoint for your client code to take full
+ * advantage of Vite's plugin and build system.
+ *
+ * This can also be a good place to put code that you don't want Vite to
+ * process, for example, if you run into a compatibility issue or need to use
+ * nested imports which Vite doesn't support.
+ */
\ No newline at end of file
diff --git a/tools/static-assets/skel-solid/client/main.js b/tools/static-assets/skel-solid/client/main.js
new file mode 100644
index 0000000000..44bcc64d55
--- /dev/null
+++ b/tools/static-assets/skel-solid/client/main.js
@@ -0,0 +1 @@
+import '../imports/ui/main';
\ No newline at end of file
diff --git a/tools/static-assets/skel-solid/client/main.jsx b/tools/static-assets/skel-solid/client/main.jsx
deleted file mode 100644
index 97d382a9bd..0000000000
--- a/tools/static-assets/skel-solid/client/main.jsx
+++ /dev/null
@@ -1 +0,0 @@
-// main entry point is in imports/ui/main.jsx
diff --git a/tools/static-assets/skel-solid/client/main.css b/tools/static-assets/skel-solid/imports/ui/main.css
similarity index 100%
rename from tools/static-assets/skel-solid/client/main.css
rename to tools/static-assets/skel-solid/imports/ui/main.css
diff --git a/tools/static-assets/skel-solid/imports/ui/main.jsx b/tools/static-assets/skel-solid/imports/ui/main.jsx
index 99eb6c43d7..044f1aee69 100644
--- a/tools/static-assets/skel-solid/imports/ui/main.jsx
+++ b/tools/static-assets/skel-solid/imports/ui/main.jsx
@@ -2,6 +2,7 @@
import { render } from 'solid-js/web';
import { App } from './App';
import { Meteor } from "meteor/meteor";
+import './main.css';
Meteor.startup(() => {
render(() => , document.getElementById('root'));
diff --git a/tools/static-assets/skel-solid/server/entry-meteor.js b/tools/static-assets/skel-solid/server/entry-meteor.js
index e69de29bb2..8a066f8e94 100644
--- a/tools/static-assets/skel-solid/server/entry-meteor.js
+++ b/tools/static-assets/skel-solid/server/entry-meteor.js
@@ -0,0 +1,12 @@
+/**
+ * Entrypoint for the Meteor server
+ * Generally, this file can be left empty. Vite will add imports for your app's
+ * server bundle here during both development and production build.
+ *
+ * Use ./main.js as the primary entrypoint for your app to take full advantage
+ * of Vite's plugin and build system.
+ *
+ * This can also be a good place to put code that you don't want Vite to
+ * process, for example, if you run into a compatibility issue or need to use
+ * nested imports.
+ */
\ No newline at end of file
diff --git a/tools/static-assets/skel-solid/vite.config.js b/tools/static-assets/skel-solid/vite.config.mjs
similarity index 91%
rename from tools/static-assets/skel-solid/vite.config.js
rename to tools/static-assets/skel-solid/vite.config.mjs
index 5752984348..e0215dbb10 100644
--- a/tools/static-assets/skel-solid/vite.config.js
+++ b/tools/static-assets/skel-solid/vite.config.mjs
@@ -8,7 +8,7 @@ export default defineConfig({
solidPlugin(),
solidSvg({ defaultExport: 'component' }),
meteor({
- clientEntry: 'imports/ui/main.jsx',
+ clientEntry: 'client/main.js',
serverEntry: 'server/main.js',
enableExperimentalFeatures: true,
stubValidation: {
diff --git a/tools/static-assets/skel-vue/client/entry-meteor.js b/tools/static-assets/skel-vue/client/entry-meteor.js
index e69de29bb2..0ec3ddc121 100644
--- a/tools/static-assets/skel-vue/client/entry-meteor.js
+++ b/tools/static-assets/skel-vue/client/entry-meteor.js
@@ -0,0 +1,14 @@
+/**
+ * Entrypoint for the Meteor client
+ *
+ * Generally, this file can be left empty. Vite will add imports for
+ * lazy-loaded Meteor packages to this file to ensure they aren't omitted from
+ * the final production bundle.
+ *
+ * Use ./main.js as the primary entrypoint for your client code to take full
+ * advantage of Vite's plugin and build system.
+ *
+ * This can also be a good place to put code that you don't want Vite to
+ * process, for example, if you run into a compatibility issue or need to use
+ * nested imports which Vite doesn't support.
+ */
\ No newline at end of file
diff --git a/tools/static-assets/skel-vue/client/main.css b/tools/static-assets/skel-vue/client/main.css
deleted file mode 100644
index b5c61c9567..0000000000
--- a/tools/static-assets/skel-vue/client/main.css
+++ /dev/null
@@ -1,3 +0,0 @@
-@tailwind base;
-@tailwind components;
-@tailwind utilities;
diff --git a/tools/static-assets/skel-vue/client/main.js b/tools/static-assets/skel-vue/client/main.js
index 97d382a9bd..403d8a2d2a 100644
--- a/tools/static-assets/skel-vue/client/main.js
+++ b/tools/static-assets/skel-vue/client/main.js
@@ -1 +1 @@
-// main entry point is in imports/ui/main.jsx
+import '../imports/ui/main'
\ No newline at end of file
diff --git a/tools/static-assets/skel-vue/imports/ui/App.vue b/tools/static-assets/skel-vue/imports/ui/App.vue
index 7a775391cb..19a68a1ea1 100644
--- a/tools/static-assets/skel-vue/imports/ui/App.vue
+++ b/tools/static-assets/skel-vue/imports/ui/App.vue
@@ -1,5 +1,5 @@
diff --git a/tools/static-assets/skel-vue/imports/ui/AppMenu.vue b/tools/static-assets/skel-vue/imports/ui/components/AppMenu.vue
similarity index 100%
rename from tools/static-assets/skel-vue/imports/ui/AppMenu.vue
rename to tools/static-assets/skel-vue/imports/ui/components/AppMenu.vue
diff --git a/tools/static-assets/skel-vue/imports/ui/Hello.vue b/tools/static-assets/skel-vue/imports/ui/components/Hello.vue
similarity index 100%
rename from tools/static-assets/skel-vue/imports/ui/Hello.vue
rename to tools/static-assets/skel-vue/imports/ui/components/Hello.vue
diff --git a/tools/static-assets/skel-vue/imports/ui/Info.vue b/tools/static-assets/skel-vue/imports/ui/components/Info.vue
similarity index 100%
rename from tools/static-assets/skel-vue/imports/ui/Info.vue
rename to tools/static-assets/skel-vue/imports/ui/components/Info.vue
diff --git a/tools/static-assets/skel-vue/imports/ui/main.css b/tools/static-assets/skel-vue/imports/ui/main.css
new file mode 100644
index 0000000000..a461c505f1
--- /dev/null
+++ b/tools/static-assets/skel-vue/imports/ui/main.css
@@ -0,0 +1 @@
+@import "tailwindcss";
\ No newline at end of file
diff --git a/tools/static-assets/skel-vue/imports/ui/main.js b/tools/static-assets/skel-vue/imports/ui/main.js
index e3500841ea..f568d94ebf 100644
--- a/tools/static-assets/skel-vue/imports/ui/main.js
+++ b/tools/static-assets/skel-vue/imports/ui/main.js
@@ -2,6 +2,7 @@ import { Meteor } from 'meteor/meteor'
import { createApp } from 'vue'
import { VueMeteor } from 'vue-meteor-tracker'
+import './main.css'
import App from './App.vue'
import { router } from './router'
diff --git a/tools/static-assets/skel-vue/imports/ui/router.js b/tools/static-assets/skel-vue/imports/ui/router.js
index b271e02d29..00ed2a51e1 100644
--- a/tools/static-assets/skel-vue/imports/ui/router.js
+++ b/tools/static-assets/skel-vue/imports/ui/router.js
@@ -1,6 +1,6 @@
import { createRouter, createWebHistory } from 'vue-router'
-import Home from './Home.vue'
-import About from './About.vue'
+import Home from './views/Home.vue'
+import About from './views/About.vue'
export const router = createRouter({
history: createWebHistory(),
diff --git a/tools/static-assets/skel-vue/imports/ui/About.vue b/tools/static-assets/skel-vue/imports/ui/views/About.vue
similarity index 100%
rename from tools/static-assets/skel-vue/imports/ui/About.vue
rename to tools/static-assets/skel-vue/imports/ui/views/About.vue
diff --git a/tools/static-assets/skel-vue/imports/ui/Home.vue b/tools/static-assets/skel-vue/imports/ui/views/Home.vue
similarity index 60%
rename from tools/static-assets/skel-vue/imports/ui/Home.vue
rename to tools/static-assets/skel-vue/imports/ui/views/Home.vue
index 0473845661..38e3688bee 100644
--- a/tools/static-assets/skel-vue/imports/ui/Home.vue
+++ b/tools/static-assets/skel-vue/imports/ui/views/Home.vue
@@ -1,6 +1,6 @@
diff --git a/tools/static-assets/skel-vue/package.json b/tools/static-assets/skel-vue/package.json
index 09146eee03..e77cf9ea19 100644
--- a/tools/static-assets/skel-vue/package.json
+++ b/tools/static-assets/skel-vue/package.json
@@ -17,6 +17,7 @@
"vue-router": "^4.2.5"
},
"meteor": {
+ "modern": true,
"mainModule": {
"client": "client/entry-meteor.js",
"server": "server/entry-meteor.js"
@@ -25,11 +26,10 @@
},
"devDependencies": {
"@types/meteor": "^2.9.7",
+ "@tailwindcss/vite": "^4.1.11",
"@vitejs/plugin-vue": "^5.2.1",
- "autoprefixer": "^10.4.16",
"meteor-vite": "^3.2.1",
- "postcss": "^8.4.31",
- "tailwindcss": "^3.3.5",
+ "tailwindcss": "^4.1.11",
"vite": "^6.0.11"
}
}
diff --git a/tools/static-assets/skel-vue/postcss.config.js b/tools/static-assets/skel-vue/postcss.config.js
deleted file mode 100644
index 33ad091d26..0000000000
--- a/tools/static-assets/skel-vue/postcss.config.js
+++ /dev/null
@@ -1,6 +0,0 @@
-module.exports = {
- plugins: {
- tailwindcss: {},
- autoprefixer: {},
- },
-}
diff --git a/tools/static-assets/skel-vue/server/entry-meteor.js b/tools/static-assets/skel-vue/server/entry-meteor.js
index e69de29bb2..8a066f8e94 100644
--- a/tools/static-assets/skel-vue/server/entry-meteor.js
+++ b/tools/static-assets/skel-vue/server/entry-meteor.js
@@ -0,0 +1,12 @@
+/**
+ * Entrypoint for the Meteor server
+ * Generally, this file can be left empty. Vite will add imports for your app's
+ * server bundle here during both development and production build.
+ *
+ * Use ./main.js as the primary entrypoint for your app to take full advantage
+ * of Vite's plugin and build system.
+ *
+ * This can also be a good place to put code that you don't want Vite to
+ * process, for example, if you run into a compatibility issue or need to use
+ * nested imports.
+ */
\ No newline at end of file
diff --git a/tools/static-assets/skel-vue/tailwind.config.js b/tools/static-assets/skel-vue/tailwind.config.js
deleted file mode 100644
index 72c950fc84..0000000000
--- a/tools/static-assets/skel-vue/tailwind.config.js
+++ /dev/null
@@ -1,8 +0,0 @@
-/** @type {import('tailwindcss').Config} */
-module.exports = {
- content: ['./imports/ui/**/*.{vue,js,ts,jsx,tsx}', './client/*.html'],
- theme: {
- extend: {},
- },
- plugins: [],
-}
diff --git a/tools/static-assets/skel-vue/vite.config.js b/tools/static-assets/skel-vue/vite.config.mjs
similarity index 80%
rename from tools/static-assets/skel-vue/vite.config.js
rename to tools/static-assets/skel-vue/vite.config.mjs
index dd08ccf69d..f955234c6a 100644
--- a/tools/static-assets/skel-vue/vite.config.js
+++ b/tools/static-assets/skel-vue/vite.config.mjs
@@ -1,12 +1,14 @@
-import { defineConfig } from 'vite';
import vue from '@vitejs/plugin-vue';
+import tailwindcss from '@tailwindcss/vite';
+import { defineConfig } from 'vite';
import { meteor } from 'meteor-vite/plugin';
export default defineConfig({
plugins: [
vue(),
+ tailwindcss(),
meteor({
- clientEntry: 'imports/ui/main.js',
+ clientEntry: 'client/main.js',
serverEntry: 'server/main.js',
enableExperimentalFeatures: true,
stubValidation: {