vueport 0.1.0 → 0.1.1

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
Files changed (34) hide show
  1. checksums.yaml +4 -4
  2. data/Gemfile +1 -1
  3. data/README.md +10 -8
  4. data/lib/generators/vueport/install_generator.rb +56 -125
  5. data/{example/babelrc → lib/generators/vueport/template/.babelrc} +0 -0
  6. data/lib/generators/vueport/template/.eslintignore +4 -0
  7. data/lib/generators/vueport/template/.eslintrc.js +33 -0
  8. data/lib/generators/vueport/template/Procfile +2 -0
  9. data/{example/Procfile → lib/generators/vueport/template/Procfile.dev} +1 -1
  10. data/lib/generators/vueport/template/package.json +43 -0
  11. data/lib/generators/vueport/template/renderer/.eslintrc.js +28 -0
  12. data/lib/generators/vueport/template/renderer/index.js +34 -0
  13. data/lib/generators/vueport/template/renderer/package.json +17 -0
  14. data/lib/generators/vueport/template/vueport/build.js +44 -0
  15. data/lib/generators/vueport/template/vueport/config.js +25 -0
  16. data/lib/generators/vueport/template/vueport/utils.js +61 -0
  17. data/lib/generators/vueport/template/vueport/webpack.base.conf.js +119 -0
  18. data/lib/generators/vueport/template/vueport/webpack.dev.conf.js +30 -0
  19. data/lib/generators/vueport/template/vueport/webpack.prod.conf.js +43 -0
  20. data/lib/generators/vueport/template/vueport/webpack.server.conf.js +40 -0
  21. data/{example → lib/generators/vueport/template/webpack}/application.js +1 -1
  22. data/lib/generators/vueport/template/webpack/server.js +9 -0
  23. data/lib/generators/vueport/template/webpack/setup.js +18 -0
  24. data/lib/vueport.rb +2 -1
  25. data/lib/vueport/railtie.rb +0 -4
  26. data/lib/vueport/version.rb +1 -1
  27. data/vueport.gemspec +1 -0
  28. metadata +36 -12
  29. data/example/Procfile.dev +0 -2
  30. data/example/index.js +0 -35
  31. data/example/server.js +0 -10
  32. data/example/setup.js +0 -14
  33. data/example/webpack.server.js +0 -59
  34. data/lib/tasks/vueport.rake +0 -24
checksums.yaml CHANGED
@@ -1,7 +1,7 @@
1
1
  ---
2
2
  SHA1:
3
- metadata.gz: 45dc87f34b0a0b04c7de4f4754b968397e6a3cfa
4
- data.tar.gz: 7b1e46d1c085bf4679c7db3c0c4fe7751d0b6bc8
3
+ metadata.gz: 147bdb73bbbd594daa855c6c32461e5b6a3b4a88
4
+ data.tar.gz: a84bd46db6183701c34b159fdbece981b6150f60
5
5
  SHA512:
6
- metadata.gz: fdd177551b9f4b464ce3ac8076e8187fb9bf8a6494698f3b639f987cec6f2c6cc99af1930f6bb39c9063cfdda40300099cc4059a34e3c45a6ad0c4d488cea1af
7
- data.tar.gz: 1463e24bf2e439afb5aab46a9ea47f450f4ef760e5ae04f078175f71ff973eef9f757fa397c4a86b95498f720183ea8828dd900806792d4d97b4195e503cb96f
6
+ metadata.gz: 72e0085bd54a0eb721244dbbbea89f589334015f6f20a8ec96b2283b35dc3039e0f586944d4b3cf5fb521a613ee5c066f292a2e4079ff51b19cb4f347df5b130
7
+ data.tar.gz: 4942208142a73c3458686df5e5e19b6bca3574bdf96f8cd5998fc36e65f10e1020c9e859d106d1249cffe67136df95a9d2ff89976c6d434bfc448445b79b80a3
data/Gemfile CHANGED
@@ -4,6 +4,6 @@ source 'https://rubygems.org'
4
4
  gemspec
5
5
 
6
6
  group :test do
7
+ gem 'pry'
7
8
  gem 'pry-byebug'
8
- gem 'pry-rails'
9
9
  end
data/README.md CHANGED
@@ -110,13 +110,15 @@ _Check out the WebpackRails gem for information on its configuration._
110
110
 
111
111
  ## How does it work?
112
112
 
