13 |
14 | ## Sponsors
15 |
16 | [](https://guillaume-chau.info/sponsors)
17 |
18 |
19 |
20 |
21 |
22 | vue+meteor is a set of packages to help you create awesome apps quickly and efficiently with two great web technologies:
23 |
24 | - [vuejs](http://vuejs.org/) is the frontend
25 | - [meteor](http://meteor.com/) is the platform (client, server, database, network)
26 |
27 | You will be able to [use meteor data inside Vue](https://github.com/Akryum/vue-meteor-tracker#vue-integration-for-meteor) or [write `.vue` files in your meteor project](https://github.com/Akryum/meteor-vue-component/tree/master/packages/vue-component).
28 |
29 | ### [Complete Example/Demo Project](https://github.com/Akryum/vue-meteor-demo)
30 |
31 | ## Quick Packages Links
32 |
33 | Here is a list of recommended packages for developping a meteor+vue app:
34 |
35 | - [:package: `vue-meteor-tracker`](https://github.com/Akryum/vue-meteor-tracker) (meteor tracker integration)
36 | - [:package: `akryum:vue-component`](https://github.com/Akryum/meteor-vue-component/tree/master/packages/vue-component) (vue component files)
37 | - [:package: `akryum:vue-router2`](https://github.com/Akryum/meteor-vue-component/tree/master/packages/vue-router2) (`vue-router` 2.x helpers)
38 | - [:package: `vue-apollo`](https://github.com/Akryum/vue-apollo) (apollo integration)
39 | - [:package: `vuejs:blaze-integration`](https://github.com/meteor-vue/blaze-integration) (integrate Vue and Blaze)
40 | - [:package: `vue-supply`](https://github.com/Akryum/vue-supply) (use reactive data & automatic subscriptions in components and vuex store)
41 | - [:package: `akryum:vue-ssr`](https://github.com/Akryum/vue-meteor/tree/master/packages/vue-ssr) (Server-Side Rendering)
42 |
43 | ## Resources
44 |
45 | ### Examples
46 |
47 | - [Guide Example](https://github.com/meteor-vue/guide)
48 | - [TodoMVC](https://github.com/meteor-vue/todomvc)
49 | - [Complete Example/Demo Project](https://github.com/Akryum/vue-meteor-demo)
50 |
51 |
52 |
53 | ### Meteor & Tracker data integration  
54 |
55 | Declarative subscriptions and meteor reactive data
56 |
57 | [:package: See Usage in npm vue-meteor-tracker package](https://github.com/Akryum/vue-meteor-tracker#vue-integration-for-meteor)
58 |
59 |
60 |
61 | ### Single-file component  
62 |
63 | It allows you to write your components in [this format](https://vuejs.org/v2/guide/single-file-components.html) with hot-reloading support.
64 |
65 | [:package: See Usage in arkyum:vue-component package](https://github.com/Akryum/meteor-vue-component/tree/master/packages/vue-component#usage)
66 |
67 |
68 |
69 | ### Routing 
70 |
71 | Routing for Vue 2.x and Meteor using [vue-router](https://github.com/vuejs/vue-router).
72 |
73 | [:package: See Installation & Usage in arkyum:vue-router2 package](https://github.com/Akryum/meteor-vue-component/tree/master/packages/vue-router2#installation)
74 |
75 | [Example app](https://github.com/Akryum/meteor-vue2-example-routing)
76 |
77 |
78 |
79 | ### Apollo integration  
80 |
81 | Use apollo in your vue component!
82 |
83 | [:package: See Installation & Usage in the vue-apollo npm package](https://github.com/Akryum/vue-apollo)
84 |
85 |
86 |
87 | ### Server-side rendering 
88 |
89 | Very easy way to render your frontend on the server automatically when a user first loads the app.
90 |
91 | [:package: See Installation & Usage in the akryum:vue-ssr package](https://github.com/meteor-vue/vue-meteor/tree/master/packages/vue-ssr#installation)
92 |
93 |
94 |
95 | ### Integrate Blaze 
96 |
97 | Render Blaze templates in Vue components and the other way around!
98 |
99 | [:package: See Installation & Usage in the vuejs:blaze-integration package](https://github.com/meteor-vue/blaze-integration)
100 |
101 |
102 |
103 |
104 |
105 | ## Vue 1.x
106 |
107 | See `old` branch.
108 |
109 | ---
110 |
111 | ## Features & Roadmap
112 |
113 | Currently supported and possible future features (in no particular order) are:
114 |
115 | - [x] Declarative subscriptions and meteor reactive data  
116 | - [x] Single-file components (.vue) with basic support of ``, `
33 | ```
34 |
35 | [Example app](https://github.com/Akryum/meteor-vue-blaze/tree/render-blaze)
36 |
--------------------------------------------------------------------------------
/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-blaze-template/vue-render-blaze.js:
--------------------------------------------------------------------------------
1 | import Vue from 'vue'
2 | import { Blaze } from 'meteor/blaze'
3 |
4 | const vueVersion = parseInt(Vue.version.charAt(0))
5 |
6 | if (vueVersion === 1) {
7 | Vue.directive('blaze', {
8 | update (newValue, oldValue) {
9 | if (newValue !== oldValue || !this.blazeView) {
10 | const templateName = newValue
11 | const template = Blaze._getTemplate(templateName, null)
12 | if (!template) {
13 | throw new Error(`Blaze template '${templateName}' not found.`)
14 | }
15 | if (this.blazeView) {
16 | Blaze.remove(this.blazeView)
17 | }
18 | this.blazeView = Blaze.render(template, this.el)
19 | }
20 | },
21 | unbind () {
22 | if (this.blazeView) {
23 | Blaze.remove(this.blazeView)
24 | }
25 | },
26 | })
27 | } else if (vueVersion === 2) {
28 | Vue.directive('blaze', {
29 | bind (el, {value}) {
30 | renderTemplate(el, value)
31 | },
32 | update (el, {value, oldValue}) {
33 | if (value !== oldValue || !el.blazeView) {
34 | if (el.blazeView) {
35 | Blaze.remove(el.blazeView)
36 | }
37 | renderTemplate(el, value)
38 | }
39 | },
40 | unbind (el) {
41 | if (el.blazeView) {
42 | Blaze.remove(el.blazeView)
43 | }
44 | },
45 | })
46 | }
47 |
48 | function renderTemplate (el, templateName) {
49 | const template = Blaze._getTemplate(templateName, null)
50 | if (!template) {
51 | throw new Error(`Blaze template '${templateName}' not found.`)
52 | }
53 | el.blazeView = Blaze.render(template, el)
54 | }
55 |
--------------------------------------------------------------------------------
/packages/vue-coffee/.gitignore:
--------------------------------------------------------------------------------
1 | .npm
2 |
--------------------------------------------------------------------------------
/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-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-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-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
82 | ```
83 |
84 | ### Scoped style
85 |
86 | By default, the css added with `
96 | ```
97 |
98 | ### CSS Modules
99 |
100 | As an alternative to scoped styles, you can use CSS modules to scope your CSS to your components by adding the `module` attribute to any `
108 |
109 |
110 |
Red Text
111 |
112 |
113 |
120 | ```
121 |
122 | By default, your styles will be assigned to the `$style` computed property. You can customize this by setting the module attribute. This also allows you to create multiple "modules" in one component file:
123 |
124 | ```html
125 |
130 |
135 |
136 |
137 |
Foo Text
138 |
Bar Text
139 |
140 | ```
141 |
142 | Note: composing from other files is not supported by the built-in CSS modules processor. See the community packages.
143 |
144 | ### Language packages
145 |
146 | Using the power of preprocessors, you can use a different language (like less or jade) by adding a `lang` attribute on your ``, `
197 | ```
198 |
199 | ### Manual import
200 |
201 | You can then import your .vue component files in your meteor code:
202 |
203 |
204 | ```javascript
205 | // Post
206 | import Post from '/imports/ui/Post.vue';
207 | Vue.component('post', Post);
208 | ```
209 |
210 | ### Automatic components registration
211 |
212 | `.vue` files outside of the `imports` directory are automatically registered as custom tags. The default tag name is the name of the file in kebab-case, and you can set your own with the `name` attribute in the component options.
213 |
214 | 
215 |
216 | In the example above, the `Post.vue` component is automatically available in your vue templates as ``.
217 |
218 | You can override the default naming behavior by setting the `name` option in your component:
219 |
220 | ```html
221 |
227 | ```
228 |
229 | Here your component will be available as `` regardless of the file name.
230 |
231 | ### Package name
232 |
233 | If your component files are in a package, they will have the `packageName` attribute set. You can access it in your component instances like this:
234 |
235 | ```javascript
236 | let packageName = this.$options.packageName;
237 | ```
238 |
239 | It will be null if the components is in your application code.
240 |
241 | ### Ignore files
242 |
243 | You can create `.vueignore` files with a RegEx on each line to exclude `.vue` files from the compilation based on their path. If the `.vueignore` is inside a folder, it only applies to that folder.
244 |
245 | For example, you can add the following `.vueignore` file to your app inorder to ignore `.vue` files in the `node_modules` folders:
246 |
247 | ```
248 | node_modules/
249 | ```
250 |
251 | ### Using Vue npm packages
252 |
253 | Most of the time, you need to ignore the compilation of Vue files inside the `node_modules` directory.
254 |
255 | Add a `.vueignore` file in the project root with the following content:
256 |
257 | ```
258 | node_modules/
259 | ```
260 |
261 | The npm packages should have distribution/compiled files (or try to tell their authors if they are missing). You should directly import these if you have any issue.
262 |
263 | For example, to use the [keen-ui](https://github.com/JosephusPaye/keen-ui) package, install the plugin in your app using the dist files:
264 |
265 | ```javascript
266 | import 'keen-ui/dist/keen-ui.min.css'
267 | import KeenUI from 'keen-ui/dist/keen-ui.min.js'
268 | Vue.use(KeenUI)
269 | ```
270 |
271 | ---
272 |
273 | ## Next steps
274 |
275 | - [Example project without blaze](https://github.com/Akryum/meteor-vue-example)
276 | - [Example project with blaze](https://github.com/Akryum/meteor-vue-blaze)
277 | - [Add routing to your app](https://github.com/Akryum/meteor-vue-component/tree/master/packages/vue-router#installation)
278 |
279 | ---
280 |
281 | LICENCE ISC - Created by Guillaume CHAU (@Akryum)
282 |
--------------------------------------------------------------------------------
/packages/vue-component/global_component_file_tree.png:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/meteor-vue/vue-meteor/811e1bebf6db69be023e4944f828f3eae95a192b/packages/vue-component/global_component_file_tree.png
--------------------------------------------------------------------------------
/packages/vue-component/package.js:
--------------------------------------------------------------------------------
1 | Package.describe({
2 | name: 'akryum:vue-component',
3 | version: '0.16.0',
4 | summary: 'VueJS single-file components that hot-reloads',
5 | git: 'https://github.com/Akryum/meteor-vue-component',
6 | documentation: 'README.md',
7 | })
8 |
9 | Package.registerBuildPlugin({
10 | name: 'vue-component',
11 | use: [
12 | 'ecmascript@0.12.7',
13 | 'caching-compiler@1.2.1',
14 | 'babel-compiler@7.3.4',
15 | ],
16 | sources: [
17 | 'plugin/regexps.js',
18 | 'plugin/utils.js',
19 | 'plugin/dev-server.js',
20 | 'plugin/post-css.js',
21 | 'plugin/tag-handler.js',
22 | 'plugin/vue-compiler.js',
23 | 'plugin/plugin.js',
24 | ],
25 | npmDependencies: {
26 | 'postcss': '7.0.16',
27 | 'postcss-load-config': '2.0.0',
28 | 'postcss-selector-parser': '2.2.3',
29 | 'postcss-modules': '1.4.1',
30 | 'socket.io': '2.2.0',
31 | 'async': '2.6.2',
32 | 'lodash': '4.17.11',
33 | 'hash-sum': '1.0.2',
34 | 'source-map': '0.7.3',
35 | 'source-map-merger': '0.2.0',
36 | 'generate-source-map': '0.0.5',
37 | 'autoprefixer': '9.5.1',
38 | 'vue-template-compiler': '2.7.14',
39 | 'vue-template-es2015-compiler': '1.9.1',
40 | 'colors': '1.3.3',
41 | 'app-module-path': '2.2.0',
42 | },
43 | })
44 |
45 | Package.onUse(function (api) {
46 | api.use('isobuild:compiler-plugin@1.0.0')
47 | api.use('akryum:vue-component-dev-server@0.1.4')
48 | api.use('akryum:vue-component-dev-client@0.4.7')
49 | })
50 |
--------------------------------------------------------------------------------
/packages/vue-component/plugin/dev-server.js:
--------------------------------------------------------------------------------
1 | import http from 'http'
2 | import SocketIo from 'socket.io'
3 |
4 | function getMeteorBinding () {
5 | const argv = this.process.argv
6 | if (Array.isArray(argv)) {
7 | const index = argv.findIndex(
8 | arg => arg.indexOf('-p') === 0 || arg.indexOf('--port') === 0
9 | )
10 | if (index !== -1) {
11 | const arg = argv[index]
12 | const equalIndex = arg.indexOf('=')
13 | let value
14 | if (equalIndex !== -1) {
15 | value = arg.substr(equalIndex + 1)
16 | } else {
17 | value = argv[index + 1]
18 | }
19 | const results = value.split(':')
20 | let networkInterface
21 | let port
22 | if (results.length === 2) {
23 | networkInterface = results[0]
24 | port = results[1]
25 | } else {
26 | port = results[0]
27 | }
28 | return {
29 | networkInterface,
30 | port: parseInt(port),
31 | }
32 | }
33 | } else {
34 | const reg = /(?:--port|-p)(?:=|\s)(?:([0-9.]+):)?(\d+)/gi
35 | const result = reg.exec(argv)
36 | if (result && result.length >= 2) {
37 | const networkInterface = result[1]
38 | const port = parseInt(result[2])
39 | return {
40 | networkInterface,
41 | port,
42 | }
43 | }
44 | }
45 | return {}
46 | }
47 |
48 | if (global._dev_server_http) {
49 | global._dev_server.close()
50 | global._dev_server_http.close()
51 | delete global._dev_server
52 | delete global._dev_server_http
53 | }
54 |
55 | if (isDevelopment()) {
56 | var server = http.createServer()
57 | var io = SocketIo(server, {
58 | serveClient: false,
59 | })
60 |
61 | // Stored dynamic styles
62 | io.__styles = {}
63 | io.__addStyle = function ({hash, css, path}, emit = true) {
64 | if (emit) {
65 | io.emit('css', { hash, css, path })
66 | }
67 | io.__styles[hash] = {
68 | hash,
69 | css,
70 | path,
71 | }
72 | }
73 |
74 | // Send all stored dynamic styles to new clients
75 | io.on('connection', function (socket) {
76 | for (var hash in io.__styles) {
77 | socket.emit('css', io.__styles[hash])
78 | }
79 | })
80 | const binding = getMeteorBinding.call(this)
81 | PORT = parseInt(process.env.HMR_PORT) || parseInt(process.env.VUE_DEV_SERVER_PORT) || binding.port + 3 || 3003
82 | INTERFACE = binding.networkInterface
83 |
84 | try {
85 | let status
86 | if (INTERFACE) {
87 | server.listen(PORT, INTERFACE)
88 | status = `${INTERFACE}:${PORT}`
89 | } else {
90 | server.listen(PORT)
91 | status = `port ${PORT}`
92 | }
93 | if (process.stdout.clearLine) {
94 | process.stdout.clearLine()
95 | }
96 | process.stdout.write(`\r=> [HMR] Dev server listening on ${status}.\n`)
97 | global._dev_server = io
98 | global._dev_server_http = server
99 | } catch (e) {
100 | console.log(e)
101 | }
102 | }
103 |
--------------------------------------------------------------------------------
/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-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
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-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/vue-less/vue-less.js:
--------------------------------------------------------------------------------
1 | import path from 'path'
2 | import fs from 'fs'
3 | import less from 'less'
4 | import {Meteor} from 'meteor/meteor'
5 |
6 | global.vue = global.vue || {}
7 | global.vue.lang = global.vue.lang || {}
8 |
9 | function MeteorImportLessPlugin (dependencyManager) {
10 | this.minVersion = [2, 5, 0]
11 |
12 | this.install = (less, pluginManager) => {
13 | pluginManager.addFileManager(new MeteorImportLessFileManager(dependencyManager))
14 | }
15 | }
16 |
17 | class MeteorImportLessFileManager extends less.AbstractFileManager {
18 | constructor (dependencyManager) {
19 | super()
20 | this.dependencyManager = dependencyManager
21 | }
22 |
23 | // We want to be the only active FileManager, so claim to support everything.
24 | supports (filename) {
25 | // We shouldn't process files that start with `//` or a protocol because
26 | // those are not relative to the app at all they are probably native
27 | // CSS imports
28 | if (!filename.match(/^(https?:)?\/\//)) {
29 | return true
30 | }
31 |
32 | return false
33 | }
34 |
35 | loadFile (filename, currentDirectory, options, environment, cb) {
36 | // console.log(filename, currentDirectory)
37 | // console.log("### options", options, "### env", environment, "###")
38 |
39 | let resolvedFilename
40 | if (filename.indexOf('~') === 0) {
41 | resolvedFilename = filename.substr(1)
42 | /* } else if (filename.indexOf('{') === 0) {
43 | resolvedFilename = decodeFilePath(filename) */
44 | } else {
45 | resolvedFilename = path.resolve(currentDirectory, filename)
46 | }
47 |
48 | if (!/\.less$/i.test(resolvedFilename)) {
49 | resolvedFilename += '.less'
50 | }
51 |
52 | if (!fs.existsSync(resolvedFilename)) {
53 | cb({
54 | type: 'File',
55 | message: 'Unknown import (file not found): ' + filename,
56 | })
57 | } else {
58 | let contents = fs.readFileSync(resolvedFilename, {
59 | encoding: 'utf8',
60 | })
61 |
62 | cb(null, {
63 | contents,
64 | filename: resolvedFilename,
65 | })
66 |
67 | this.dependencyManager.addDependency(resolvedFilename)
68 | }
69 | }
70 | }
71 |
72 | // function decodeFilePath (filePath) {
73 | // const match = filePath.match(/^{(.*)}\/(.*)$/)
74 | // if (!match) { throw new Error('Failed to decode Less path: ' + filePath) }
75 |
76 | // if (match[1] === '') {
77 | // // app
78 | // return match[2]
79 | // }
80 |
81 | // return 'packages/' + match[1] + '/' + match[2]
82 | // }
83 |
84 | const importPlugins = {}
85 |
86 | function getKey (inputFile) {
87 | return `${inputFile.getPackageName()}:${inputFile.getPathInPackage()}`
88 | }
89 |
90 | function getImportPlugin (inputFile, dependencyManager) {
91 | const key = getKey(inputFile)
92 | let result = importPlugins[key]
93 | if (!result) {
94 | result = importPlugins[key] = new MeteorImportLessPlugin(dependencyManager)
95 | }
96 | return result
97 | }
98 |
99 | global.vue.lang.less = Meteor.wrapAsync(function ({
100 | source,
101 | inputFile,
102 | basePath,
103 | dependencyManager,
104 | }, cb) {
105 | less.render(source, {
106 | filename: basePath,
107 | plugins: [getImportPlugin(inputFile, dependencyManager)],
108 | sourceMap: {
109 | outputSourceFiles: true,
110 | },
111 | }).then(function (output) {
112 | cb(null, {
113 | css: output.css,
114 | map: output.map,
115 | })
116 | }, function (error) {
117 | console.error(error)
118 | cb(error, null)
119 | })
120 | })
121 |
--------------------------------------------------------------------------------
/packages/vue-pug/.gitignore:
--------------------------------------------------------------------------------
1 | .npm
2 |
--------------------------------------------------------------------------------
/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/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 |
16 | .post
17 | .message {{data.message}}
18 | a.action(@click="removePost") x
19 |
20 | ```
21 |
22 | ---
23 |
24 | LICENCE ISC - Created by Guillaume CHAU (@Akryum)
25 |
--------------------------------------------------------------------------------
/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/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-router2/.gitignore:
--------------------------------------------------------------------------------
1 | .npm
2 |
--------------------------------------------------------------------------------
/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 |
--------------------------------------------------------------------------------
/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-router2/README.md:
--------------------------------------------------------------------------------
1 | # Vue-router 2.x integration for Meteor
2 |
3 | Compatibility: **Vue 2.x**
4 |
5 | ## Add routes in the blink of an eye.
6 | Routing for vue and meteor using [vue-router](https://github.com/vuejs/vue-router).
7 |
8 | See the [example here](https://github.com/Akryum/meteor-vue2-example-routing).
9 |
10 | ## Installation
11 |
12 |
13 | meteor add akryum:vue-router2
14 |
15 | ## Usage
16 |
17 | ### Router options
18 |
19 | With this package, we will not directly configure the `router` instance, but will use a factory instead. This is to easy the definition of routes regarding how Meteor build files (especially in a large project).
20 |
21 | First, let's create our router factory:
22 |
23 | ```javascript
24 | /* /client/client.js */
25 |
26 | // Import the router factory
27 | import { RouterFactory, nativeScrollBehavior } from 'meteor/akryum:vue-router2'
28 |
29 | // Create router instance
30 | const routerFactory = new RouterFactory({
31 | mode: 'history',
32 | scrollBehavior: nativeScrollBehavior,
33 | })
34 | ```
35 |
36 | When you create the router factory, you can pass router `options` that allows you to customize the router behavior ([more info](http://router.vuejs.org/en/api/options.html)).
37 |
38 | ### Route definition
39 |
40 | In your client, add some routes with the `RouterFactory.configure()` method (for more info about route definition, check the [vue-router documentation](http://router.vuejs.org/en/essentials/nested-routes.html)):
41 |
42 | ```javascript
43 | /* /client/routes.js */
44 |
45 | // Import the router
46 | import { RouterFactory } from 'meteor/akryum:vue-router2'
47 |
48 | // Components
49 | import Home from '/imports/ui/Home.vue'
50 | import Forum from '/imports/ui/Forum.vue'
51 | import Apollo from '/imports/ui/Apollo.vue'
52 |
53 | RouterFactory.configure(factory => {
54 | // Simple routes
55 | factory.addRoutes([
56 | {
57 | path: '/',
58 | name: 'home',
59 | component: Home,
60 | },
61 | {
62 | path: '/forum',
63 | name: 'forum',
64 | component: Forum,
65 | },
66 | {
67 | path: '/apollo',
68 | name: 'apollo',
69 | component: Apollo,
70 | },
71 | ])
72 | })
73 | ```
74 |
75 | **Attention! The order of the routes matters during the route matching!**
76 |
77 | The callbacks you pass to the `RouterFactory.configure()` calls will be called before the router is started, regardless of the file load order.
78 |
79 | You can pass a second integer argument `priority`, that changes the order in which the callbacks are called to add routes. Callbacks with higher priority will be called before the others. The default priority is `0`.
80 |
81 | #### Simple syntax
82 |
83 | You can use an alternative special syntax in `.routes.js` files:
84 |
85 | ```javascript
86 | /* /client/main.routes.js */
87 | export default [
88 | {
89 | path: '/',
90 | name: 'home',
91 | component: '/imports/ui/Home.vue'
92 | },
93 | {
94 | path: '/forum',
95 | name: 'forum',
96 | component: '/imports/ui/Forum.vue'
97 | },
98 | {
99 | path: '/apollo',
100 | name: 'apollo',
101 | component: '/imports/ui/Apollo.vue'
102 | }
103 | ];
104 | ```
105 |
106 | All the routes will be automatically added and the component's paths resolved.
107 |
108 | ### App menu
109 |
110 | Use the `router-link` component to add dynamic links that take to different routes in your app ([more info](http://router.vuejs.org/en/api/router-link.html)):
111 |
112 | ```html
113 |
114 |
115 |