diff --git a/lib/generators/vueport/install_generator.rb b/lib/generators/vueport/install_generator.rb index 4df063a..a6c09a3 100644 --- a/lib/generators/vueport/install_generator.rb +++ b/lib/generators/vueport/install_generator.rb @@ -2,68 +2,16 @@ module Vueport class InstallGenerator < ::Rails::Generators::Base source_root File.expand_path('../template', __FILE__) - desc 'Install extras for using Vue with WebpackRails' + desc 'Install a local node rendering service for Vueport' - def add_webpack_rails - gem 'webpack-rails' - gem 'foreman' - end - - def add_to_gitignore - append_to_file '.gitignore' do - <<-EOF.strip_heredoc - # Added by vueport - /node_modules - /public/webpack - /npm-debug.log - - /renderer/node_modules - /renderer/npm-debug.log - /renderer/bundle.server.js - EOF - end - end - - def copy_package_json - copy_file 'package.json' - end - - def copy_eslint - copy_file '.eslintrc.js' - copy_file '.eslintignore' - end - - def copy_config_files - directory 'vueport', 'config/vueport' - end - - def copy_renderer_files - directory 'renderer' - end - - def update_procfile - copy_file 'Procfile.dev' - copy_file 'Procfile' - end - - def create_setup_files - directory 'webpack' - copy_file '.babelrc' - empty_directory 'app/components' - end - - def run_npm_install - if yarn? && yes?("Would you like me to run 'yarn' for you? [y/N]") - run 'yarn' - run 'cd renderer && yarn' - elsif !yarn? && yes?("Would you like me to run 'npm install' for you? [y/N]") - run 'npm i' - run 'cd renderer && npm i' + def add_gems + gem_group :development do + gem 'foreman' end end - def run_bundle_install - run 'bundle install' if yes?("Would you like me to run 'bundle install' for you? [y/N]") + def install_renderer + plugin 'vue-renderer', :git => 'git://github.com/samtgarson/vue-renderer.git' end # rubocop:disable Metrics/MethodLength @@ -72,12 +20,11 @@ def whats_next say 'All done!', :green say '' - say "I've added a few things here and there to set you up using Vue in your Rails app." - say "Now you're already to create your first Vue component in app/components." + say "I've installed foreman and a vue-rendering service in a local git submodule" say '' - say 'To run the webpack-dev-server and rails server:' - say 'foreman start -f Procfile.dev', :yellow + say 'You\'ll need to run yarn from ./vue-renderer to install its dependencies:' + say 'cd vueport-renderer && yarn', :yellow say '' say 'For more info, see the README.md for this gem at:' diff --git a/lib/generators/vueport/template/.babelrc b/lib/generators/vueport/template/.babelrc deleted file mode 100644 index 725151c..0000000 --- a/lib/generators/vueport/template/.babelrc +++ /dev/null @@ -1,3 +0,0 @@ -{ - presets: ['es2015', 'stage-0'] -} diff --git a/lib/generators/vueport/template/.eslintignore b/lib/generators/vueport/template/.eslintignore deleted file mode 100644 index 35d0f10..0000000 --- a/lib/generators/vueport/template/.eslintignore +++ /dev/null @@ -1,4 +0,0 @@ -public/**/*.js -config/**/*.js -node_modules/**/*.js -renderer/node_modules/**/*.js diff --git a/lib/generators/vueport/template/.eslintrc.js b/lib/generators/vueport/template/.eslintrc.js deleted file mode 100644 index d098508..0000000 --- a/lib/generators/vueport/template/.eslintrc.js +++ /dev/null @@ -1,33 +0,0 @@ -module.exports = { - root: true, - parser: 'babel-eslint', - parserOptions: { - sourceType: 'module' - }, - extends: 'airbnb-base', - // required to lint *.vue files - plugins: [ - 'html' - ], - // check if imports actually resolve - 'settings': { - 'import/resolver': { - 'webpack': { - 'config': 'config/vueport/webpack.base.conf.js' - } - } - }, - // add your custom rules here - 'rules': { - // don't require .vue extension when importing - 'import/extensions': ['error', 'always', { - 'js': 'never', - 'vue': 'never' - }], - 'comma-dangle': ['error', 'never'], - 'space-before-function-paren': ['error', 'always'], - 'semi': ['error', 'never'], - // allow debugger during development - 'no-debugger': process.env.NODE_ENV === 'production' ? 2 : 0 - } -} diff --git a/lib/generators/vueport/template/Procfile b/lib/generators/vueport/template/Procfile deleted file mode 100644 index d0a89d6..0000000 --- a/lib/generators/vueport/template/Procfile +++ /dev/null @@ -1,2 +0,0 @@ -rails: bundle exec rails server -node: cd renderer && npm run start diff --git a/lib/generators/vueport/template/Procfile.dev b/lib/generators/vueport/template/Procfile.dev deleted file mode 100644 index 59ede1a..0000000 --- a/lib/generators/vueport/template/Procfile.dev +++ /dev/null @@ -1,2 +0,0 @@ -rails: bundle exec rails server -webpack: npm run dev diff --git a/lib/generators/vueport/template/package.json b/lib/generators/vueport/template/package.json deleted file mode 100644 index 3483c81..0000000 --- a/lib/generators/vueport/template/package.json +++ /dev/null @@ -1,43 +0,0 @@ -{ - "name": "vueport-example", - "version": "0.0.1", - "license": "MIT", - "description": "Example Rails application using Vueport and Vue single file components", - "main": "index.js", - "repository": { - "url": "git@github.com:samtgarson/vueport-example.git", - "type": "git" - }, - "author": "Sam Garson ", - "scripts": { - "dev": "./node_modules/.bin/webpack-dev-server --hot --inline --config config/vueport/webpack.dev.conf --host 0.0.0.0", - "compile": "node config/vueport/build" - }, - "dependencies": { - "babel-core": "^6.17.0", - "babel-eslint": "^7.1.1", - "babel-loader": "^6.2.5", - "babel-polyfill": "^6.16.0", - "babel-preset-es2015": "^6.16.0", - "babel-preset-stage-0": "^6.16.0", - "css-loader": "^0.25.0", - "eslint": "^3.12.0", - "eslint-config-airbnb-base": "^10.0.1", - "eslint-friendly-formatter": "^2.0.6", - "eslint-import-resolver-webpack": "^0.7.1", - "eslint-loader": "^1.6.1", - "eslint-plugin-html": "^1.7.0", - "eslint-plugin-import": "^2.2.0", - "extract-text-webpack-plugin": "^1.0.1", - "ora": "^0.4.0", - "stats-webpack-plugin": "^0.2.1", - "style-loader": "^0.13.1", - "vue": "^2.1.4", - "vue-loader": "^10.0.1", - "vue-style-loader": "^1.0.0", - "vue-template-compiler": "^2.1.4", - "webpack": "^1.9.11", - "webpack-dev-server": "^1.9.0", - "webpack-merge": "^1.1.1" - } -} diff --git a/lib/generators/vueport/template/renderer/.eslintrc.js b/lib/generators/vueport/template/renderer/.eslintrc.js deleted file mode 100644 index a688b50..0000000 --- a/lib/generators/vueport/template/renderer/.eslintrc.js +++ /dev/null @@ -1,28 +0,0 @@ -module.exports = { - root: true, - parser: 'babel-eslint', - parserOptions: { - sourceType: 'module' - }, - extends: 'airbnb-base', - // required to lint *.vue files - plugins: [ - 'html' - ], - // check if imports actually resolve - 'settings': { - 'import/resolver': { - 'webpack': { - 'config': '../config/vueport/webpack.base.conf.js' - } - } - }, - // add your custom rules here - 'rules': { - // allow debugger during development - 'comma-dangle': ['error', 'never'], - 'space-before-function-paren': ['error', 'always'], - 'semi': ['error', 'never'], - 'no-debugger': process.env.NODE_ENV === 'production' ? 2 : 0 - } -} diff --git a/lib/generators/vueport/template/renderer/index.js b/lib/generators/vueport/template/renderer/index.js deleted file mode 100644 index b4953c1..0000000 --- a/lib/generators/vueport/template/renderer/index.js +++ /dev/null @@ -1,34 +0,0 @@ -const app = require('express')() -const fs = require('fs') -const path = require('path') -const bodyParser = require('body-parser') -const vueServerRenderer = require('vue-server-renderer') -const morgan = require('morgan') - -const filePath = path.join(__dirname, './bundle.server.js') -const code = fs.readFileSync(filePath, 'utf8') -const bundleRenderer = vueServerRenderer.createBundleRenderer(code) - -const PORT = process.env.PORT || 5000 - -app.use(bodyParser.text()) -app.use(morgan('tiny')) - -const render = html => new Promise((resolve, reject) => { - bundleRenderer.renderToString({ body: html }, (err, res) => { - if (err) return reject(err) - return resolve(res) - }) -}) - -app.post('*', (req, res) => { - if (typeof req.body !== 'string' || req.body.length === 0) return res.status(400).send('') - return render(req.body) - .catch((err) => { - console.error(err) - res.status(500).send(JSON.stringify(err)) - }) - .then(html => res.send(html)) -}) - -app.listen(PORT, () => console.log('listening on', PORT)) diff --git a/lib/generators/vueport/template/renderer/package.json b/lib/generators/vueport/template/renderer/package.json deleted file mode 100644 index 612bbd7..0000000 --- a/lib/generators/vueport/template/renderer/package.json +++ /dev/null @@ -1,17 +0,0 @@ -{ - "name": "vueport-renderer", - "repository": "samtgarson/vueport", - "description": "Vueport Server Side Renderer", - "version": "0.0.1", - "license": "MIT", - "scripts": { - "start": "node ." - }, - "dependencies": { - "body-parser": "^1.15.2", - "express": "^4.14.0", - "morgan": "^1.7.0", - "vue-server-renderer": "2.1.4", - "vue-template-compiler": "2.1.4" - } -} diff --git a/lib/generators/vueport/template/server.js b/lib/generators/vueport/template/server.js new file mode 100644 index 0000000..559fa88 --- /dev/null +++ b/lib/generators/vueport/template/server.js @@ -0,0 +1,21 @@ +// Note: You must restart bin/webpack-dev-server for changes to take effect + +/* eslint global-require: 0 */ + +const webpack = require('webpack') +const merge = require('webpack-merge') +const CompressionPlugin = require('compression-webpack-plugin') +const sharedConfig = require('./shared.js') + +module.exports = merge(sharedConfig, { + output: { filename: 'bundle.server.js' }, + + plugins: [ + new webpack.optimize.UglifyJsPlugin(), + new CompressionPlugin({ + asset: '[path].gz[query]', + algorithm: 'gzip', + test: /\.(js|css|svg|eot|ttf|woff|woff2)$/ + }) + ] +}) diff --git a/lib/generators/vueport/template/vueport/build.js b/lib/generators/vueport/template/vueport/build.js deleted file mode 100644 index 62718fe..0000000 --- a/lib/generators/vueport/template/vueport/build.js +++ /dev/null @@ -1,46 +0,0 @@ -// https://github.com/shelljs/shelljs -require('shelljs/global') -env.NODE_ENV = 'production' - -var path = require('path') -var config = require('./config') -var ora = require('ora') -var webpack = require('webpack') -var clientConfig = require('./webpack.prod.conf') -var serverConfig = require('./webpack.server.conf') - -var assetsPath = path.join(config.build.assetsRoot) -rm('-rf', assetsPath) -mkdir('-p', assetsPath) - -var statsConfig = { - colors: true, - modules: false, - children: false, - chunks: false, - chunkModules: false -} - -const compile = (config, bundle) => { - const spinner = ora(`Building ${bundle} for production...`) - spinner.start() - - return new Promise(function (resolve, reject) { - webpack(config, function (err, stats) { - if (err) { - spinner.text = `Error building ${bundle}.` - spinner.fail() - return reject(err) - } - - spinner.text = `Built ${bundle} successfully` - spinner.succeed() - process.stdout.write(stats.toString(statsConfig) + '\n') - resolve() - }) - }) -} - -compile(clientConfig, 'client bundle').then(() => { - compile(serverConfig, 'server bundle') -}) diff --git a/lib/generators/vueport/template/vueport/config.js b/lib/generators/vueport/template/vueport/config.js deleted file mode 100644 index b123ca0..0000000 --- a/lib/generators/vueport/template/vueport/config.js +++ /dev/null @@ -1,25 +0,0 @@ -// see http://vuejs-templates.github.io/webpack for documentation. -var path = require('path') - -module.exports = { - build: { - env: { NODE_ENV: '"production"' }, - assetsRoot: path.resolve(__dirname, '../../public/webpack'), - assetsSubDirectory: '/', - assetsPublicPath: '/', - productionSourceMap: true - }, - dev: { - env: { NODE_ENV: '"development"' }, - port: 8080, - assetsSubDirectory: '/', - assetsPublicPath: '/', - proxyTable: {}, - // CSS Sourcemaps off by default because relative paths are "buggy" - // with this option, according to the CSS-Loader README - // (https://github.com/webpack/css-loader#sourcemaps) - // In our experience, they generally work as expected, - // just be aware of this issue when enabling this option. - cssSourceMap: false - } -} diff --git a/lib/generators/vueport/template/vueport/utils.js b/lib/generators/vueport/template/vueport/utils.js deleted file mode 100644 index 67e7cee..0000000 --- a/lib/generators/vueport/template/vueport/utils.js +++ /dev/null @@ -1,61 +0,0 @@ -var path = require('path') -var config = require('./config') -var ExtractTextPlugin = require('extract-text-webpack-plugin') - -exports.assetsPath = function (_path) { - var assetsSubDirectory = process.env.NODE_ENV === 'production' - ? config.build.assetsSubDirectory - : config.dev.assetsSubDirectory - return path.posix.join(assetsSubDirectory, _path) -} - -exports.cssLoaders = function (options) { - options = options || {} - // generate loader string to be used with extract text plugin - function generateLoaders (loaders) { - var sourceLoader = loaders.map(function (loader) { - var extraParamChar - if (/\?/.test(loader)) { - loader = loader.replace(/\?/, '-loader?') - extraParamChar = '&' - } else { - loader = loader + '-loader' - extraParamChar = '?' - } - return loader + (options.sourceMap ? extraParamChar + 'sourceMap' : '') - }).join('!') - - // Extract CSS when that option is specified - // (which is the case during production build) - if (options.extract) { - return ExtractTextPlugin.extract('vue-style-loader', sourceLoader) - } else { - return ['vue-style-loader', sourceLoader].join('!') - } - } - - // http://vuejs.github.io/vue-loader/en/configurations/extract-css.html - return { - css: generateLoaders(['css']), - postcss: generateLoaders(['css']), - less: generateLoaders(['css', 'less']), - sass: generateLoaders(['css', 'sass?indentedSyntax']), - scss: generateLoaders(['css', 'sass']), - stylus: generateLoaders(['css', 'stylus']), - styl: generateLoaders(['css', 'stylus']) - } -} - -// Generate loaders for standalone style files (outside of .vue) -exports.styleLoaders = function (options) { - var output = [] - var loaders = exports.cssLoaders(options) - for (var extension in loaders) { - var loader = loaders[extension] - output.push({ - test: new RegExp('\\.' + extension + '$'), - loader: loader - }) - } - return output -} diff --git a/lib/generators/vueport/template/vueport/webpack.base.conf.js b/lib/generators/vueport/template/vueport/webpack.base.conf.js deleted file mode 100644 index c62079f..0000000 --- a/lib/generators/vueport/template/vueport/webpack.base.conf.js +++ /dev/null @@ -1,119 +0,0 @@ -var path = require('path') -var config = require('./config') -var utils = require('./utils') -var projectRoot = path.resolve(__dirname, '../../') -var StatsPlugin = require('stats-webpack-plugin') - -var env = process.env.NODE_ENV -// check env & config/index.js to decide weither to enable CSS Sourcemaps for the -// various preprocessor loaders added to vue-loader at the end of this file -var cssSourceMapDev = (env === 'development' && config.dev.cssSourceMap) -var cssSourceMapProd = (env === 'production' && config.build.productionSourceMap) -var useCssSourceMap = cssSourceMapDev || cssSourceMapProd - -module.exports = { - entry: { - application: './webpack/application.js' - }, - output: { - path: config.build.assetsRoot, - publicPath: '/webpack/', - filename: '[name].js' - }, - resolve: { - extensions: ['', '.js', '.vue'], - fallback: [ - path.join(projectRoot, 'node_modules'), - ], - alias: { - 'vue$': 'vue/dist/vue.common.js', - 'components': path.resolve(projectRoot, 'app/components'), - 'assets': path.resolve(projectRoot, 'app/assets') - } - }, - resolveLoader: { - fallback: [path.join(projectRoot, 'node_modules')] - }, - module: { - preLoaders: [ - { - test: /\.vue$/, - loader: 'eslint', - include: projectRoot, - exclude: /node_modules/ - }, - { - test: /\.js$/, - loader: 'eslint', - include: projectRoot, - exclude: /node_modules/ - } - ], - loaders: [ - { - test: /\.vue$/, - loader: 'vue' - }, - { - test: /\.js$/, - loader: 'babel', - include: projectRoot, - exclude: /node_modules/ - }, - { - test: /\.pug$/, - loader: 'pug', - include: projectRoot, - exclude: /node_modules/ - }, - { - test: /\.sass$/, - loader: 'sass', - include: projectRoot, - exclude: /node_modules/ - }, - { - test: /\.json$/, - loader: 'json' - }, - { - test: /\.(png|jpe?g|gif|svg)(\?.*)?$/, - loader: 'url', - query: { - limit: 10000, - name: utils.assetsPath('img/[name].[hash:7].[ext]') - } - }, - { - test: /\.(woff2?|eot|ttf|otf)(\?.*)?$/, - loader: 'url', - query: { - limit: 10000, - name: utils.assetsPath('fonts/[name].[hash:7].[ext]') - } - } - ] - }, - eslint: { - formatter: require('eslint-friendly-formatter') - }, - vue: { - loaders: utils.cssLoaders({ sourceMap: useCssSourceMap }), - postcss: [ - require('autoprefixer')({ - browsers: ['last 2 versions'] - }) - ] - }, - plugins: [ - // must match config.webpack.manifest_filename - new StatsPlugin('manifest.json', { - // We only need assetsByChunkName - chunkModules: false, - source: false, - chunks: false, - modules: false, - assets: true - }), - ] -} diff --git a/lib/generators/vueport/template/vueport/webpack.dev.conf.js b/lib/generators/vueport/template/vueport/webpack.dev.conf.js deleted file mode 100644 index 7a55a73..0000000 --- a/lib/generators/vueport/template/vueport/webpack.dev.conf.js +++ /dev/null @@ -1,30 +0,0 @@ -var config = require('./config') -var webpack = require('webpack') -var merge = require('webpack-merge') -var utils = require('./utils') -var baseWebpackConfig = require('./webpack.base.conf') - -var devServerPort = 3808 - -module.exports = merge(baseWebpackConfig, { - module: { - loaders: utils.styleLoaders({ sourceMap: config.dev.cssSourceMap }) - }, - output: { - publicPath: '//localhost:' + devServerPort + '/webpack/' - }, - // eval-source-map is faster for development - devtool: '#eval-source-map', - devServer: { - port: devServerPort, - headers: { 'Access-Control-Allow-Origin': '*' } - }, - plugins: [ - new webpack.DefinePlugin({ - 'process.env': config.dev.env - }), - // https://github.com/glenjamin/webpack-hot-middleware#installation--usage - new webpack.optimize.OccurenceOrderPlugin(), - new webpack.NoErrorsPlugin() - ] -}) diff --git a/lib/generators/vueport/template/vueport/webpack.prod.conf.js b/lib/generators/vueport/template/vueport/webpack.prod.conf.js deleted file mode 100644 index eaa82d7..0000000 --- a/lib/generators/vueport/template/vueport/webpack.prod.conf.js +++ /dev/null @@ -1,43 +0,0 @@ -var path = require('path') -var config = require('./config') -var utils = require('./utils') -var webpack = require('webpack') -var merge = require('webpack-merge') -var baseWebpackConfig = require('./webpack.base.conf') -var ExtractTextPlugin = require('extract-text-webpack-plugin') -var env = config.build.env - -var webpackConfig = merge(baseWebpackConfig, { - module: { - loaders: utils.styleLoaders({ sourceMap: config.build.productionSourceMap, extract: true }) - }, - devtool: config.build.productionSourceMap ? '#source-map' : false, - output: { - path: config.build.assetsRoot, - filename: utils.assetsPath('[name].[chunkhash].js'), - chunkFilename: utils.assetsPath('[id].[chunkhash].js') - }, - vue: { - loaders: utils.cssLoaders({ - sourceMap: config.build.productionSourceMap, - extract: true - }) - }, - plugins: [ - // http://vuejs.github.io/vue-loader/en/workflow/production.html - new webpack.DefinePlugin({ - 'process.env': env - }), - new webpack.optimize.UglifyJsPlugin({ - compress: { - warnings: false - } - }), - new webpack.optimize.DedupePlugin(), - new webpack.optimize.OccurrenceOrderPlugin(), - // extract css into its own file - new ExtractTextPlugin(utils.assetsPath('[name].[contenthash].css')) - ] -}) - -module.exports = webpackConfig diff --git a/lib/generators/vueport/template/vueport/webpack.server.conf.js b/lib/generators/vueport/template/vueport/webpack.server.conf.js deleted file mode 100644 index c53a539..0000000 --- a/lib/generators/vueport/template/vueport/webpack.server.conf.js +++ /dev/null @@ -1,41 +0,0 @@ -var path = require('path') -var utils = require('./utils') -var webpack = require('webpack') -var merge = require('webpack-merge') -var baseWebpackConfig = require('./webpack.base.conf') - -baseWebpackConfig.plugins = [] -delete baseWebpackConfig.resolve.alias['vue$'] -var webpackConfig = merge(baseWebpackConfig, { - entry: './webpack/server.js', - module: { - loaders: utils.styleLoaders({ sourceMap: false, extract: false }) - }, - target: 'node', - output: { - path: path.resolve(__dirname, '../../renderer'), - libraryTarget: 'commonjs2', - filename: 'bundle.server.js' - }, - vue: { - loaders: utils.cssLoaders({ - sourceMap: false, - extract: false - }) - }, - plugins: [ - // http://vuejs.github.io/vue-loader/en/workflow/production.html - new webpack.DefinePlugin({ - 'process.env': '"production"' - }), - new webpack.optimize.UglifyJsPlugin({ - compress: { - warnings: false - } - }), - new webpack.optimize.DedupePlugin(), - new webpack.optimize.OccurrenceOrderPlugin(), - ] -}) - -module.exports = webpackConfig diff --git a/lib/generators/vueport/template/webpack/application.js b/lib/generators/vueport/template/webpack/application.js deleted file mode 100644 index d3c32e0..0000000 --- a/lib/generators/vueport/template/webpack/application.js +++ /dev/null @@ -1,5 +0,0 @@ -import 'babel-polyfill' -import setup from './setup' - -const vm = setup('#vueport-template') -vm.$mount('#vueport-wrapper') diff --git a/lib/generators/vueport/template/webpack/server.js b/lib/generators/vueport/template/webpack/server.js deleted file mode 100644 index af9680f..0000000 --- a/lib/generators/vueport/template/webpack/server.js +++ /dev/null @@ -1,9 +0,0 @@ -import 'babel-polyfill' -import setup from './setup' - -export default function (context) { - const app = setup(context.body) - return new Promise((resolve) => { - resolve(app) - }) -} diff --git a/lib/generators/vueport/template/webpack/setup.js b/lib/generators/vueport/template/webpack/setup.js deleted file mode 100644 index 66ad3db..0000000 --- a/lib/generators/vueport/template/webpack/setup.js +++ /dev/null @@ -1,22 +0,0 @@ -import Vue from 'vue' -/* -* Import your components here. -* Your components directory is aliased as 'components' -* e.g. -* -import MyComponent from 'components/my-component' -*/ - -export default function (template) { - return new Vue({ - template, - computed: { - // This is a utitly to add classes to your container - wrapperClass () { return '' } - }, - // Then include them here: - components: { - // MyComponent - } - }) -}