113
- To see how WebpackRails works, take a look at [this section of the readme](https://github.com/mipearson/webpack-rails#how-it-works).
113
+ What Vueport gives you is effectively 3 applications:
114
114
 
115
- Vueport extends the functionality of WebpackRails by adding a few extra features:
115
+ - Your base rails app
116
+ - A Node app for server side rendering in production (in /renderer)
117
+ - A Node app for running webpack in development
116
118
 
117
- - Webpack setup to read and compile Vue components
118
- - Webpack setup to enable HMR (Hot Module Reloading) for an A+ development experience
119
- - Server Side rendering in production.
119
+ These have been set up so that they can be built for production completely separately to avoid complicated pipelines—for example, you can run these 3 application using Docker completely separately meaning you don't need Ruby and Node in a single Dockerfile.
120
+
121
+ For more information on how Webpack has been integrated with Rails, check out [this section of the Webpack Rails readme](https://github.com/mipearson/webpack-rails#how-it-works).
120
122
 
121
123
  ### Server Side Rendering (SSR)
122
124
 
@@ -135,7 +137,7 @@ For a Vue.js and React [collaborative](https://github.com/vuejs/vuejs.org/issues
135
137
  ## To Do
136
138
 
137
139
  - [x] Handle SSR
138
- - [ ] Make webpack config more like the config from the [Vue CLI template](https://github.com/vuejs-templates/webpack/tree/master/template/build)
140
+ - [x] Make webpack config more like the config from the [Vue CLI template](https://github.com/vuejs-templates/webpack/tree/master/template/build)
139
141
  - [ ] Optimize SSR interaction with NodeJS
140
142
  - [ ] JS Component test setup
141
143
 
@@ -151,8 +153,8 @@ Bug reports and pull requests are welcome on GitHub at https://github.com/samtga
151
153
 
152
154
  ## Thanks
153
155
 
154
- - Many thanks to [Evan You](https://github.com/yyx990803) and the VueJS for sustaining such a vibrant and supporting community around Vue JS
155
- - Many thanks also to [mipearson](https://github.com/mipearson) for his WebpackRails gem which this gem completely cannibalizes
156
+ - Many thanks to [Evan You](https://github.com/yyx990803) and the VueJS team for sustaining such a vibrant and supportive community around Vue JS
157
+ - Many thanks also to [mipearson](https://github.com/mipearson) for his WebpackRails gem on which this gem relies.
156
158
 
157
159
  ## License
158
160
 
@@ -1,166 +1,97 @@
1
1
  module Vueport
2
2
  class InstallGenerator < ::Rails::Generators::Base
3
- source_root File.expand_path('../../../../example', __FILE__)
3
+ source_root File.expand_path('../template', __FILE__)
4
+
4
5
  desc 'Install extras for using Vue with WebpackRails'
5
6
 
6
7
  def add_webpack_rails
7
8
  gem 'webpack-rails'
8
- end
9
-
10
- def bundle_and_install_webpack
11
- run 'gem install webpack-rails'
12
- generate 'webpack_rails:install'
9
+ gem 'foreman'
13
10
  end
14
11
 
15
12
  def add_to_gitignore
16
13
  append_to_file '.gitignore' do
17
14
  <<-EOF.strip_heredoc
18
- npm-debug.log
15
+ # Added by vueport
16
+ /node_modules
17
+ /public/webpack
18
+ /npm-debug.log
19
+
20
+ /renderer/node_modules
21
+ /renderer/npm-debug.log
22
+ /renderer/bundle.server.js
19
23
  EOF
20
24
  end
21
25
  end
22
26
 
23
- def insert_resolve
24
- inject_into_file 'config/webpack.config.js', after: "root: path.join(__dirname, '..', 'webpack')" do
25
- <<~HEREDOC
26
- ,
27
- extensions: ['', '.js', '.vue'],
28
- fallback: [path.join(__dirname, '../node_modules'), path.join(__dirname, '../app/'),],
29
- alias: {
30
- // Use the standalone build to compile our page at runtime
31
- 'vue$': 'vue/dist/vue.common.js'
32
- }
33
- HEREDOC
34
- end
35
- end
36
-
37
- def insert_module
38
- inject_into_file 'config/webpack.config.js', after: "assets: true\n })]" do
39
- <<~HEREDOC
40
- ,
41
- // Use the necessary loaders to process our components
42
- module: {
43
- loaders: [
44
- {
45
- test: /\.vue$/,
46
- loader: 'vue'
47
- },
48
- {
49
- loaders: ['babel'],
50
- test: /\.js$/,
51
- exclude: /node_modules/
52
- },
53
- {
54
- test: /\.css$/,
55
- loader: production ? ExtractTextPlugin.extract('vue-style', 'css') : 'style!css',
56
- fallbackLoader: 'vue-style-loader'
57
- }
58
- ]
59
- },
60
- vue: {
61
- loaders: {
62
- css: production ? ExtractTextPlugin.extract('vue-style', "css") : 'style!css'
63
- }
64
- }
65
- HEREDOC
66
- end
27
+ def copy_package_json
28
+ copy_file 'package.json'
67
29
  end
68
30
 
69
- def update_procfile
70
- remove_file 'Procfile'
71
- copy_file 'Procfile.dev', 'Procfile.dev'
72
- copy_file 'Procfile', 'Procfile'
31
+ def copy_eslint
32
+ copy_file '.eslintrc.js'
33
+ copy_file '.eslintignore'
73
34
  end
74
35
 
75
- def insert_css_extract
76
- inject_into_file 'config/webpack.config.js', after: "var StatsPlugin = require('stats-webpack-plugin');" do
77
- <<~HEREDOC
78
-
79
- var ExtractTextPlugin = require("extract-text-webpack-plugin");
80
- HEREDOC
81
- end
82
-
83
- inject_into_file 'config/webpack.config.js', after: 'new webpack.optimize.OccurenceOrderPlugin()' do
84
- <<~HEREDOC
85
- ,
86
- new ExtractTextPlugin('[name]-[chunkhash].css')
87
- HEREDOC
88
- end
36
+ def copy_config_files
37
+ directory 'vueport', 'config/vueport'
89
38
  end
90
39
 
91
- def update_dev_tool
92
- gsub_file 'config/webpack.config.js', 'cheap-module-eval-source-map', '#eval-source-map'
40
+ def copy_renderer_files
41
+ directory 'renderer'
93
42
  end
94
43
 
95
- def create_server_config
96
- copy_file 'webpack.server.js', 'config/webpack.server.js'
44
+ def update_procfile
45
+ copy_file 'Procfile.dev'
46
+ copy_file 'Procfile'
97
47
  end
98
48
 
99
49
  def create_setup_files
100
- remove_file 'webpack/application.js'
101
- copy_file 'application.js', 'webpack/application.js'
102
- copy_file 'setup.js', 'webpack/setup.js'
103
- copy_file 'server.js', 'webpack/server.js'
104
- copy_file 'index.js', 'index.js'
105
- copy_file 'babelrc', '.babelrc'
50
+ directory 'webpack'
51
+ copy_file '.babelrc'
106
52
  empty_directory 'app/components'
107
53
  end
108
54
 
109
- def add_npm_scripts
110
- inject_into_file 'package.json', before: '"dependencies": {' do
111
- <<~HEREDOC
112
- "scripts": {
113
- "dev-server": "./node_modules/.bin/webpack-dev-server --hot --inline --config config/webpack.config.js --host 0.0.0.0",
114
- "start": "NODE_ENV=production node ."
115
- },
116
-
117
- HEREDOC
55
+ def run_npm_install
56
+ if yarn? && yes?("Would you like me to run 'yarn' for you? [y/N]")
57
+ run 'yarn'
58
+ run 'cd renderer && yarn'
59
+ elsif !yarn? && yes?("Would you like me to run 'npm install' for you? [y/N]")
60
+ run 'npm i'
61
+ run 'cd renderer && npm i'
118
62
  end
119
63
  end
120
64
 
121
- def add_npm_dependencies
122
- inject_into_file 'package.json', after: '"webpack-dev-server": "^1.9.0"' do
123
- <<~HEREDOC
124
- ,
125
- "body-parser": "^1.15.2",
126
- "express": "^4.14.0",
127
- "morgan": "^1.7.0",
128
- "extract-text-webpack-plugin": "^1.0.1",
129
- "vue": "^2.1.3",
130
- "vue-server-renderer": "^2.1.3",
131
- "babel-core": "^6.17.0",
132
- "babel-loader": "^6.2.5",
133
- "babel-polyfill": "^6.16.0",
134
- "babel-preset-es2015": "^6.16.0",
135
- "babel-preset-stage-0": "^6.16.0",
136
- "css-loader": "^0.25.0",
137
- "style-loader": "^0.13.1",
138
- "vue-loader": "^10.0.1",
139
- "vue-style-loader": "^1.0.0",
140
- "vue-template-compiler": "^2.1.3"
141
- HEREDOC
142
- end
143
- end
144
-
145
- def run_npm_install
146
- run 'npm install' if yes?("Would you like me to run 'npm install' for you (I've added a few things since last time?) [y/N]")
65
+ def run_bundle_install
66
+ run 'bundle install' if yes?("Would you like me to run 'bundle install' for you? [y/N]")
147
67
  end
148
68
 
69
+ # rubocop:disable Metrics/MethodLength
149
70
  def whats_next
150
- # rubocop:disable Rails/Output
151
- puts <<-EOF.strip_heredoc
71
+ say ''
72
+ say 'All done!', :green
73
+
74
+ say ''
75
+ say "I've added a few things here and there to set you up using Vue in your Rails app."
76
+ say "Now you're already to create your first Vue component in app/components."
77
+ say ''
152
78
 
153
- I've added a few things here and there to set you up using Vue in your Rails app.
79
+ say 'To run the webpack-dev-server and rails server:'
80
+ say 'foreman start -f Procfile.dev', :yellow
81
+ say ''
154
82
 
155
- Now you're already to create your first Vue component in app/components.
156
- Run 'foreman start' to run the webpack-dev-server and rails server.
83
+ say 'For more info, see the README.md for this gem at:'
84
+ say 'https://github.com/samtgarson/vueport', :blue
85
+ say ''
157
86
 
158
- See the README.md for this gem at
159
- https://github.com/samtgarson/vueport
160
- for more info.
161
- Thanks for using Vueport!
162
- EOF
163
- # rubocop:enable Rails/Output
87
+ say 'Thanks for using Vueport!'
164
88
  end
89
+ # rubocop:enable Metrics/MethodLength
90
+
91
+ private
92
+
93
+ def yarn?
94
+ @yarn ||= `yarn -V`.present?
95
+ end
165
96
  end
166
97
  end
@@ -0,0 +1,4 @@
1
+ public/**/*.js
2
+ config/**/*.js
3
+ node_modules/**/*.js
4
+ renderer/node_modules/**/*.js
@@ -0,0 +1,33 @@
1
+ module.exports = {
2
+ root: true,
3
+ parser: 'babel-eslint',
4
+ parserOptions: {
5
+ sourceType: 'module'
6
+ },
7
+ extends: 'airbnb-base',
8
+ // required to lint *.vue files
9
+ plugins: [
10
+ 'html'
11
+ ],
12
+ // check if imports actually resolve
13
+ 'settings': {
14
+ 'import/resolver': {
15
+ 'webpack': {
16
+ 'config': 'config/vueport/webpack.base.conf.js'
17
+ }
18
+ }
19
+ },
20
+ // add your custom rules here
21
+ 'rules': {
22
+ // don't require .vue extension when importing
23
+ 'import/extensions': ['error', 'always', {
24
+ 'js': 'never',
25
+ 'vue': 'never'
26
+ }],
27
+ 'comma-dangle': ['error', 'never'],
28
+ 'space-before-function-paren': ['error', 'always'],
29
+ 'semi': ['error', 'never'],
30
+ // allow debugger during development
31
+ 'no-debugger': process.env.NODE_ENV === 'production' ? 2 : 0
32
+ }
33
+ }
@@ -0,0 +1,2 @@
1
+ rails: bundle exec rails server
2
+ node: cd renderer && npm run start
@@ -1,2 +1,2 @@
1
1
  rails: bundle exec rails server
2
- webpack: npm run start
2
+ webpack: npm run dev
@@ -0,0 +1,43 @@
1
+ {
2
+ "name": "vueport-example",
3
+ "version": "0.0.1",
4
+ "license": "MIT",
5
+ "description": "Example Rails application using Vueport and Vue single file components",
6
+ "main": "index.js",
7
+ "repository": {
8
+ "url": "git@github.com:samtgarson/vueport-example.git",
9
+ "type": "git"
10
+ },
11
+ "author": "Sam Garson <samtgarson@gmail.com>",
12
+ "scripts": {
13
+ "dev": "./node_modules/.bin/webpack-dev-server --hot --inline --config config/vueport/webpack.dev.conf --host 0.0.0.0",
14
+ "compile": "node config/vueport/build"
15
+ },
16
+ "dependencies": {
17
+ "babel-core": "^6.17.0",
18
+ "babel-eslint": "^7.1.1",
19
+ "babel-loader": "^6.2.5",
20
+ "babel-polyfill": "^6.16.0",
21
+ "babel-preset-es2015": "^6.16.0",
22
+ "babel-preset-stage-0": "^6.16.0",
23
+ "css-loader": "^0.25.0",
24
+ "eslint": "^3.12.0",
25
+ "eslint-config-airbnb-base": "^10.0.1",
26
+ "eslint-friendly-formatter": "^2.0.6",
27
+ "eslint-import-resolver-webpack": "^0.7.1",
28
+ "eslint-loader": "^1.6.1",
29
+ "eslint-plugin-html": "^1.7.0",
30
+ "eslint-plugin-import": "^2.2.0",
31
+ "extract-text-webpack-plugin": "^1.0.1",
32
+ "ora": "^0.4.0",
33
+ "stats-webpack-plugin": "^0.2.1",
34
+ "style-loader": "^0.13.1",
35
+ "vue": "^2.1.4",
36
+ "vue-loader": "^10.0.1",
37
+ "vue-style-loader": "^1.0.0",
38
+ "vue-template-compiler": "^2.1.4",
39
+ "webpack": "^1.9.11",
40
+ "webpack-dev-server": "^1.9.0",
41
+ "webpack-merge": "^1.1.1"
42
+ }
43
+ }
@@ -0,0 +1,28 @@
1
+ module.exports = {
2
+ root: true,
3
+ parser: 'babel-eslint',
4
+ parserOptions: {
5
+ sourceType: 'module'
6
+ },
7
+ extends: 'airbnb-base',
8
+ // required to lint *.vue files
9
+ plugins: [
10
+ 'html'
11
+ ],
12
+ // check if imports actually resolve
13
+ 'settings': {
14
+ 'import/resolver': {
15
+ 'webpack': {
16
+ 'config': '../config/vueport/webpack.base.conf.js'
17
+ }
18
+ }
19
+ },
20
+ // add your custom rules here
21
+ 'rules': {
22
+ // allow debugger during development
23
+ 'comma-dangle': ['error', 'never'],
24
+ 'space-before-function-paren': ['error', 'always'],
25
+ 'semi': ['error', 'never'],
26
+ 'no-debugger': process.env.NODE_ENV === 'production' ? 2 : 0
27
+ }
28
+ }
@@ -0,0 +1,34 @@
1
+ const app = require('express')()
2
+ const fs = require('fs')
3
+ const path = require('path')
4
+ const bodyParser = require('body-parser')
5
+ const vueServerRenderer = require('vue-server-renderer')
6
+ const morgan = require('morgan')
7
+
8
+ const filePath = path.join(__dirname, './bundle.server.js')
9
+ const code = fs.readFileSync(filePath, 'utf8')
10
+ const bundleRenderer = vueServerRenderer.createBundleRenderer(code)
11
+
12
+ const PORT = process.env.PORT || 5000
13
+
14
+ app.use(bodyParser.text())
15
+ app.use(morgan('tiny'))
16
+
17
+ const render = html => new Promise((resolve, reject) => {
18
+ bundleRenderer.renderToString({ body: html }, (err, res) => {
19
+ if (err) return reject(err)
20
+ return resolve(res)
21
+ })
22
+ })
23
+
24
+ app.post('/render', (req, res) => {
25
+ if (typeof req.body !== 'string' || req.body.length === 0) return res.status(400).send('')
26
+ return render(req.body)
27
+ .catch((err) => {
28
+ console.error(err)
29
+ res.status(500).send(JSON.stringify(err))
30
+ })
31
+ .then(html => res.send(html))
32
+ })
33
+
34
+ app.listen(PORT, () => console.log('listening on', PORT))
@@ -0,0 +1,17 @@
1
+ {
2
+ "name": "vueport-renderer",
3
+ "repository": "samtgarson/vueport",
4
+ "description": "Vueport Server Side Renderer",
5
+ "version": "0.0.1",
6
+ "license": "MIT",
7
+ "scripts": {
8
+ "start": "node ."
9
+ },
10
+ "dependencies": {
11
+ "body-parser": "^1.15.2",
12
+ "express": "^4.14.0",
13
+ "morgan": "^1.7.0",
14
+ "vue-server-renderer": "2.1.4",
15
+ "vue-template-compiler": "2.1.4"
16
+ }
17
+ }
@@ -0,0 +1,44 @@
1
+ // https://github.com/shelljs/shelljs
2
+ require('shelljs/global')
3
+ env.NODE_ENV = 'production'
4
+
5
+ var path = require('path')
6
+ var config = require('./config')
7
+ var ora = require('ora')
8
+ var webpack = require('webpack')
9
+ var clientConfig = require('./webpack.prod.conf')
10
+ var serverConfig = require('./webpack.server.conf')
11
+
12
+ var spinner = ora('building client bundle for production...')
13
+ spinner.start()
14
+
15
+ var assetsPath = path.join(config.build.assetsRoot)
16
+ rm('-rf', assetsPath)
17
+ mkdir('-p', assetsPath)
18
+
19
+ var statsConfig = {
20
+ colors: true,
21
+ modules: false,
22
+ children: false,
23
+ chunks: false,
24
+ chunkModules: false
25
+ }
26
+
27
+ webpack(clientConfig, function (err, stats) {
28
+ spinner.stop()
29
+ if (err) throw err
30
+ process.stdout.write(stats.toString(statsConfig) + '\n')
31
+
32
+ server()
33
+ })
34
+
35
+ var server = function () {
36
+ var spinner = ora('building server bundle for production...')
37
+ spinner.start()
38
+
39
+ webpack(serverConfig, function (err, stats) {
40
+ spinner.stop()
41
+ if (err) throw err
42
+ process.stdout.write(stats.toString(statsConfig) + '\n')
43
+ })
44
+ }
@@ -0,0 +1,25 @@
1
+ // see http://vuejs-templates.github.io/webpack for documentation.
2
+ var path = require('path')
3
+
4
+ module.exports = {
5
+ build: {
6
+ env: { NODE_ENV: '"production"' },
7
+ assetsRoot: path.resolve(__dirname, '../../public/webpack'),
8
+ assetsSubDirectory: '/',
9
+ assetsPublicPath: '/',
10
+ productionSourceMap: true
11
+ },
12
+ dev: {
13
+ env: { NODE_ENV: '"development"' },
14
+ port: 8080,
15
+ assetsSubDirectory: '/',
16
+ assetsPublicPath: '/',
17
+ proxyTable: {},
18
+ // CSS Sourcemaps off by default because relative paths are "buggy"
19
+ // with this option, according to the CSS-Loader README
20
+ // (https://github.com/webpack/css-loader#sourcemaps)
21
+ // In our experience, they generally work as expected,
22
+ // just be aware of this issue when enabling this option.
23
+ cssSourceMap: false
24
+ }
25
+ }
@@ -0,0 +1,61 @@
1
+ var path = require('path')
2
+ var config = require('./config')
3
+ var ExtractTextPlugin = require('extract-text-webpack-plugin')
4
+
5
+ exports.assetsPath = function (_path) {
6
+ var assetsSubDirectory = process.env.NODE_ENV === 'production'
7
+ ? config.build.assetsSubDirectory
8
+ : config.dev.assetsSubDirectory
9
+ return path.posix.join(assetsSubDirectory, _path)
10
+ }
11
+
12
+ exports.cssLoaders = function (options) {
13
+ options = options || {}
14
+ // generate loader string to be used with extract text plugin
15
+ function generateLoaders (loaders) {
16
+ var sourceLoader = loaders.map(function (loader) {
17
+ var extraParamChar
18
+ if (/\?/.test(loader)) {
19
+ loader = loader.replace(/\?/, '-loader?')
20
+ extraParamChar = '&'
21
+ } else {
22
+ loader = loader + '-loader'
23
+ extraParamChar = '?'
24
+ }
25
+ return loader + (options.sourceMap ? extraParamChar + 'sourceMap' : '')
26
+ }).join('!')
27
+
28
+ // Extract CSS when that option is specified
29
+ // (which is the case during production build)
30
+ if (options.extract) {
31
+ return ExtractTextPlugin.extract('vue-style-loader', sourceLoader)
32
+ } else {
33
+ return ['vue-style-loader', sourceLoader].join('!')
34
+ }
35
+ }
36
+
37
+ // http://vuejs.github.io/vue-loader/en/configurations/extract-css.html
38
+ return {
39
+ css: generateLoaders(['css']),
40
+ postcss: generateLoaders(['css']),
41
+ less: generateLoaders(['css', 'less']),
42
+ sass: generateLoaders(['css', 'sass?indentedSyntax']),
43
+ scss: generateLoaders(['css', 'sass']),
44
+ stylus: generateLoaders(['css', 'stylus']),
45
+ styl: generateLoaders(['css', 'stylus'])
46
+ }
47
+ }
48
+
49
+ // Generate loaders for standalone style files (outside of .vue)
50
+ exports.styleLoaders = function (options) {
51
+ var output = []
52
+ var loaders = exports.cssLoaders(options)
53
+ for (var extension in loaders) {
54
+ var loader = loaders[extension]
55
+ output.push({
56
+ test: new RegExp('\\.' + extension + '$'),
57
+ loader: loader
58
+ })
59
+ }
60
+ return output
61
+ }
@@ -0,0 +1,119 @@
1
+ var path = require('path')
2
+ var config = require('./config')
3
+ var utils = require('./utils')
4
+ var projectRoot = path.resolve(__dirname, '../../')
5
+ var StatsPlugin = require('stats-webpack-plugin')
6
+
7
+ var env = process.env.NODE_ENV
8
+ // check env & config/index.js to decide weither to enable CSS Sourcemaps for the
9
+ // various preprocessor loaders added to vue-loader at the end of this file
10
+ var cssSourceMapDev = (env === 'development' && config.dev.cssSourceMap)
11
+ var cssSourceMapProd = (env === 'production' && config.build.productionSourceMap)
12
+ var useCssSourceMap = cssSourceMapDev || cssSourceMapProd
13
+
14
+ module.exports = {
15
+ entry: {
16
+ application: './webpack/application.js'
17
+ },
18
+ output: {
19
+ path: config.build.assetsRoot,
20
+ publicPath: '/webpack/',
21
+ filename: '[name].js'
22
+ },
23
+ resolve: {
24
+ extensions: ['', '.js', '.vue'],
25
+ fallback: [
26
+ path.join(projectRoot, 'node_modules'),
27
+ ],
28
+ alias: {
29
+ 'vue$': 'vue/dist/vue.common.js',
30
+ 'components': path.resolve(projectRoot, 'app/components'),
31
+ 'assets': path.resolve(projectRoot, 'app/assets')
32
+ }
33
+ },
34
+ resolveLoader: {
35
+ fallback: [path.join(projectRoot, 'node_modules')]
36
+ },
37
+ module: {
38
+ preLoaders: [
39
+ {
40
+ test: /\.vue$/,
41
+ loader: 'eslint',
42
+ include: projectRoot,
43
+ exclude: /node_modules/
44
+ },
45
+ {
46
+ test: /\.js$/,
47
+ loader: 'eslint',
48
+ include: projectRoot,
49
+ exclude: /node_modules/
50
+ }
51
+ ],
52
+ loaders: [
53
+ {
54
+ test: /\.vue$/,
55
+ loader: 'vue'
56
+ },
57
+ {
58
+ test: /\.js$/,
59
+ loader: 'babel',
60
+ include: projectRoot,
61
+ exclude: /node_modules/
62
+ },
63
+ {
64
+ test: /\.pug$/,
65
+ loader: 'pug',
66
+ include: projectRoot,
67
+ exclude: /node_modules/
68
+ },
69
+ {
70
+ test: /\.sass$/,
71
+ loader: 'sass',
72
+ include: projectRoot,
73
+ exclude: /node_modules/
74
+ },
75
+ {
76
+ test: /\.json$/,
77
+ loader: 'json'
78
+ },
79
+ {
80
+ test: /\.(png|jpe?g|gif|svg)(\?.*)?$/,
81
+ loader: 'url',
82
+ query: {
83
+ limit: 10000,
84
+ name: utils.assetsPath('img/[name].[hash:7].[ext]')
85
+ }
86
+ },
87
+ {
88
+ test: /\.(woff2?|eot|ttf|otf)(\?.*)?$/,
89
+ loader: 'url',
90
+ query: {
91
+ limit: 10000,
92
+ name: utils.assetsPath('fonts/[name].[hash:7].[ext]')
93
+ }
94
+ }
95
+ ]
96
+ },
97
+ eslint: {
98
+ formatter: require('eslint-friendly-formatter')
99
+ },
100
+ vue: {
101
+ loaders: utils.cssLoaders({ sourceMap: useCssSourceMap }),
102
+ postcss: [
103
+ require('autoprefixer')({
104
+ browsers: ['last 2 versions']
105
+ })
106
+ ]
107
+ },
108
+ plugins: [
109
+ // must match config.webpack.manifest_filename
110
+ new StatsPlugin('manifest.json', {
111
+ // We only need assetsByChunkName
112
+ chunkModules: false,
113
+ source: false,
114
+ chunks: false,
115
+ modules: false,
116
+ assets: true
117
+ }),
118
+ ]
119
+ }
@@ -0,0 +1,30 @@
1
+ var config = require('./config')
2
+ var webpack = require('webpack')
3
+ var merge = require('webpack-merge')
4
+ var utils = require('./utils')
5
+ var baseWebpackConfig = require('./webpack.base.conf')
6
+
7
+ var devServerPort = 3808
8
+
9
+ module.exports = merge(baseWebpackConfig, {
10
+ module: {
11
+ loaders: utils.styleLoaders({ sourceMap: config.dev.cssSourceMap })
12
+ },
13
+ output: {
14
+ publicPath: '//localhost:' + devServerPort + '/webpack/'
15
+ },
16
+ // eval-source-map is faster for development
17
+ devtool: '#eval-source-map',
18
+ devServer: {
19
+ port: devServerPort,
20
+ headers: { 'Access-Control-Allow-Origin': '*' }
21
+ },
22
+ plugins: [
23
+ new webpack.DefinePlugin({
24
+ 'process.env': config.dev.env
25
+ }),
26
+ // https://github.com/glenjamin/webpack-hot-middleware#installation--usage
27
+ new webpack.optimize.OccurenceOrderPlugin(),
28
+ new webpack.NoErrorsPlugin()
29
+ ]
30
+ })
@@ -0,0 +1,43 @@
1
+ var path = require('path')
2
+ var config = require('./config')
3
+ var utils = require('./utils')
4
+ var webpack = require('webpack')
5
+ var merge = require('webpack-merge')
6
+ var baseWebpackConfig = require('./webpack.base.conf')
7
+ var ExtractTextPlugin = require('extract-text-webpack-plugin')
8
+ var env = config.build.env
9
+
10
+ var webpackConfig = merge(baseWebpackConfig, {
11
+ module: {
12
+ loaders: utils.styleLoaders({ sourceMap: config.build.productionSourceMap, extract: true })
13
+ },
14
+ devtool: config.build.productionSourceMap ? '#source-map' : false,
15
+ output: {
16
+ path: config.build.assetsRoot,
17
+ filename: utils.assetsPath('[name].[chunkhash].js'),
18
+ chunkFilename: utils.assetsPath('[id].[chunkhash].js')
19
+ },
20
+ vue: {
21
+ loaders: utils.cssLoaders({
22
+ sourceMap: config.build.productionSourceMap,
23
+ extract: true
24
+ })
25
+ },
26
+ plugins: [
27
+ // http://vuejs.github.io/vue-loader/en/workflow/production.html
28
+ new webpack.DefinePlugin({
29
+ 'process.env': env
30
+ }),
31
+ new webpack.optimize.UglifyJsPlugin({
32
+ compress: {
33
+ warnings: false
34
+ }
35
+ }),
36
+ new webpack.optimize.DedupePlugin(),
37
+ new webpack.optimize.OccurrenceOrderPlugin(),
38
+ // extract css into its own file
39
+ new ExtractTextPlugin(utils.assetsPath('[name].[contenthash].css'))
40
+ ]
41
+ })
42
+
43
+ module.exports = webpackConfig
@@ -0,0 +1,40 @@
1
+ var path = require('path')
2
+ var utils = require('./utils')
3
+ var webpack = require('webpack')
4
+ var merge = require('webpack-merge')
5
+ var baseWebpackConfig = require('./webpack.base.conf')
6
+
7
+ baseWebpackConfig.plugins = []
8
+ var webpackConfig = merge(baseWebpackConfig, {
9
+ entry: './webpack/server.js',
10
+ module: {
11
+ loaders: utils.styleLoaders({ sourceMap: false, extract: false })
12
+ },
13
+ target: 'node',
14
+ output: {
15
+ path: path.resolve(__dirname, '../../renderer'),
16
+ libraryTarget: 'commonjs2',
17
+ filename: 'bundle.server.js'
18
+ },
19
+ vue: {
20
+ loaders: utils.cssLoaders({
21
+ sourceMap: false,
22
+ extract: false
23
+ })
24
+ },
25
+ plugins: [
26
+ // http://vuejs.github.io/vue-loader/en/workflow/production.html
27
+ new webpack.DefinePlugin({
28
+ 'process.env': '"production"'
29
+ }),
30
+ new webpack.optimize.UglifyJsPlugin({
31
+ compress: {
32
+ warnings: false
33
+ }
34
+ }),
35
+ new webpack.optimize.DedupePlugin(),
36
+ new webpack.optimize.OccurrenceOrderPlugin(),
37
+ ]
38
+ })
39
+
40
+ module.exports = webpackConfig
@@ -1,5 +1,5 @@
1
1
  import 'babel-polyfill'
2
2
  import setup from './setup'
3
3
 
4
- window.vm = setup('#vueport-template')
4
+ const vm = setup('#vueport-template')
5
5
  vm.$mount('#vueport-wrapper')
@@ -0,0 +1,9 @@
1
+ import 'babel-polyfill'
2
+ import setup from './setup'
3
+
4
+ export default function (context) {
5
+ const app = setup(context.body)
6
+ return new Promise((resolve) => {
7
+ resolve(app)
8
+ })
9
+ }
@@ -0,0 +1,18 @@
1
+ import Vue from 'vue'
2
+ /*
3
+ * Import your components here.
4
+ * Your components directory is aliased as 'components'
5
+ * e.g.
6
+ *
7
+ import MyComponent from 'components/my-component'
8
+ */
9
+
10
+ export default function (template) {
11
+ return new Vue({
12
+ template,
13
+ // Then include them here:
14
+ components: {
15
+ // MyComponent
16
+ }
17
+ })
18
+ }
data/lib/vueport.rb CHANGED
@@ -12,7 +12,8 @@ module Vueport
12
12
  @config ||= {
13
13
  server_host: 'localhost',
14
14
  server_port: 5000,
15
- server_config_file: 'config/webpack.server.js',
15
+ server_config_file: 'config/vueport/webpack.server.conf',
16
+ client_config_file: 'config/vueport/webpack.prod.conf',
16
17
  ssr_enabled: false
17
18
  }
18
19
  end
@@ -14,9 +14,5 @@ module Vueport
14
14
  include Vueport::Helper
15
15
  end
16
16
  end
17
-
18
- rake_tasks do
19
- load 'tasks/vueport.rake'
20
- end
21
17
  end
22
18
  end
@@ -1,3 +1,3 @@
1
1
  module Vueport
2
- VERSION = '0.1.0'.freeze
2
+ VERSION = '0.1.1'.freeze
3
3
  end
data/vueport.gemspec CHANGED
@@ -24,6 +24,7 @@ Gem::Specification.new do |spec|
24
24
  spec.add_development_dependency 'rspec', '~> 3.0'
25
25
  spec.add_development_dependency 'rubocop', '~> 0.45.0'
26
26
  spec.add_development_dependency 'rspec-html-matchers', '~> 0.8.1'
27
+ spec.add_development_dependency 'ammeter', '~> 1.1.4'
27
28
 
28
29
  spec.add_dependency 'rails', '>= 3.2.0'
29
30
  spec.add_dependency 'webpack-rails', '~> 0.9.9'
metadata CHANGED
@@ -1,14 +1,14 @@
1
1
  --- !ruby/object:Gem::Specification
2
2
  name: vueport
3
3
  version: !ruby/object:Gem::Version
4
- version: 0.1.0
4
+ version: 0.1.1
5
5
  platform: ruby
6
6
  authors:
7
7
  - Sam Garson
8
8
  autorequire:
9
9
  bindir: exe
10
10
  cert_chain: []
11
- date: 2016-12-08 00:00:00.000000000 Z
11
+ date: 2016-12-31 00:00:00.000000000 Z
12
12
  dependencies:
13
13
  - !ruby/object:Gem::Dependency
14
14
  name: bundler
@@ -80,6 +80,20 @@ dependencies:
80
80
  - - "~>"
81
81
  - !ruby/object:Gem::Version
82
82
  version: 0.8.1
83
+ - !ruby/object:Gem::Dependency
84
+ name: ammeter
85
+ requirement: !ruby/object:Gem::Requirement
86
+ requirements:
87
+ - - "~>"
88
+ - !ruby/object:Gem::Version
89
+ version: 1.1.4
90
+ type: :development
91
+ prerelease: false
92
+ version_requirements: !ruby/object:Gem::Requirement
93
+ requirements:
94
+ - - "~>"
95
+ - !ruby/object:Gem::Version
96
+ version: 1.1.4
83
97
  - !ruby/object:Gem::Dependency
84
98
  name: rails
85
99
  requirement: !ruby/object:Gem::Requirement
@@ -141,16 +155,26 @@ files:
141
155
  - Rakefile
142
156
  - bin/console
143
157
  - bin/setup
144
- - example/Procfile
145
- - example/Procfile.dev
146
- - example/application.js
147
- - example/babelrc
148
- - example/index.js
149
- - example/server.js
150
- - example/setup.js
151
- - example/webpack.server.js
152
158
  - lib/generators/vueport/install_generator.rb
153
- - lib/tasks/vueport.rake
159
+ - lib/generators/vueport/template/.babelrc
160
+ - lib/generators/vueport/template/.eslintignore
161
+ - lib/generators/vueport/template/.eslintrc.js
162
+ - lib/generators/vueport/template/Procfile
163
+ - lib/generators/vueport/template/Procfile.dev
164
+ - lib/generators/vueport/template/package.json
165
+ - lib/generators/vueport/template/renderer/.eslintrc.js
166
+ - lib/generators/vueport/template/renderer/index.js
167
+ - lib/generators/vueport/template/renderer/package.json
168
+ - lib/generators/vueport/template/vueport/build.js
169
+ - lib/generators/vueport/template/vueport/config.js
170
+ - lib/generators/vueport/template/vueport/utils.js
171
+ - lib/generators/vueport/template/vueport/webpack.base.conf.js
172
+ - lib/generators/vueport/template/vueport/webpack.dev.conf.js
173
+ - lib/generators/vueport/template/vueport/webpack.prod.conf.js
174
+ - lib/generators/vueport/template/vueport/webpack.server.conf.js
175
+ - lib/generators/vueport/template/webpack/application.js
176
+ - lib/generators/vueport/template/webpack/server.js
177
+ - lib/generators/vueport/template/webpack/setup.js
154
178
  - lib/vueport.rb
155
179
  - lib/vueport/helper.rb
156
180
  - lib/vueport/node_client.rb
@@ -178,7 +202,7 @@ required_rubygems_version: !ruby/object:Gem::Requirement
178
202
  version: '0'
179
203
  requirements: []
180
204
  rubyforge_project:
181
- rubygems_version: 2.5.1
205
+ rubygems_version: 2.6.8
182
206
  signing_key:
183
207
  specification_version: 4
184
208
  summary: Single file components for Rails with Vue JS and Webpack
data/example/Procfile.dev DELETED
@@ -1,2 +0,0 @@
1
- rails: bundle exec rails server
2
- webpack: npm run dev-server
data/example/index.js DELETED
@@ -1,35 +0,0 @@
1
- const app = require('express')()
2
- const fs = require('fs');
3
- const path = require('path');
4
- const bodyParser = require('body-parser')
5
- const vueServerRenderer = require('vue-server-renderer');
6
- const morgan = require('morgan')
7
-
8
- const filePath = path.join(__dirname, './public/webpack/bundle.server.js')
9
- const code = fs.readFileSync(filePath, 'utf8');
10
- const bundleRenderer = vueServerRenderer.createBundleRenderer(code);
11
-
12
- const PORT = process.env['PORT'] || 5000
13
-
14
- app.use(bodyParser.text())
15
- app.use(morgan('tiny'))
16
-
17
- const render = html => {
18
- return p = new Promise((resolve, reject) => {
19
- bundleRenderer.renderToString({body: html}, (err, html) => {
20
- if (err) return reject(err)
21
- else return resolve(html)
22
- })
23
- })
24
- }
25
-
26
- app.post('/render', (req, res) => {
27
- render(req.body)
28
- .catch(err => {
29
- console.error(err)
30
- res.status(500).send(JSON.stringify(err))
31
- })
32
- .then(html => res.send(html))
33
- })
34
-
35
- app.listen(PORT, () => console.log('listening on', PORT))
data/example/server.js DELETED
@@ -1,10 +0,0 @@
1
- import 'babel-polyfill'
2
- import Vue from 'vue'
3
- import setup from './setup';
4
-
5
- export default function(context) {
6
- const app = setup(context.body)
7
- return new Promise((resolve, reject) => {
8
- resolve(app);
9
- });
10
- };
data/example/setup.js DELETED
@@ -1,14 +0,0 @@
1
- import Vue from 'vue'
2
- // Import your components here, then include it in your Vue application below.
3
- // (We've added /app to our webpack resolves for convenience)
4
-
5
- // import MyComponent from 'components/my-component'
6
-
7
- export default function (template) {
8
- return new Vue({
9
- template: template,
10
- components: {
11
- //MyComponent
12
- }
13
- })
14
- }
@@ -1,59 +0,0 @@
1
- // Example webpack configuration with asset fingerprinting in production.
2
- 'use strict';
3
-
4
- var path = require('path');
5
- var webpack = require('webpack');
6
-
7
- var config = {
8
- target: 'node', // !different
9
- entry: './webpack/server.js',
10
- output: {
11
- libraryTarget: 'commonjs2', // !different
12
- path: path.join(__dirname, '..', 'public', 'webpack'),
13
- publicPath: '/webpack/',
14
- filename: 'bundle.server.js',
15
- },
16
- resolve: {
17
- root: path.join(__dirname, '..', 'webpack'),
18
- extensions: ['', '.js', '.vue'],
19
- fallback: [path.join(__dirname, '../node_modules'), path.join(__dirname, '../app/')]
20
- },
21
-
22
- plugins: [
23
- new webpack.NoErrorsPlugin(),
24
- new webpack.optimize.UglifyJsPlugin({
25
- compressor: { warnings: false },
26
- sourceMap: false
27
- }),
28
- new webpack.DefinePlugin({
29
- 'process.env': { NODE_ENV: JSON.stringify('production') }
30
- }),
31
- new webpack.optimize.DedupePlugin(),
32
- new webpack.optimize.OccurenceOrderPlugin()
33
- ],
34
-
35
- module: {
36
- loaders: [
37
- {
38
- test: /\.vue$/,
39
- loader: 'vue'
40
- },
41
- {
42
- test: /\.json$/,
43
- loader: 'json'
44
- },
45
- {
46
- loaders: ['babel'],
47
- test: /\.js$/,
48
- exclude: /node_modules/
49
- },
50
- {
51
- test: /\.(sc|sa|c)ss$/,
52
- loaders: ['style', 'css', 'sass']
53
- }
54
- ]
55
- }
56
- };
57
-
58
-
59
- module.exports = config;
@@ -1,24 +0,0 @@
1
- namespace :vueport do
2
- desc 'Compile client and server bundles'
3
- task compile: :environment do
4
- ENV['NODE_ENV'] = 'production'
5
- webpack_bin = ::Rails.root.join(::Rails.configuration.webpack.binary)
6
- config_file = ::Rails.root.join(::Rails.configuration.webpack.config_file)
7
- server_config_file = ::Rails.root.join(Vueport.config[:server_config_file])
8
-
9
- unless File.exist?(webpack_bin)
10
- raise "Can't find our webpack executable at #{webpack_bin} - have you run `npm install`?"
11
- end
12
-
13
- unless File.exist?(config_file)
14
- raise "Can't find our webpack config file at #{config_file}"
15
- end
16
-
17
- unless File.exist?(server_config_file)
18
- raise "Can't find our webpack server config file at #{config_file}"
19
- end
20
-
21
- sh "#{webpack_bin} --config #{config_file} --bail"
22
- sh "#{webpack_bin} --config #{server_config_file} --bail"
23
- end
24
- end