diff --git a/tools/cli/commands.js b/tools/cli/commands.js
index 95df9286d2..a50cd06c07 100644
--- a/tools/cli/commands.js
+++ b/tools/cli/commands.js
@@ -517,6 +517,7 @@ main.registerCommand({
minimal: { type: Boolean },
full: { type: Boolean },
react: { type: Boolean },
+ vue: { type: Boolean },
typescript: { type: Boolean },
},
catalogRefresh: new catalog.Refresh.Never()
@@ -770,6 +771,8 @@ main.registerCommand({
skelName += "-full";
} else if (options.react) {
skelName += "-react";
+ } else if (options.vue) {
+ skelName += "-vue";
} else if (options.typescript) {
skelName += "-typescript";
}
@@ -886,8 +889,9 @@ main.registerCommand({
! options.minimal &&
! options.full &&
! options.react &&
+ ! options.vue &&
! options.typescript) {
- // Notify people about --bare, --minimal, --full, --react, and --typescript.
+ // Notify people about --bare, --minimal, --full, --react, --vue, and --typescript.
Console.info([
"",
"To start with a different app template, try one of the following:",
@@ -898,6 +902,7 @@ main.registerCommand({
cmd("meteor create --minimal # to create an app with as few Meteor packages as possible");
cmd("meteor create --full # to create a more complete scaffolded app");
cmd("meteor create --react # to create a basic React-based app");
+ cmd("meteor create --vue # to create a basic Vue-based app");
cmd("meteor create --typescript # to create an app using TypeScript and React");
}
diff --git a/tools/static-assets/skel-vue/.gitignore b/tools/static-assets/skel-vue/.gitignore
new file mode 100644
index 0000000000..c2658d7d1b
--- /dev/null
+++ b/tools/static-assets/skel-vue/.gitignore
@@ -0,0 +1 @@
+node_modules/
diff --git a/tools/static-assets/skel-vue/.meteor/.gitignore b/tools/static-assets/skel-vue/.meteor/.gitignore
new file mode 100644
index 0000000000..4083037423
--- /dev/null
+++ b/tools/static-assets/skel-vue/.meteor/.gitignore
@@ -0,0 +1 @@
+local
diff --git a/tools/static-assets/skel-vue/.meteor/packages b/tools/static-assets/skel-vue/.meteor/packages
new file mode 100644
index 0000000000..83be6b3a62
--- /dev/null
+++ b/tools/static-assets/skel-vue/.meteor/packages
@@ -0,0 +1,24 @@
+# Meteor packages used by this project, one per line.
+# Check this file (and the other files in this directory) into your repository.
+#
+# 'meteor add' and 'meteor remove' will edit this file for you,
+# but you can also edit it by hand.
+
+meteor-base # Packages every Meteor app needs to have
+mobile-experience # Packages for a great mobile UX
+mongo # The database Meteor supports right now
+reactive-var # Reactive variable for tracker
+
+standard-minifier-css # CSS minifier run for production mode
+standard-minifier-js # JS minifier run for production mode
+es5-shim # ECMAScript 5 compatibility for older browsers
+ecmascript # Enable ECMAScript2015+ syntax in app code
+typescript # Enable TypeScript syntax in .ts and .tsx modules
+shell-server # Server-side component of the `meteor shell` command
+
+tracker # Dependency tracker to allow reactive callbacks
+static-html # Define static page content in .html files
+akryum:vue-component # Vue-CLI template to publish components
+
+meteortesting:mocha # A package for writing and running your meteor app and package tests with mocha
+johanbrook:publication-collector # Test a Meteor publication by collecting its output
diff --git a/tools/static-assets/skel-vue/.meteor/platforms b/tools/static-assets/skel-vue/.meteor/platforms
new file mode 100644
index 0000000000..efeba1b50c
--- /dev/null
+++ b/tools/static-assets/skel-vue/.meteor/platforms
@@ -0,0 +1,2 @@
+server
+browser
diff --git a/tools/static-assets/skel-vue/package.json b/tools/static-assets/skel-vue/package.json
new file mode 100644
index 0000000000..97a009989c
--- /dev/null
+++ b/tools/static-assets/skel-vue/package.json
@@ -0,0 +1,23 @@
+{
+ "name": "skel",
+ "private": true,
+ "scripts": {
+ "start": "meteor run",
+ "test": "meteor test --once --driver-package meteortesting:mocha",
+ "test-app": "TEST_WATCH=1 meteor test --full-app --driver-package meteortesting:mocha",
+ "visualize": "meteor --production --extra-packages bundle-visualizer"
+ },
+ "dependencies": {
+ "@babel/runtime": "^7.8.3",
+ "meteor-node-stubs": "^1.0.0",
+ "vue": "^2.6.11",
+ "vue-meteor-tracker": "^2.0.0-beta.5"
+ },
+ "meteor": {
+ "mainModule": {
+ "client": "src/client.js",
+ "server": "src/server.js"
+ },
+ "testModule": "tests/main.js"
+ }
+}
diff --git a/tools/static-assets/skel-vue/src/App.vue b/tools/static-assets/skel-vue/src/App.vue
new file mode 100644
index 0000000000..e126098ccb
--- /dev/null
+++ b/tools/static-assets/skel-vue/src/App.vue
@@ -0,0 +1,26 @@
+
+
+
Welcome to Meteor!
+
+
+
+
+
+
+
+
diff --git a/tools/static-assets/skel-vue/src/client.js b/tools/static-assets/skel-vue/src/client.js
new file mode 100644
index 0000000000..835acaec7b
--- /dev/null
+++ b/tools/static-assets/skel-vue/src/client.js
@@ -0,0 +1,12 @@
+import Vue from 'vue'
+
+import './plugins'
+
+import App from './App.vue'
+
+Meteor.startup(() => {
+ new Vue({
+ el: '#app',
+ ...App,
+ })
+})
diff --git a/tools/static-assets/skel-vue/src/collections/Links.js b/tools/static-assets/skel-vue/src/collections/Links.js
new file mode 100644
index 0000000000..de6a43c4a4
--- /dev/null
+++ b/tools/static-assets/skel-vue/src/collections/Links.js
@@ -0,0 +1,3 @@
+import { Mongo } from 'meteor/mongo';
+
+export default new Mongo.Collection('links');
diff --git a/tools/static-assets/skel-vue/src/collections/Links.tests.js b/tools/static-assets/skel-vue/src/collections/Links.tests.js
new file mode 100644
index 0000000000..0bc5b437dd
--- /dev/null
+++ b/tools/static-assets/skel-vue/src/collections/Links.tests.js
@@ -0,0 +1,24 @@
+// Tests for the behavior of the links collection
+//
+// https://guide.meteor.com/testing.html
+
+import { Meteor } from 'meteor/meteor';
+import { assert } from 'chai';
+import Links from './links.js';
+
+if (Meteor.isServer) {
+ describe('links collection', function () {
+ it('insert correctly', function () {
+ const linkId = Links.insert({
+ title: 'meteor homepage',
+ url: 'https://www.meteor.com',
+ });
+ const added = Links.find({ _id: linkId });
+ const collectionName = added._getCollectionName();
+ const count = added.count();
+
+ assert.equal(collectionName, 'links');
+ assert.equal(count, 1);
+ });
+ });
+}
diff --git a/tools/static-assets/skel-vue/src/components/Hello.vue b/tools/static-assets/skel-vue/src/components/Hello.vue
new file mode 100644
index 0000000000..64947eb06a
--- /dev/null
+++ b/tools/static-assets/skel-vue/src/components/Hello.vue
@@ -0,0 +1,27 @@
+
+
+
+
You've pressed the button {{counter}} times.
+
+
+
+
+
+
diff --git a/tools/static-assets/skel-vue/src/components/Info.vue b/tools/static-assets/skel-vue/src/components/Info.vue
new file mode 100644
index 0000000000..f20fc4c800
--- /dev/null
+++ b/tools/static-assets/skel-vue/src/components/Info.vue
@@ -0,0 +1,55 @@
+
+
+
+
+
+
+
diff --git a/tools/static-assets/skel-vue/src/fixtures.js b/tools/static-assets/skel-vue/src/fixtures.js
new file mode 100644
index 0000000000..f629f5ca0b
--- /dev/null
+++ b/tools/static-assets/skel-vue/src/fixtures.js
@@ -0,0 +1,32 @@
+import { Meteor } from 'meteor/meteor';
+import Links from './collections/Links.js';
+
+Meteor.startup(() => {
+ // if the Links collection is empty
+ if (Links.find().count() === 0) {
+ const data = [
+ {
+ title: 'Do the Tutorial',
+ url: 'https://www.meteor.com/try',
+ createdAt: new Date(),
+ },
+ {
+ title: 'Follow the Guide',
+ url: 'http://guide.meteor.com',
+ createdAt: new Date(),
+ },
+ {
+ title: 'Read the Docs',
+ url: 'https://docs.meteor.com',
+ createdAt: new Date(),
+ },
+ {
+ title: 'Discussions',
+ url: 'https://forums.meteor.com',
+ createdAt: new Date(),
+ },
+ ];
+
+ data.forEach(link => Links.insert(link));
+ }
+});
diff --git a/tools/static-assets/skel-vue/src/main.html b/tools/static-assets/skel-vue/src/main.html
new file mode 100644
index 0000000000..944bc69810
--- /dev/null
+++ b/tools/static-assets/skel-vue/src/main.html
@@ -0,0 +1,7 @@
+
+ skel
+
+
+
+
+
diff --git a/tools/static-assets/skel-vue/src/methods/createLink.js b/tools/static-assets/skel-vue/src/methods/createLink.js
new file mode 100644
index 0000000000..876f710978
--- /dev/null
+++ b/tools/static-assets/skel-vue/src/methods/createLink.js
@@ -0,0 +1,16 @@
+import { Meteor } from 'meteor/meteor';
+import { check } from 'meteor/check';
+import Links from '../collections/Links.js';
+
+Meteor.methods({
+ 'createLink'(title, url) {
+ check(url, String);
+ check(title, String);
+
+ return Links.insert({
+ url,
+ title,
+ createdAt: new Date(),
+ });
+ },
+});
diff --git a/tools/static-assets/skel-vue/src/methods/createLink.tests.js b/tools/static-assets/skel-vue/src/methods/createLink.tests.js
new file mode 100644
index 0000000000..d899a7338f
--- /dev/null
+++ b/tools/static-assets/skel-vue/src/methods/createLink.tests.js
@@ -0,0 +1,20 @@
+import { Meteor } from 'meteor/meteor';
+import { assert } from 'chai';
+import Links from '../collections/Links.js';
+import './methods.js';
+
+if (Meteor.isServer) {
+ describe('method: createLink', function () {
+ beforeEach(function () {
+ Links.remove({});
+ });
+
+ it('can add a new link', function () {
+ const addLink = Meteor.server.method_handlers['createLink'];
+
+ addLink.apply({}, ['meteor.com', 'https://www.meteor.com']);
+
+ assert.equal(Links.find().count(), 1);
+ });
+ });
+}
diff --git a/tools/static-assets/skel-vue/src/methods/index.js b/tools/static-assets/skel-vue/src/methods/index.js
new file mode 100644
index 0000000000..c52403a2e8
--- /dev/null
+++ b/tools/static-assets/skel-vue/src/methods/index.js
@@ -0,0 +1 @@
+import './createLink'
diff --git a/tools/static-assets/skel-vue/src/plugins.js b/tools/static-assets/skel-vue/src/plugins.js
new file mode 100644
index 0000000000..eb976c92e5
--- /dev/null
+++ b/tools/static-assets/skel-vue/src/plugins.js
@@ -0,0 +1,4 @@
+import Vue from 'vue'
+import VueMeteorTracker from 'vue-meteor-tracker'
+
+Vue.use(VueMeteorTracker)
diff --git a/tools/static-assets/skel-vue/src/publications/index.js b/tools/static-assets/skel-vue/src/publications/index.js
new file mode 100644
index 0000000000..d161b580e7
--- /dev/null
+++ b/tools/static-assets/skel-vue/src/publications/index.js
@@ -0,0 +1 @@
+import './links'
diff --git a/tools/static-assets/skel-vue/src/publications/links.js b/tools/static-assets/skel-vue/src/publications/links.js
new file mode 100644
index 0000000000..f085d75045
--- /dev/null
+++ b/tools/static-assets/skel-vue/src/publications/links.js
@@ -0,0 +1,6 @@
+import { Meteor } from 'meteor/meteor';
+import Links from '../collections/Links.js';
+
+Meteor.publish('links', function () {
+ return Links.find();
+});
diff --git a/tools/static-assets/skel-vue/src/publications/links.tests.js b/tools/static-assets/skel-vue/src/publications/links.tests.js
new file mode 100644
index 0000000000..37f337c869
--- /dev/null
+++ b/tools/static-assets/skel-vue/src/publications/links.tests.js
@@ -0,0 +1,22 @@
+import { assert } from 'chai'
+import { PublicationCollector } from 'meteor/johanbrook:publication-collector'
+import Links from '../collections/Links.js'
+import './publications.js'
+
+describe('Publish links', function () {
+ beforeEach(function () {
+ Links.remove({})
+ Links.insert({
+ title: 'meteor homepage',
+ url: 'https://www.meteor.com'
+ })
+ })
+
+ it('sends all links', function (done) {
+ const collector = new PublicationCollector()
+ collector.collect('links', (collections) => {
+ assert.equal(collections.links.length, 1)
+ done()
+ })
+ })
+})
diff --git a/tools/static-assets/skel-vue/src/server.js b/tools/static-assets/skel-vue/src/server.js
new file mode 100644
index 0000000000..c48a837760
--- /dev/null
+++ b/tools/static-assets/skel-vue/src/server.js
@@ -0,0 +1,3 @@
+import './fixtures'
+import './methods'
+import './publications'
diff --git a/tools/static-assets/skel-vue/tests/main.js b/tools/static-assets/skel-vue/tests/main.js
new file mode 100644
index 0000000000..6d2a32e09d
--- /dev/null
+++ b/tools/static-assets/skel-vue/tests/main.js
@@ -0,0 +1,20 @@
+import assert from "assert";
+
+describe("skel", function () {
+ it("package.json has correct name", async function () {
+ const { name } = await import("../package.json");
+ assert.strictEqual(name, "skel");
+ });
+
+ if (Meteor.isClient) {
+ it("client is not server", function () {
+ assert.strictEqual(Meteor.isServer, false);
+ });
+ }
+
+ if (Meteor.isServer) {
+ it("server is not client", function () {
+ assert.strictEqual(Meteor.isClient, false);
+ });
+ }
+});