├── .gitignore ├── .eslintignore ├── packages ├── vue-less │ ├── .gitignore │ ├── .versions │ ├── package.js │ ├── README.md │ └── vue-less.js ├── vue-pug │ ├── .gitignore │ ├── .versions │ ├── vue-pug.js │ ├── README.md │ └── package.js ├── vue-sass │ ├── .gitignore │ ├── .versions │ ├── package.js │ ├── README.md │ └── vue-sass.js ├── vue-ssr │ ├── .gitignore │ ├── npm.json │ ├── CHANGELOG.md │ ├── package.js │ ├── .versions │ ├── server │ │ ├── context.js │ │ ├── data.js │ │ └── index.js │ └── README.md ├── vue-coffee │ ├── .gitignore │ ├── .versions │ ├── package.js │ ├── README.md │ └── vue-coffee.js ├── vue-component │ ├── .gitignore │ ├── global_component_file_tree.png │ ├── plugin │ │ ├── plugin.js │ │ ├── regexps.js │ │ ├── dev-server.js │ │ ├── post-css.js │ │ ├── utils.js │ │ ├── tag-handler.js │ │ └── vue-compiler.js │ ├── .versions │ ├── package.js │ ├── CHANGELOG.md │ └── README.md ├── vue-router2 │ ├── .gitignore │ ├── npm.json │ ├── CHANGELOG.md │ ├── .versions │ ├── package.js │ ├── client │ │ └── client.js │ ├── plugin │ │ └── plugin.js │ └── README.md ├── vue-stylus │ ├── .gitignore │ ├── .versions │ ├── package.js │ ├── README.md │ └── vue-stylus.js ├── vue-component-dev-client │ ├── .gitignore │ ├── client │ │ ├── buffer.js │ │ ├── vue2-hot.js │ │ ├── dev-client.js │ │ └── vue-hot.js │ ├── README.md │ ├── package.js │ └── .versions ├── vue-component-dev-server │ ├── README.md │ ├── package.js │ ├── .versions │ └── server │ │ └── main.js ├── npm-check │ ├── .versions │ ├── package.js │ ├── README.md │ ├── npm-check.js │ └── lib.js └── vue-blaze-template │ ├── package.js │ ├── README.md │ ├── .versions │ └── vue-render-blaze.js ├── logo.png ├── .babelrc ├── vue+meteor.png ├── with-async.png ├── .github └── FUNDING.yml ├── withou-async.png ├── .gitattributes ├── package.json ├── .eslintrc.js ├── logo.svg ├── README.md └── vue+meteor.svg /.gitignore: -------------------------------------------------------------------------------- 1 | node_modules/ 2 | -------------------------------------------------------------------------------- /.eslintignore: -------------------------------------------------------------------------------- 1 | node_modules 2 | -------------------------------------------------------------------------------- /packages/vue-less/.gitignore: -------------------------------------------------------------------------------- 1 | .npm 2 | -------------------------------------------------------------------------------- /packages/vue-pug/.gitignore: -------------------------------------------------------------------------------- 1 | .npm 2 | -------------------------------------------------------------------------------- /packages/vue-sass/.gitignore: -------------------------------------------------------------------------------- 1 | .npm 2 | -------------------------------------------------------------------------------- /packages/vue-ssr/.gitignore: -------------------------------------------------------------------------------- 1 | .npm 2 | -------------------------------------------------------------------------------- /packages/vue-coffee/.gitignore: -------------------------------------------------------------------------------- 1 | .npm 2 | -------------------------------------------------------------------------------- /packages/vue-component/.gitignore: -------------------------------------------------------------------------------- 1 | .npm 2 | -------------------------------------------------------------------------------- /packages/vue-router2/.gitignore: -------------------------------------------------------------------------------- 1 | .npm 2 | -------------------------------------------------------------------------------- /packages/vue-stylus/.gitignore: -------------------------------------------------------------------------------- 1 | .npm 2 | -------------------------------------------------------------------------------- /packages/vue-component-dev-client/.gitignore: -------------------------------------------------------------------------------- 1 | .npm 2 | -------------------------------------------------------------------------------- /logo.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/meteor-vue/vue-meteor/HEAD/logo.png -------------------------------------------------------------------------------- /.babelrc: -------------------------------------------------------------------------------- 1 | { 2 | "presets": [ 3 | "env", 4 | "stage-2" 5 | ] 6 | } 7 | -------------------------------------------------------------------------------- /vue+meteor.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/meteor-vue/vue-meteor/HEAD/vue+meteor.png -------------------------------------------------------------------------------- /with-async.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/meteor-vue/vue-meteor/HEAD/with-async.png -------------------------------------------------------------------------------- /.github/FUNDING.yml: -------------------------------------------------------------------------------- 1 | # These are supported funding model platforms 2 | 3 | github: Akryum 4 | -------------------------------------------------------------------------------- /withou-async.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/meteor-vue/vue-meteor/HEAD/withou-async.png -------------------------------------------------------------------------------- /packages/vue-component-dev-client/client/buffer.js: -------------------------------------------------------------------------------- 1 | global.Buffer = global.Buffer || require('buffer').Buffer 2 | -------------------------------------------------------------------------------- /packages/vue-router2/npm.json: -------------------------------------------------------------------------------- 1 | { 2 | "dependencies": { 3 | "vue": "^2.5.0", 4 | "vue-router": "^3.0.0" 5 | } 6 | } 7 | -------------------------------------------------------------------------------- /packages/vue-component-dev-client/README.md: -------------------------------------------------------------------------------- 1 | Used by [akryum:vue-component](https://github.com/Akryum/meteor-vue-component/tree/master/packages/vue-component). 2 | -------------------------------------------------------------------------------- /packages/vue-component-dev-server/README.md: -------------------------------------------------------------------------------- 1 | Used by [akryum:vue-component](https://github.com/Akryum/meteor-vue-component/tree/master/packages/vue-component). 2 | -------------------------------------------------------------------------------- /packages/vue-component/global_component_file_tree.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/meteor-vue/vue-meteor/HEAD/packages/vue-component/global_component_file_tree.png -------------------------------------------------------------------------------- /packages/vue-ssr/npm.json: -------------------------------------------------------------------------------- 1 | { 2 | "dependencies": { 3 | "vue": "2.2.4", 4 | "vue-router": "^2.3.0", 5 | "vue-meteor-tracker": "^1.2.0" 6 | } 7 | } 8 | -------------------------------------------------------------------------------- /packages/vue-ssr/CHANGELOG.md: -------------------------------------------------------------------------------- 1 | # Changelog 2 | 3 | ## v0.2.0 - 2017-05-01 4 | 5 | - You can now inject arbitrary JS to the generated HTML by passing an object with `app` and `js` attribute to `VueSSR.createApp`. 6 | 7 | -------------------------------------------------------------------------------- /packages/vue-component/plugin/plugin.js: -------------------------------------------------------------------------------- 1 | Plugin.registerCompiler({ 2 | extensions: ['vue'], 3 | filenames: [IGNORE_FILE], 4 | }, () => new VueComponentCompiler()) 5 | 6 | global.vue = global.vue || {} 7 | global.vue.lang = global.vue.lang || {} 8 | -------------------------------------------------------------------------------- /packages/vue-router2/CHANGELOG.md: -------------------------------------------------------------------------------- 1 | # Changelog 2 | 3 | ## 0.1.0 4 | 5 | - **[BREAKING CHANGE]** The API changed to better self-explain what it does (help create a VueRouter instance). 6 | - `Router` => `RouterFactory` 7 | - `router.start()` => `routerFactory.create()` 8 | 9 | ## 0.0.1 10 | 11 | - Supports vue-router 2.x 12 | -------------------------------------------------------------------------------- /packages/vue-pug/.versions: -------------------------------------------------------------------------------- 1 | akryum:vue-pug@0.1.0 2 | babel-compiler@7.0.0 3 | babel-runtime@1.2.2 4 | dynamic-import@0.3.0 5 | ecmascript@0.10.0 6 | ecmascript-runtime@0.5.0 7 | ecmascript-runtime-client@0.6.0 8 | ecmascript-runtime-server@0.5.0 9 | http@1.4.0 10 | meteor@1.8.2 11 | modules@0.11.3 12 | modules-runtime@0.9.2 13 | promise@0.10.1 14 | url@1.2.0 15 | -------------------------------------------------------------------------------- /packages/npm-check/.versions: -------------------------------------------------------------------------------- 1 | akryum:npm-check@0.1.0 2 | babel-compiler@7.0.0 3 | babel-runtime@1.2.2 4 | dynamic-import@0.3.0 5 | ecmascript@0.10.0 6 | ecmascript-runtime@0.5.0 7 | ecmascript-runtime-client@0.6.0 8 | ecmascript-runtime-server@0.5.0 9 | http@1.4.0 10 | meteor@1.8.2 11 | modules@0.11.3 12 | modules-runtime@0.9.2 13 | promise@0.10.1 14 | url@1.2.0 15 | -------------------------------------------------------------------------------- /packages/vue-less/.versions: -------------------------------------------------------------------------------- 1 | akryum:vue-less@0.1.0 2 | babel-compiler@7.0.0 3 | babel-runtime@1.2.2 4 | dynamic-import@0.3.0 5 | ecmascript@0.10.0 6 | ecmascript-runtime@0.5.0 7 | ecmascript-runtime-client@0.6.0 8 | ecmascript-runtime-server@0.5.0 9 | http@1.4.0 10 | meteor@1.8.2 11 | modules@0.11.3 12 | modules-runtime@0.9.2 13 | promise@0.10.1 14 | url@1.2.0 15 | -------------------------------------------------------------------------------- /packages/vue-sass/.versions: -------------------------------------------------------------------------------- 1 | akryum:vue-sass@0.1.0 2 | babel-compiler@7.0.0 3 | babel-runtime@1.2.2 4 | dynamic-import@0.3.0 5 | ecmascript@0.10.0 6 | ecmascript-runtime@0.5.0 7 | ecmascript-runtime-client@0.6.0 8 | ecmascript-runtime-server@0.5.0 9 | http@1.4.0 10 | meteor@1.8.2 11 | modules@0.11.3 12 | modules-runtime@0.9.2 13 | promise@0.10.1 14 | url@1.2.0 15 | -------------------------------------------------------------------------------- /packages/vue-stylus/.versions: -------------------------------------------------------------------------------- 1 | akryum:vue-stylus@0.1.0 2 | babel-compiler@7.0.0 3 | babel-runtime@1.2.2 4 | dynamic-import@0.3.0 5 | ecmascript@0.10.0 6 | ecmascript-runtime@0.5.0 7 | ecmascript-runtime-client@0.6.0 8 | ecmascript-runtime-server@0.5.0 9 | http@1.4.0 10 | meteor@1.8.2 11 | modules@0.11.3 12 | modules-runtime@0.9.2 13 | promise@0.10.1 14 | url@1.2.0 15 | -------------------------------------------------------------------------------- /packages/vue-coffee/.versions: -------------------------------------------------------------------------------- 1 | akryum:vue-coffee@0.3.0 2 | babel-compiler@7.0.0 3 | babel-runtime@1.2.2 4 | coffeescript-compiler@2.0.3_4 5 | dynamic-import@0.3.0 6 | ecmascript@0.10.0 7 | ecmascript-runtime@0.5.0 8 | ecmascript-runtime-client@0.6.0 9 | ecmascript-runtime-server@0.5.0 10 | http@1.4.0 11 | meteor@1.8.2 12 | modules@0.11.3 13 | modules-runtime@0.9.2 14 | promise@0.10.1 15 | url@1.2.0 16 | -------------------------------------------------------------------------------- /packages/vue-router2/.versions: -------------------------------------------------------------------------------- 1 | akryum:npm-check@0.1.0 2 | akryum:vue-router2@0.2.0 3 | babel-compiler@7.0.0 4 | babel-runtime@1.2.2 5 | caching-compiler@1.1.11 6 | dynamic-import@0.3.0 7 | ecmascript@0.10.0 8 | ecmascript-runtime@0.5.0 9 | ecmascript-runtime-client@0.6.0 10 | ecmascript-runtime-server@0.5.0 11 | http@1.4.0 12 | meteor@1.8.2 13 | modules@0.11.3 14 | modules-runtime@0.9.2 15 | promise@0.10.1 16 | random@1.1.0 17 | url@1.2.0 18 | -------------------------------------------------------------------------------- /.gitattributes: -------------------------------------------------------------------------------- 1 | # Auto detect text files and perform LF normalization 2 | * text=auto 3 | 4 | # Custom for Visual Studio 5 | *.cs diff=csharp 6 | 7 | # Standard to msysgit 8 | *.doc diff=astextplain 9 | *.DOC diff=astextplain 10 | *.docx diff=astextplain 11 | *.DOCX diff=astextplain 12 | *.dot diff=astextplain 13 | *.DOT diff=astextplain 14 | *.pdf diff=astextplain 15 | *.PDF diff=astextplain 16 | *.rtf diff=astextplain 17 | *.RTF diff=astextplain 18 | -------------------------------------------------------------------------------- /packages/vue-component-dev-server/package.js: -------------------------------------------------------------------------------- 1 | Package.describe({ 2 | name: 'akryum:vue-component-dev-server', 3 | version: '0.1.4', 4 | summary: 'Dev server for vue hot-reloading', 5 | git: 'https://github.com/Akryum/meteor-vue-component', 6 | documentation: 'README.md', 7 | debugOnly: true, 8 | }) 9 | 10 | Package.onUse(function (api) { 11 | api.use('ecmascript@0.12.7') 12 | api.use('webapp@1.7.4') 13 | api.mainModule('server/main.js', 'server') 14 | }) 15 | -------------------------------------------------------------------------------- /packages/vue-pug/vue-pug.js: -------------------------------------------------------------------------------- 1 | import pug from 'pug' 2 | import { Meteor } from 'meteor/meteor' 3 | 4 | global.vue = global.vue || {} 5 | global.vue.lang = global.vue.lang || {} 6 | 7 | global.vue.lang.pug = Meteor.wrapAsync(function ({ source, basePath, inputFile }, cb) { 8 | var fn = pug.compile(source, { 9 | filename: basePath, 10 | fileMode: true, 11 | doctype: 'html', 12 | }) 13 | 14 | var html = fn() 15 | 16 | cb(null, { 17 | template: html, 18 | }) 19 | }) 20 | -------------------------------------------------------------------------------- /packages/vue-blaze-template/package.js: -------------------------------------------------------------------------------- 1 | Package.describe({ 2 | name: 'akryum:vue-blaze-template', 3 | version: '0.1.1', 4 | summary: 'Render Blaze templates in vue components', 5 | git: 'https://github.com/Akryum/meteor-vue-component', 6 | documentation: 'README.md', 7 | }) 8 | 9 | Package.onUse(function (api) { 10 | api.versionsFrom('1.6') 11 | api.use([ 12 | 'ecmascript', 13 | 'templating@1.3.2', 14 | 'blaze@2.3.3', 15 | ]) 16 | api.mainModule('vue-render-blaze.js', 'client') 17 | }) 18 | -------------------------------------------------------------------------------- /packages/vue-pug/README.md: -------------------------------------------------------------------------------- 1 | # Integrate pug with vue single-file components for Meteor 2 | 3 | Compatibility: **Vue 1.x, Vue 2.x** 4 | 5 | This meteor package adds [pug](http://pugjs.org) support in your single-file `.vue` components. 6 | 7 | ## Installation 8 | 9 | meteor add akryum:vue-pug 10 | 11 | 12 | ## Usage 13 | 14 | ```html 15 | 20 | ``` 21 | 22 | --- 23 | 24 | LICENCE ISC - Created by Guillaume CHAU (@Akryum) 25 | -------------------------------------------------------------------------------- /packages/vue-component-dev-server/.versions: -------------------------------------------------------------------------------- 1 | akryum:vue-component-dev-server@0.1.0 2 | babel-compiler@7.0.0 3 | babel-runtime@1.2.2 4 | base64@1.0.10 5 | boilerplate-generator@1.4.0 6 | dynamic-import@0.3.0 7 | ecmascript@0.10.0 8 | ecmascript-runtime@0.5.0 9 | ecmascript-runtime-client@0.6.0 10 | ecmascript-runtime-server@0.5.0 11 | ejson@1.1.0 12 | http@1.4.0 13 | logging@1.1.19 14 | meteor@1.8.2 15 | modules@0.11.3 16 | modules-runtime@0.9.2 17 | promise@0.10.1 18 | routepolicy@1.0.12 19 | underscore@1.0.10 20 | url@1.2.0 21 | webapp@1.5.0 22 | webapp-hashing@1.0.9 23 | -------------------------------------------------------------------------------- /packages/vue-coffee/package.js: -------------------------------------------------------------------------------- 1 | Package.describe({ 2 | name: 'akryum:vue-coffee', 3 | version: '0.4.2', 4 | summary: 'Add coffee support for vue components', 5 | git: 'https://github.com/Akryum/meteor-vue-component', 6 | documentation: 'README.md', 7 | }) 8 | 9 | Package.registerBuildPlugin({ 10 | name: 'vue-component-coffee', 11 | use: [ 12 | 'ecmascript@0.12.7', 13 | 'coffeescript-compiler@2.3.2_1', 14 | ], 15 | sources: ['vue-coffee.js'], 16 | }) 17 | 18 | Package.onUse(function (api) { 19 | api.use('isobuild:compiler-plugin@1.0.0') 20 | }) 21 | -------------------------------------------------------------------------------- /packages/vue-component-dev-client/package.js: -------------------------------------------------------------------------------- 1 | Package.describe({ 2 | name: 'akryum:vue-component-dev-client', 3 | version: '0.4.7', 4 | summary: 'Hot-reloading client for vue components', 5 | git: 'https://github.com/Akryum/meteor-vue-component', 6 | documentation: 'README.md', 7 | debugOnly: true, 8 | }) 9 | 10 | Package.onUse(function (api) { 11 | api.use('ecmascript@0.12.7') 12 | api.use('reload@1.3.0') 13 | api.use('autoupdate@1.6.0') 14 | api.mainModule('client/dev-client.js', 'client') 15 | }) 16 | 17 | Npm.depends({ 18 | 'socket.io-client': '2.2.0', 19 | }) 20 | -------------------------------------------------------------------------------- /packages/vue-pug/package.js: -------------------------------------------------------------------------------- 1 | Package.describe({ 2 | name: 'akryum:vue-pug', 3 | version: '0.1.3', 4 | summary: 'Add pug support for vue components', 5 | git: 'https://github.com/Akryum/meteor-vue-component', 6 | documentation: 'README.md', 7 | }) 8 | 9 | Package.registerBuildPlugin({ 10 | name: 'vue-component-pug', 11 | use: [ 12 | 'ecmascript@0.12.7', 13 | ], 14 | sources: [ 15 | 'vue-pug.js', 16 | ], 17 | npmDependencies: { 18 | 'pug': '2.0.3', 19 | }, 20 | }) 21 | 22 | Package.onUse(function (api) { 23 | api.use('isobuild:compiler-plugin@1.0.0') 24 | }) 25 | -------------------------------------------------------------------------------- /packages/npm-check/package.js: -------------------------------------------------------------------------------- 1 | Package.describe({ 2 | name: 'akryum:npm-check', 3 | version: '0.1.2', 4 | summary: 'Check npm peer-dependencies and auto-installs them.', 5 | git: 'https://github.com/Akryum/meteor-vue-component/tree/master/packages/npm-check', 6 | documentation: 'README.md', 7 | }) 8 | 9 | Package.registerBuildPlugin({ 10 | name: 'npm-check', 11 | use: [ 12 | 'ecmascript@0.12.7', 13 | ], 14 | sources: [ 15 | 'lib.js', 16 | 'npm-check.js', 17 | ], 18 | }) 19 | 20 | Package.onUse(function (api) { 21 | api.use('isobuild:compiler-plugin@1.0.0') 22 | }) 23 | -------------------------------------------------------------------------------- /packages/vue-less/package.js: -------------------------------------------------------------------------------- 1 | Package.describe({ 2 | name: 'akryum:vue-less', 3 | version: '0.2.1', 4 | summary: 'Add less support for vue components', 5 | git: 'https://github.com/Akryum/meteor-vue-component', 6 | documentation: 'README.md', 7 | }) 8 | 9 | Package.registerBuildPlugin({ 10 | name: 'vue-component-less', 11 | use: [ 12 | 'ecmascript@0.12.7', 13 | ], 14 | sources: [ 15 | 'vue-less.js', 16 | ], 17 | npmDependencies: { 18 | 'less': '3.9.0', 19 | }, 20 | }) 21 | 22 | Package.onUse(function (api) { 23 | api.use('isobuild:compiler-plugin@1.0.0') 24 | }) 25 | -------------------------------------------------------------------------------- /packages/npm-check/README.md: -------------------------------------------------------------------------------- 1 | # Checks and auto-installs your atmosphere package npm dependencies 2 | 3 | In your package folder, add a `npm.json`: 4 | 5 | ```json 6 | { 7 | "dependencies": { 8 | "socket.io-client": "^1.4.6" 9 | }, 10 | "devDependencies": { 11 | "vue": "^1.0.24" 12 | } 13 | } 14 | ``` 15 | 16 | And in your `package.js` add the `npm-check` package: 17 | 18 | ```javascript 19 | Package.onUse(function(api) { 20 | api.versionsFrom('1.3.2.4'); 21 | api.use('akryum:npm-check@0.0.1'); 22 | api.use('ecmascript'); 23 | api.mainModule('index.js', 'client'); 24 | }); 25 | ``` 26 | -------------------------------------------------------------------------------- /packages/vue-sass/package.js: -------------------------------------------------------------------------------- 1 | Package.describe({ 2 | name: 'akryum:vue-sass', 3 | version: '0.1.3', 4 | summary: 'Add sass and scss support for vue components', 5 | git: 'https://github.com/Akryum/meteor-vue-component', 6 | documentation: 'README.md', 7 | }) 8 | 9 | Package.registerBuildPlugin({ 10 | name: 'vue-component-sass', 11 | use: [ 12 | 'ecmascript@0.12.7', 13 | ], 14 | sources: [ 15 | 'vue-sass.js', 16 | ], 17 | npmDependencies: { 18 | 'node-sass': '4.14.0', 19 | 'meteor-project-path': '0.0.3', 20 | }, 21 | }) 22 | 23 | Package.onUse(function (api) { 24 | api.use('isobuild:compiler-plugin@1.0.0') 25 | }) 26 | -------------------------------------------------------------------------------- /packages/vue-coffee/README.md: -------------------------------------------------------------------------------- 1 | # Integrate CoffeeScript with vue single-file components for Meteor 2 | 3 | Compatibility: **Vue 1.x, Vue 2.x** 4 | 5 | This meteor package adds [CoffeeScript](http://coffeescript.org/) support in your single-file `.vue` components. 6 | 7 | ## Installation 8 | 9 | meteor add akryum:vue-coffee 10 | 11 | 12 | ## Usage 13 | 14 | ```html 15 | 24 | ``` 25 | 26 | --- 27 | 28 | LICENCE ISC - Created by Guillaume CHAU (@Akryum) 29 | -------------------------------------------------------------------------------- /packages/vue-component/plugin/regexps.js: -------------------------------------------------------------------------------- 1 | quoteReg = /'/g 2 | lineReg = /\r?\n|\r/g 3 | tagReg = /<([\w\d-]+)((\s+.*?)*)?\/?>/ig 4 | classAttrReg = /\s+class=([''])(.*?)\1/gi 5 | rnReg = /\r\n/g 6 | rReg = /\r/g 7 | tagCommentRegex = //igm 8 | expandedTagRegex = /<(template|script)(\s+.*)?>\n?([\s\S]+)<\/\1>/igm 9 | limitedTagRegex = /<(style)(\s+.*)?>\n?([\s\S]+?)<\/\1>/igm 10 | attrsRegex = /\s+(\w+)(=(["'])([\w/~$@:.-]*)\3)?/ig 11 | globalFileNameReg = /\.global\.vue$/ 12 | capitalLetterReg = /([A-Z])/g 13 | trimDashReg = /^-/ 14 | nonWordCharReg = /\W/g 15 | requireRelativeFileReg = /require\(["']\.\//ig 16 | 17 | splitRE = /\r?\n/g 18 | emptyRE = /^(?:\/\/)?\s*$/ 19 | -------------------------------------------------------------------------------- /packages/vue-stylus/package.js: -------------------------------------------------------------------------------- 1 | Package.describe({ 2 | name: 'akryum:vue-stylus', 3 | version: '0.1.3', 4 | summary: 'Add stylus support for vue components', 5 | git: 'https://github.com/Akryum/meteor-vue-component', 6 | documentation: 'README.md', 7 | }) 8 | 9 | Package.registerBuildPlugin({ 10 | name: 'vue-component-stylus', 11 | use: [ 12 | 'ecmascript@0.12.7', 13 | ], 14 | sources: [ 15 | 'vue-stylus.js', 16 | ], 17 | npmDependencies: { 18 | stylus: 'https://github.com/meteor/stylus/tarball/bb47a357d132ca843718c63998eb37b90013a449', // fork of 0.54.5 19 | nib: '1.1.2', 20 | }, 21 | }) 22 | 23 | Package.onUse(function (api) { 24 | api.use('isobuild:compiler-plugin@1.0.0') 25 | }) 26 | -------------------------------------------------------------------------------- /packages/vue-router2/package.js: -------------------------------------------------------------------------------- 1 | Package.describe({ 2 | name: 'akryum:vue-router2', 3 | version: '0.2.3', 4 | summary: 'Easy vue routing for Meteor - vue-router 2.x', 5 | git: 'https://github.com/Akryum/meteor-vue-component', 6 | documentation: 'README.md', 7 | }) 8 | 9 | Package.registerBuildPlugin({ 10 | name: 'vue-router', 11 | use: [ 12 | 'ecmascript@0.12.7', 13 | 'caching-compiler@1.2.1', 14 | 'babel-compiler@7.3.4', 15 | ], 16 | sources: [ 17 | 'plugin/plugin.js', 18 | ], 19 | }) 20 | 21 | Package.onUse(function (api) { 22 | api.use('isobuild:compiler-plugin@1.0.0') 23 | api.use('ecmascript@0.12.7') 24 | api.use('akryum:npm-check@0.1.1') 25 | api.mainModule('client/client.js', 'client') 26 | api.export(['RouterFactory', 'nativeScrollBehavior'], 'client') 27 | }) 28 | -------------------------------------------------------------------------------- /packages/vue-blaze-template/README.md: -------------------------------------------------------------------------------- 1 | # Use Blaze templates in Vue components 2 | 3 | Compatibility: **Vue 1.x, Vue 2.x** 4 | 5 | ## Installation 6 | 7 | meteor add akryum:vue-blaze-template 8 | 9 | ## Usage 10 | 11 | The `v-blaze` directive allow you to use any Blaze template in your Vue component. It expect an expression. 12 | 13 | Static template name (**don't forget the single quote**): 14 | 15 | ```html 16 |
17 | ``` 18 | 19 | Dynamic template name (will switch the template reactively): 20 | 21 | ```html 22 | 25 | 26 | 33 | ``` 34 | 35 | [Example app](https://github.com/Akryum/meteor-vue-blaze/tree/render-blaze) 36 | -------------------------------------------------------------------------------- /packages/vue-ssr/package.js: -------------------------------------------------------------------------------- 1 | Package.describe({ 2 | name: 'akryum:vue-ssr', 3 | version: '0.5.0', 4 | summary: 'Render Vue server-side', 5 | git: 'https://github.com/Akryum/meteor-vue-component', 6 | documentation: 'README.md', 7 | }) 8 | 9 | Package.onUse(function (api) { 10 | api.versionsFrom('1.6.1') 11 | api.use([ 12 | 'isobuild:compiler-plugin@1.0.0', 13 | 'ecmascript', 14 | 'tracker', 15 | 'minimongo', 16 | 'underscore', 17 | 'webapp', 18 | 'mongo', 19 | 'routepolicy', 20 | 'url', 21 | 'akryum:npm-check@0.1.1', 22 | 'communitypackages:fast-render@4.0.6', 23 | 'ejson', 24 | 'server-render', 25 | ]) 26 | api.mainModule('server/index.js', 'server') 27 | api.export('VueSSR', 'server') 28 | }) 29 | 30 | Npm.depends({ 31 | 'vue-server-renderer': '2.6.10', 32 | 'cookie-parser': '1.4.4', 33 | }) 34 | -------------------------------------------------------------------------------- /packages/vue-less/README.md: -------------------------------------------------------------------------------- 1 | # Integrate less with vue single-file components for Meteor 2 | 3 | Compatibility: **Vue 1.x, Vue 2.x** 4 | 5 | This meteor package adds [less](http://lesscss.org/) support in your single-file `.vue` components. 6 | 7 | ## Installation 8 | 9 | meteor add akryum:vue-less 10 | 11 | 12 | ## Usage 13 | 14 | ```html 15 | 26 | ``` 27 | 28 | You can import files with absolute or relative path: 29 | 30 | ```html 31 | 37 | ``` 38 | 39 | --- 40 | 41 | LICENCE ISC - Created by Guillaume CHAU (@Akryum) 42 | -------------------------------------------------------------------------------- /packages/vue-blaze-template/.versions: -------------------------------------------------------------------------------- 1 | akryum:vue-blaze-template@0.1.0 2 | babel-compiler@7.0.0 3 | babel-runtime@1.2.2 4 | base64@1.0.10 5 | blaze@2.3.2 6 | blaze-tools@1.0.10 7 | caching-compiler@1.1.11 8 | caching-html-compiler@1.1.2 9 | check@1.3.0 10 | deps@1.0.12 11 | diff-sequence@1.1.0 12 | dynamic-import@0.3.0 13 | ecmascript@0.10.0 14 | ecmascript-runtime@0.5.0 15 | ecmascript-runtime-client@0.6.0 16 | ecmascript-runtime-server@0.5.0 17 | ejson@1.1.0 18 | html-tools@1.0.11 19 | htmljs@1.0.11 20 | http@1.4.0 21 | id-map@1.1.0 22 | jquery@1.11.10 23 | meteor@1.8.2 24 | modules@0.11.3 25 | modules-runtime@0.9.2 26 | mongo-id@1.0.6 27 | observe-sequence@1.0.16 28 | ordered-dict@1.1.0 29 | promise@0.10.1 30 | random@1.1.0 31 | reactive-var@1.0.11 32 | spacebars@1.0.15 33 | spacebars-compiler@1.1.3 34 | templating@1.3.2 35 | templating-compiler@1.3.3 36 | templating-runtime@1.3.2 37 | templating-tools@1.1.2 38 | tracker@1.1.3 39 | underscore@1.0.10 40 | url@1.2.0 41 | -------------------------------------------------------------------------------- /packages/vue-stylus/README.md: -------------------------------------------------------------------------------- 1 | # Integrate stylus with vue single-file components for Meteor 2 | 3 | Compatibility: **Vue 1.x, Vue 2.x** 4 | 5 | This meteor package adds [stylus](http://stylus-lang.com/) support in your single-file `.vue` components. [nib](https://github.com/tj/nib) is also supported. 6 | 7 | ## Installation 8 | 9 | meteor add akryum:vue-stylus 10 | 11 | 12 | ## Usage 13 | 14 | ```html 15 | 23 | ``` 24 | 25 | You can import files with absolute, relative path or a folder: 26 | 27 | ```html 28 | 36 | ``` 37 | 38 | --- 39 | 40 | LICENCE ISC - Created by Guillaume CHAU (@Akryum) 41 | -------------------------------------------------------------------------------- /package.json: -------------------------------------------------------------------------------- 1 | { 2 | "name": "vue-meteor", 3 | "version": "0.1.0", 4 | "description": "Meteor + Vue stack", 5 | "scripts": { 6 | "eslint": "eslint --ext .js,.jsx,.vue packages" 7 | }, 8 | "repository": { 9 | "type": "git", 10 | "url": "git+https://github.com/meteor-vue/vue-meteor.git" 11 | }, 12 | "author": "Guillaume Chau ", 13 | "license": "ISC", 14 | "bugs": { 15 | "url": "https://github.com/meteor-vue/vue-meteor/issues" 16 | }, 17 | "homepage": "https://github.com/meteor-vue/vue-meteor#readme", 18 | "devDependencies": { 19 | "babel-core": "^6.26.0", 20 | "babel-eslint": "^8.2.1", 21 | "babel-preset-env": "^1.6.1", 22 | "babel-preset-stage-2": "^6.24.1", 23 | "eslint": "^4.16.0", 24 | "eslint-config-standard": "^11.0.0-beta.0", 25 | "eslint-plugin-import": "^2.8.0", 26 | "eslint-plugin-node": "^5.2.1", 27 | "eslint-plugin-promise": "^3.6.0", 28 | "eslint-plugin-standard": "^3.0.1" 29 | } 30 | } 31 | -------------------------------------------------------------------------------- /packages/vue-coffee/vue-coffee.js: -------------------------------------------------------------------------------- 1 | import { Meteor } from 'meteor/meteor' 2 | import { CoffeeScriptCompiler } from 'meteor/coffeescript-compiler' 3 | 4 | const coffeeScriptCompiler = new CoffeeScriptCompiler() 5 | 6 | global.vue = global.vue || {} 7 | global.vue.lang = global.vue.lang || {} 8 | 9 | global.vue.lang.coffee = Meteor.wrapAsync(function ({ source, inputFile }, callback) { 10 | // Override this method so that it returns only the source within the ` 108 | 109 | sink.renderIntoElementById(VueSSR.outlet, html) 110 | sink.appendToHead(head) 111 | sink.appendToBody([body, script]) 112 | 113 | resolve() 114 | }, 115 | ) 116 | }).catch(e => { 117 | console.error(e) 118 | writeServerError(sink) 119 | resolve() 120 | }) 121 | } catch (error) { 122 | console.error(error) 123 | writeServerError(sink) 124 | resolve() 125 | } 126 | }) 127 | })) 128 | -------------------------------------------------------------------------------- /packages/vue-component/plugin/post-css.js: -------------------------------------------------------------------------------- 1 | // Makes sure we can load peer dependencies from app's directory. 2 | // See: https://github.com/meteor/meteor/issues/9865 3 | Npm.require('app-module-path/cwd') 4 | 5 | import postcss from 'postcss' 6 | import selectorParser from 'postcss-selector-parser' 7 | import load from 'postcss-load-config' 8 | import { Meteor } from 'meteor/meteor' 9 | 10 | let loaded 11 | 12 | loadPostcssConfig = Meteor.wrapAsync(function (cb) { 13 | let error = null 14 | if (!loaded) { 15 | loaded = load({'vue-meteor': true}).catch(err => { 16 | // postcss-load-config throws error when no config file is found, 17 | // but for us it's optional. only emit other errors 18 | if (err.message.indexOf('No PostCSS Config found') < 0) { 19 | error = err 20 | error.message = 'PostCSS config Error: '.red + error.message 21 | } 22 | }) 23 | } 24 | 25 | loaded.then(config => { 26 | let plugins = [] 27 | let options = {} 28 | 29 | // merge postcss config file 30 | if (config && config.plugins) { 31 | plugins = plugins.concat(config.plugins) 32 | } 33 | if (config && config.options) { 34 | options = Object.assign({}, config.options, options) 35 | } 36 | 37 | cb(error, { 38 | plugins, 39 | options, 40 | }) 41 | }) 42 | }) 43 | 44 | scopeId = postcss.plugin('add-id', ({ id }) => root => { 45 | const keyframes = Object.create(null) 46 | 47 | root.each(function rewriteSelector (node) { 48 | if (!node.selector) { 49 | // handle media queries 50 | if (node.type === 'atrule') { 51 | if (node.name === 'media' || node.name === 'supports') { 52 | node.each(rewriteSelector) 53 | } else if (/-?keyframes$/.test(node.name)) { 54 | // register keyframes 55 | keyframes[node.params] = node.params = node.params + '-' + id 56 | } 57 | } 58 | return 59 | } 60 | node.selector = selectorParser(selectors => { 61 | selectors.each(selector => { 62 | let node = null 63 | selector.each(n => { 64 | // ">>>" combinator 65 | if (n.type === 'combinator' && n.value === '>>>') { 66 | n.value = ' ' 67 | n.spaces.before = n.spaces.after = '' 68 | return false 69 | } 70 | // /deep/ alias for >>>, since >>> doesn't work in SASS 71 | if (n.type === 'tag' && n.value === '/deep/') { 72 | const prev = n.prev() 73 | if (prev && prev.type === 'combinator' && prev.value === ' ') { 74 | prev.remove() 75 | } 76 | n.remove() 77 | return false 78 | } 79 | if (n.type !== 'pseudo' && n.type !== 'combinator') { 80 | node = n 81 | } 82 | }) 83 | selector.insertAfter(node, selectorParser.attribute({ 84 | attribute: id, 85 | })) 86 | }) 87 | }).process(node.selector).result 88 | }) 89 | 90 | // If keyframes are found in this 138 | ``` 139 | 140 | ### App layout 141 | 142 | Create a vue component with a `` element, that will contain the route content ([more info](http://router.vuejs.org/en/api/router-view.html)): 143 | 144 | ```html 145 | 146 | 155 | 156 | 165 | ``` 166 | 167 | ### Not found page 168 | 169 | To add a 'not found' page, add a `*` route in your client code: 170 | 171 | ```javascript 172 | /* /client/routes.js */ 173 | 174 | // Import the router 175 | import { RouterFactory } from 'meteor/akryum:vue-router'; 176 | 177 | // Not found 178 | import NotFound from '/imports/ui/NotFound.vue'; 179 | 180 | RouterFactory.configure(factory => { 181 | factory.addRoute({ 182 | path: '*', 183 | component: NotFound, 184 | }); 185 | }, -1); 186 | ``` 187 | 188 | *Note that we use a priority of `-1`, so this route is added last. If we don't do that, there is a chance that this route will be first and then will match immediately: the user will be greeted by a 'not found' page every time he loads the app!* 189 | 190 | ### Starting the router 191 | 192 | Then import the routes and start the router in your client: 193 | 194 | ```javascript 195 | /* /client/client.js */ 196 | 197 | // App layout 198 | import AppLayout from '/imports/ui/AppLayout.vue'; 199 | 200 | // App start 201 | Meteor.startup(() => { 202 | // Create the router instance 203 | const router = routerFactory.create() 204 | 205 | // Start the Vue app 206 | new Vue({ 207 | router, 208 | ...AppLayout, 209 | }).$mount('app'); 210 | }); 211 | 212 | ``` 213 | 214 | **If you put your routes files in the `/imports` folder, you need to import them manually.** 215 | 216 | To start the router, use the `routerFactory.create()` method and pass the result to a Vue instance with the `router` option. 217 | 218 | ### Fast-render 219 | 220 | You can use the [meteorhacks:fast-render](https://github.com/kadirahq/fast-render) package to inject the subscriptions data in the html. This greatly speeds up the initial render of your app if it depends on subscriptions. 221 | 222 | First, install the fast-render package: 223 | 224 | meteor add meteorhacks:fast-render 225 | 226 | In your server, add fast-render routes: 227 | 228 | ```javascript 229 | FastRender.route('/forum', function(params) { 230 | this.subscribe('threads'); 231 | }); 232 | ``` 233 | 234 | This will send the `threads` subscription data along side the html if the user open your app with the `yourapp/forum` url. 235 | 236 | --- 237 | 238 | ## Next steps 239 | 240 | - [Example project](https://github.com/Akryum/meteor-vue2-example-routing) 241 | - [Integrate apollo](https://github.com/Akryum/vue-apollo) 242 | 243 | --- 244 | 245 | LICENCE ISC - Created by Guillaume CHAU (@Akryum) 246 | -------------------------------------------------------------------------------- /packages/vue-component-dev-client/client/vue2-hot.js: -------------------------------------------------------------------------------- 1 | let Vue // late bind 2 | let version 3 | const map = Object.create(null) 4 | if (typeof window !== 'undefined') { 5 | window.__VUE_HOT_MAP__ = map 6 | } 7 | let installed = false 8 | let isBrowserify = false 9 | let initHookName = 'beforeCreate' 10 | 11 | exports.install = (vue, browserify) => { 12 | if (installed) return 13 | installed = true 14 | 15 | Vue = vue.__esModule ? vue.default : vue 16 | version = Vue.version.split('.').map(Number) 17 | isBrowserify = browserify 18 | 19 | // compat with < 2.0.0-alpha.7 20 | if (Vue.config._lifecycleHooks.indexOf('init') > -1) { 21 | initHookName = 'init' 22 | } 23 | 24 | exports.compatible = version[0] >= 2 25 | if (!exports.compatible) { 26 | console.warn( 27 | '[HMR] You are using a version of vue-hot-reload-api that is ' + 28 | 'only compatible with Vue.js core ^2.0.0.' 29 | ) 30 | return 31 | } 32 | } 33 | 34 | /** 35 | * Create a record for a hot module, which keeps track of its constructor 36 | * and instances 37 | * 38 | * @param {String} id 39 | * @param {Object} options 40 | */ 41 | 42 | exports.createRecord = (id, options) => { 43 | if (map[id]) return 44 | 45 | let Ctor = null 46 | if (typeof options === 'function') { 47 | Ctor = options 48 | options = Ctor.options 49 | } 50 | makeOptionsHot(id, options) 51 | map[id] = { 52 | Ctor, 53 | options, 54 | instances: [] 55 | } 56 | } 57 | 58 | /** 59 | * Check if module is recorded 60 | * 61 | * @param {String} id 62 | */ 63 | 64 | exports.isRecorded = (id) => { 65 | return typeof map[id] !== 'undefined' 66 | } 67 | 68 | /** 69 | * Make a Component options object hot. 70 | * 71 | * @param {String} id 72 | * @param {Object} options 73 | */ 74 | 75 | function makeOptionsHot (id, options) { 76 | if (options.functional) { 77 | const render = options.render 78 | options.render = (h, ctx) => { 79 | const instances = map[id].instances 80 | if (ctx && instances.indexOf(ctx.parent) < 0) { 81 | instances.push(ctx.parent) 82 | } 83 | return render(h, ctx) 84 | } 85 | } else { 86 | injectHook(options, initHookName, function () { 87 | const record = map[id] 88 | if (!record.Ctor) { 89 | record.Ctor = this.constructor 90 | } 91 | record.instances.push(this) 92 | }) 93 | injectHook(options, 'beforeDestroy', function () { 94 | const instances = map[id].instances 95 | instances.splice(instances.indexOf(this), 1) 96 | }) 97 | } 98 | } 99 | 100 | /** 101 | * Inject a hook to a hot reloadable component so that 102 | * we can keep track of it. 103 | * 104 | * @param {Object} options 105 | * @param {String} name 106 | * @param {Function} hook 107 | */ 108 | 109 | function injectHook (options, name, hook) { 110 | const existing = options[name] 111 | options[name] = existing 112 | ? Array.isArray(existing) ? existing.concat(hook) : [existing, hook] 113 | : [hook] 114 | } 115 | 116 | function tryWrap (fn) { 117 | return (id, arg) => { 118 | try { 119 | fn(id, arg) 120 | } catch (e) { 121 | console.error(e) 122 | console.warn( 123 | 'Something went wrong during Vue component hot-reload. Full reload required.' 124 | ) 125 | } 126 | } 127 | } 128 | 129 | function updateOptions (oldOptions, newOptions) { 130 | for (const key in oldOptions) { 131 | if (!(key in newOptions)) { 132 | delete oldOptions[key] 133 | } 134 | } 135 | for (const key in newOptions) { 136 | oldOptions[key] = newOptions[key] 137 | } 138 | } 139 | 140 | exports.rerender = tryWrap((id, options) => { 141 | const record = map[id] 142 | if (!options) { 143 | record.instances.slice().forEach(instance => { 144 | instance.$forceUpdate() 145 | }) 146 | return 147 | } 148 | if (typeof options === 'function') { 149 | options = options.options 150 | } 151 | if (record.Ctor) { 152 | record.Ctor.options.render = options.render 153 | record.Ctor.options.staticRenderFns = options.staticRenderFns 154 | record.instances.slice().forEach(instance => { 155 | instance.$options.render = options.render 156 | instance.$options.staticRenderFns = options.staticRenderFns 157 | // reset static trees 158 | // pre 2.5, all static trees are cached together on the instance 159 | if (instance._staticTrees) { 160 | instance._staticTrees = [] 161 | } 162 | // 2.5.0 163 | if (Array.isArray(record.Ctor.options.cached)) { 164 | record.Ctor.options.cached = [] 165 | } 166 | // 2.5.3 167 | if (Array.isArray(instance.$options.cached)) { 168 | instance.$options.cached = [] 169 | } 170 | 171 | // post 2.5.4: v-once trees are cached on instance._staticTrees. 172 | // Pure static trees are cached on the staticRenderFns array 173 | // (both already reset above) 174 | 175 | // 2.6: temporarily mark rendered scoped slots as unstable so that 176 | // child components can be forced to update 177 | const restore = patchScopedSlots(instance) 178 | instance.$forceUpdate() 179 | instance.$nextTick(restore) 180 | }) 181 | } else { 182 | // functional or no instance created yet 183 | record.options.render = options.render 184 | record.options.staticRenderFns = options.staticRenderFns 185 | 186 | // handle functional component re-render 187 | if (record.options.functional) { 188 | // rerender with full options 189 | if (Object.keys(options).length > 2) { 190 | updateOptions(record.options, options) 191 | } else { 192 | // template-only rerender. 193 | // need to inject the style injection code for CSS modules 194 | // to work properly. 195 | const injectStyles = record.options._injectStyles 196 | if (injectStyles) { 197 | const render = options.render 198 | record.options.render = (h, ctx) => { 199 | injectStyles.call(ctx) 200 | return render(h, ctx) 201 | } 202 | } 203 | } 204 | record.options._Ctor = null 205 | // 2.5.3 206 | if (Array.isArray(record.options.cached)) { 207 | record.options.cached = [] 208 | } 209 | record.instances.slice().forEach(instance => { 210 | instance.$forceUpdate() 211 | }) 212 | } 213 | } 214 | }) 215 | 216 | exports.reload = tryWrap((id, options) => { 217 | const record = map[id] 218 | if (options) { 219 | if (typeof options === 'function') { 220 | options = options.options 221 | } 222 | makeOptionsHot(id, options) 223 | if (record.Ctor) { 224 | if (version[1] < 2) { 225 | // preserve pre 2.2 behavior for global mixin handling 226 | record.Ctor.extendOptions = options 227 | } 228 | const newCtor = record.Ctor.super.extend(options) 229 | record.Ctor.options = newCtor.options 230 | record.Ctor.cid = newCtor.cid 231 | record.Ctor.prototype = newCtor.prototype 232 | if (newCtor.release) { 233 | // temporary global mixin strategy used in < 2.0.0-alpha.6 234 | newCtor.release() 235 | } 236 | } else { 237 | updateOptions(record.options, options) 238 | } 239 | } 240 | record.instances.slice().forEach(instance => { 241 | if (instance.$vnode && instance.$vnode.context) { 242 | instance.$vnode.context.$forceUpdate() 243 | } else { 244 | console.warn( 245 | 'Root or manually mounted instance modified. Full reload required.' 246 | ) 247 | } 248 | }) 249 | }) 250 | 251 | // 2.6 optimizes template-compiled scoped slots and skips updates if child 252 | // only uses scoped slots. We need to patch the scoped slots resolving helper 253 | // to temporarily mark all scoped slots as unstable in order to force child 254 | // updates. 255 | function patchScopedSlots (instance) { 256 | if (!instance._u) return 257 | // https://github.com/vuejs/vue/blob/dev/src/core/instance/render-helpers/resolve-scoped-slots.js 258 | const original = instance._u 259 | instance._u = slots => { 260 | try { 261 | // 2.6.4 ~ 2.6.6 262 | return original(slots, true) 263 | } catch (e) { 264 | // 2.5 / >= 2.6.7 265 | return original(slots, null, true) 266 | } 267 | } 268 | return () => { 269 | instance._u = original 270 | } 271 | } -------------------------------------------------------------------------------- /packages/vue-component-dev-client/client/dev-client.js: -------------------------------------------------------------------------------- 1 | import './buffer' 2 | import Vue from 'vue' 3 | import { Reload } from 'meteor/reload' 4 | import { Meteor } from 'meteor/meteor' 5 | import { Autoupdate } from 'meteor/autoupdate' 6 | import VueHot1 from './vue-hot' 7 | import VueHot2 from './vue2-hot' 8 | 9 | if (__meteor_runtime_config__.VUE_NO_HMR) return 10 | 11 | const tagStyle = 'padding: 2px 4px 1px; background: #326ABC; color: white; border-radius: 3px; font-weight: bold;' 12 | const infoStyle = 'font-style: italic; color: #326ABC;' 13 | 14 | let VueHotReloadApi 15 | const vueVersion = parseInt(Vue.version.charAt(0)) 16 | 17 | console.log('%cHMR%c You are using Vue %c' + Vue.version, tagStyle, 'color: #177D4F;', 'color: #177D4F; font-weight: bold;') 18 | 19 | console.log('%cYou are currently in development mode. If the Hot-Module-Replacement system is enabled (`on` by default), the CSS will be injected to the page after the scripts are loaded. This may result in Flash Of Unstyled Contents. Those will not occur in production.', infoStyle) 20 | 21 | console.log('%cMore information about the component compilation: https://github.com/meteor-vue/vue-meteor/tree/master/packages/vue-component', infoStyle) 22 | 23 | console.log('%cDocumentation and Issues: https://github.com/meteor-vue/vue-meteor', infoStyle) 24 | 25 | if (vueVersion === 1) { 26 | VueHotReloadApi = VueHot1 27 | } else if (vueVersion === 2) { 28 | VueHotReloadApi = VueHot2 29 | Vue.config.productionTip = false 30 | } 31 | 32 | Vue.use(VueHotReloadApi) 33 | 34 | // Hot reload API 35 | window.__vue_hot__ = VueHotReloadApi 36 | 37 | // Records initialized before vue hot reload api 38 | if (window.__vue_hot_pending__) { 39 | for (let hash in window.__vue_hot_pending__) { 40 | VueHotReloadApi.createRecord(hash, window.__vue_hot_pending__[hash]) 41 | } 42 | } 43 | 44 | // Reload override 45 | let _suppressNextReload = false 46 | let _suppressTimer 47 | let _deferReload = 0 48 | const _reload = Reload._reload 49 | Reload._reload = function (options) { 50 | // Disable original reload for autoupdate package 51 | if (Reload._reload.caller.name !== '' && Reload._reload.caller.name !== 'checkNewVersionDocument') { 52 | _reload(options) 53 | } 54 | } 55 | 56 | // Custom reload method 57 | function reload (options) { 58 | if (_deferReload !== 0) { 59 | setTimeout(_reload, _deferReload) 60 | console.log(`%cHMR`, tagStyle, `Client reload defered, will reload in ${_deferReload} ms`) 61 | } else if (_suppressNextReload) { 62 | if (!_suppressTimer) { 63 | console.log(`%cHMR%c ⥁ Client version changed, reload suppressed because of a recent HMR update. You may need to reload the page.`, tagStyle, 'color: #F36E00;') 64 | } 65 | clearTimeout(_suppressTimer) 66 | // Debounce reload with 1 sec. timer 67 | _suppressTimer = setTimeout(() => { 68 | _suppressNextReload = false 69 | _suppressTimer = undefined 70 | }, 1000) 71 | } else { 72 | console.log(`%cHMR`, tagStyle, `Reloading app...`) 73 | _reload.call(Reload, options) 74 | } 75 | _deferReload = 0 76 | } 77 | 78 | // Reimplement client version check from autoupdate package 79 | function checkNewVersionDocument (doc) { 80 | if (doc && doc.version && doc._id && __meteor_runtime_config__.autoupdate.versions[doc._id]) { 81 | if (__meteor_runtime_config__.autoupdate.versions[doc._id].version !== doc.version) { 82 | reload() 83 | } 84 | } 85 | } 86 | 87 | if (Autoupdate._clientVersions) { 88 | // logic for autoupdate since Meteor 1.8.1 89 | Autoupdate._clientVersions.watch(checkNewVersionDocument) 90 | } else { 91 | // logic for autoupdate before Meteor 1.8.1 92 | const ClientVersions = Autoupdate._ClientVersions 93 | if (ClientVersions) { 94 | ClientVersions.find().observe({ 95 | added: checkNewVersionDocument, 96 | changed: checkNewVersionDocument, 97 | }) 98 | } else { 99 | console.warn('%cHMR', tagStyle, 'ClientVersions collection is not available, the app may full reload.') 100 | } 101 | } 102 | 103 | Meteor.startup(function () { 104 | if (Meteor.isCordova) { 105 | const root = new URL(__meteor_runtime_config__.ROOT_URL) 106 | __meteor_runtime_config__.VUE_DEV_SERVER_URL = root.protocol + '//' + root.hostname + ':' + (parseInt(root.port) + 3) + '/' 107 | } 108 | 109 | // Dev client 110 | const devUrl = __meteor_runtime_config__.VUE_DEV_SERVER_URL 111 | 112 | console.log('%cHMR%c Dev server URL: %c' + devUrl, tagStyle, '', 'font-weight: bold;') 113 | 114 | console.log(`%cIf you have issues connecting to the dev server, set the 'HMR_URL' env variable to the URL of the dev server displayed in the meteor console.`, infoStyle) 115 | 116 | // NOTE: Socket lib don't allow mix HTTP and HTTPS servers URLs on client! 117 | const _socket = require('socket.io-client/dist/socket.io.dev.js')(devUrl) 118 | window.__dev_client__ = _socket 119 | 120 | _socket.on('connect', function () { 121 | console.log('%cHMR%c ⏺ Dev client connected', tagStyle, 'color: #177D4F;') 122 | }) 123 | _socket.on('disconnect', function () { 124 | console.log('%cHMR%c ⏺ Dev client disconnected', tagStyle, 'color: #F36E00;') 125 | }) 126 | 127 | // JS 128 | _socket.on('js', Meteor.bindEnvironment(function ({hash, js, template, path}) { 129 | let args = ['vue'] 130 | let regResult 131 | let error = null 132 | while ((regResult = jsImportsReg.exec(js))) { 133 | args.push(regResult[2]) 134 | } 135 | args.push(function (require, exports, module) { 136 | try { 137 | // eslint-disable-next-line no-eval 138 | eval(js) 139 | } catch (e) { 140 | console.error(e) 141 | error = e 142 | } 143 | }) 144 | 145 | const id = `${path + Math.round(new Date().getTime())}.js` 146 | const files = id.split('/') 147 | const fileObj = {} 148 | let currentObj = fileObj 149 | const indexMax = files.length - 1 150 | files.forEach((file, index) => { 151 | if (index === indexMax) { 152 | currentObj[file] = args 153 | } else { 154 | currentObj = currentObj[file] = {} 155 | } 156 | }) 157 | 158 | const require = meteorInstall(fileObj) 159 | const result = require('./' + id) 160 | 161 | let needsReload = false 162 | if (!error) { 163 | console.log('%cHMR', tagStyle, 'Reloading ' + path) 164 | if (!result.default.render && !template) { 165 | error = true 166 | } 167 | if (!error) { 168 | try { 169 | if (vueVersion === 1) { 170 | needsReload = VueHotReloadApi.update(hash, result.default, template) 171 | } else if (vueVersion === 2) { 172 | needsReload = VueHotReloadApi.reload(hash, result.default, template) 173 | } 174 | } catch (e) { 175 | console.error(e) 176 | error = true 177 | } 178 | } 179 | } 180 | 181 | _suppressNextReload = !error && !needsReload 182 | })) 183 | 184 | // Template 185 | _socket.on('render', function ({hash, template, path}) { 186 | if (vueVersion === 2) { 187 | console.log('%cHMR', tagStyle, 'Rerendering ' + path) 188 | let error = false 189 | try { 190 | let obj 191 | // eslint-disable-next-line no-eval 192 | eval(`obj = ${template};`) 193 | // console.log(obj) 194 | VueHotReloadApi.rerender(hash, obj) 195 | } catch (e) { 196 | error = true 197 | } 198 | _suppressNextReload = !error 199 | } 200 | }) 201 | 202 | // CSS 203 | const _styleNodes = {} 204 | _socket.on('css', function ({hash, css, path}) { 205 | // console.log('css', hash, css.length) 206 | let style = _styleNodes[hash] 207 | if (!style) { 208 | style = document.createElement('style') 209 | style.setAttribute('data-v-source-file', path) 210 | document.getElementsByTagName('head')[0].appendChild(style) 211 | _styleNodes[hash] = style 212 | } 213 | style.textContent = css 214 | 215 | _suppressNextReload = true 216 | }) 217 | 218 | // Locale 219 | _socket.on('lang.updated', function ({lang, data}) { 220 | Vue.locale(lang, data) 221 | if (lang === Vue.config.lang) { 222 | // Refresh 223 | VueHotReloadApi.updateWatchers() 224 | } 225 | console.log(`%cHMR`, tagStyle, `Updated locale ${lang}`) 226 | _suppressNextReload = true 227 | }) 228 | _socket.on('langs.updated', function ({langs}) { 229 | _deferReload = 3000 230 | }) 231 | 232 | // Message 233 | _socket.on('message', function ({ type, message }) { 234 | let func 235 | if (type === 'error') { 236 | func = console.error 237 | } else if (type === 'warn') { 238 | func = console.warn 239 | } else { 240 | func = console.log 241 | } 242 | func(`%cHMR`, tagStyle, message) 243 | }) 244 | 245 | // Reg 246 | const jsImportsReg = /module\.import\((['"])(.+?)\1/g 247 | }) 248 | -------------------------------------------------------------------------------- /packages/vue-component/README.md: -------------------------------------------------------------------------------- 1 | # Vue Single-file component for Meteor 2 | 3 | Compatibility: **Vue 1.x, Vue 2.x** 4 | 5 | It allows you to write your components in [this format](https://vuejs.org/v2/guide/single-file-components.html) (with hot-reloading support): 6 | ![screenshot](http://blog.evanyou.me/images/vue-component.png) 7 | 8 | ## Installation 9 | 10 | ``` 11 | meteor add akryum:vue-component 12 | ``` 13 | 14 | ## Usage 15 | 16 | ### Babel cache 17 | 18 | The babel cache folder defaults to `.cache`, but you can override it with the `BABEL_CACHE_DIR` environment variable: 19 | 20 | ``` 21 | cross-env BABEL_CACHE_DIR=cacheFolderName 22 | ``` 23 | 24 | ### Hot-reloading 25 | 26 | To enable component hot-reloading, make sure that you launch meteor in development mode (typically with `meteor` or `meteor run`). The server console should print this line: 27 | 28 | ``` 29 | Dev server (vue-components) listening on port 3003 30 | ``` 31 | 32 | Your browser console should also output: 33 | 34 | ``` 35 | [HMR] Vue component hot reload shim applied. 36 | Dev client connected 37 | ``` 38 | 39 | Now, whenever you save a component file, it will be instantly updated on all the connected clients. 40 | 41 | By default, the package will try to use the Meteor port + 3, but you can override the port used by the hot-reloading server with the `HMR_PORT` environment variable: 42 | 43 | ``` 44 | cross-env HMR_PORT=4242 45 | ``` 46 | 47 | You can disable HMR with the `NO_HMR` var: 48 | 49 | ``` 50 | cross-env NO_HMR=1 51 | ``` 52 | 53 | #### Remote devices 54 | 55 | If you have an issue with HMR not connecting from remote devices (e.g. styles are not loading), set the `HMR_URL` env. variable with the IP of your computer. For example: 56 | 57 | ``` 58 | cross-env HMR_URL=192.168.1.42 59 | ``` 60 | 61 | ### File structure 62 | 63 | The component file must include: 64 | 65 | - Maximum one `