From 8a427ffb3e849684b105fd310da949407510ed82 Mon Sep 17 00:00:00 2001 From: nekosaur Date: Tue, 8 May 2018 20:47:40 +0200 Subject: [PATCH 1/2] fix/enh: restructured code, fixed bugs - no longer deleting any existing files/folders, instead only rendering relevant files (closes #5) - moved vuetify declaration into separate plugin file (closes #6) - added option to add babel/polyfill, defaults to true (closes #3) - moved vuetify import (closes #4) --- generator/helpers.js | 51 ++++++ generator/index.js | 166 ++++++------------ .../templates/default/src/plugins/vuetify.js | 46 +++++ prompts.js | 42 +++-- 4 files changed, 180 insertions(+), 125 deletions(-) create mode 100644 generator/helpers.js create mode 100644 generator/templates/default/src/plugins/vuetify.js diff --git a/generator/helpers.js b/generator/helpers.js new file mode 100644 index 00000000..d688975c --- /dev/null +++ b/generator/helpers.js @@ -0,0 +1,51 @@ +const fs = require('fs') + +module.exports = function (api) { + return { + updateBabelConfig (callback) { + let config, configPath + + const rcPath = api.resolve('./.babelrc') + const pkgPath = api.resolve('./package.json') + if (fs.existsSync(rcPath)) { + configPath = rcPath + config = JSON.parse(fs.readFileSync(rcPath, { encoding: 'utf8' })) + config = callback(config) + } else if (fs.existsSync(pkgPath)) { + configPath = pkgPath + config = JSON.parse(fs.readFileSync(pkgPath, { encoding: 'utf8' })) + + if (config.babel) { + config.babel = callback(config.babel) + } else { + // TODO: error handling here? + } + } + + if (configPath) { + fs.writeFileSync( + configPath, + JSON.stringify(config, null, 2), + { encoding: 'utf8' } + ) + } else { + // TODO: handle if babel config doesn't exist + } + }, + + updateMain (callback) { + const tsPath = api.resolve('./src/main.ts') + const jsPath = api.resolve('./src/main.js') + + const mainPath = fs.existsSync(tsPath) ? tsPath : jsPath + let content = fs.readFileSync(mainPath, { encoding: 'utf8' }) + + let lines = content.split(/\r?\n/g) + + lines = callback(lines) + + content = lines.join('\n') + fs.writeFileSync(mainPath, content, { encoding: 'utf8' }) + } + } +} diff --git a/generator/index.js b/generator/index.js index 35c8bb4e..67120052 100644 --- a/generator/index.js +++ b/generator/index.js @@ -1,4 +1,6 @@ module.exports = (api, opts, rootOpts) => { + const helpers = require('./helpers')(api) + api.extendPackage({ dependencies: { vuetify: "^1.0.16" @@ -15,99 +17,78 @@ module.exports = (api, opts, rootOpts) => { }) } - // Handle if router exists - { - const fs = require('fs') - const routerPath = api.resolve('./src/router.js') - opts.router = fs.existsSync(routerPath) + // Render vuetify plugin file + api.render({ + './src/plugins/vuetify.js': './templates/default/src/plugins/vuetify.js' + }, opts) + + // Render files if we're replacing + const fs = require('fs') + const routerPath = api.resolve('./src/router.js') + opts.router = fs.existsSync(routerPath) - if (opts.replaceComponents) { - api.render('./templates/default', { ...opts }) + if (opts.replaceComponents) { + const files = { + './src/App.vue': './templates/default/src/App.vue', + './src/assets/logo.png': './templates/default/src/assets/logo.png' } + + if (opts.router) { + files['./src/views/Home.vue'] = './templates/default/src/views/Home.vue' + } else { + files['./src/components/HelloWorld.vue'] = './templates/default/src/components/HelloWorld.vue' + } + + api.render(files, opts) } // adapted from https://github.com/Akryum/vue-cli-plugin-apollo/blob/master/generator/index.js#L68-L91 api.onCreateComplete(() => { - const fs = require('fs') + // Modify main.js + helpers.updateMain(src => { + const vueImportIndex = src.findIndex(line => line.match(/^import Vue/)) - // Setup Vuetify import for main.js - let vuetifyLines = '' - if (opts.useAlaCarte) { - vuetifyLines += "\nimport {" - vuetifyLines += "\n Vuetify," - vuetifyLines += "\n VApp," - vuetifyLines += "\n VNavigationDrawer," - vuetifyLines += "\n VFooter," - vuetifyLines += "\n VList," - vuetifyLines += "\n VBtn," - vuetifyLines += "\n VIcon," - vuetifyLines += "\n VGrid," - vuetifyLines += "\n VToolbar," - vuetifyLines += "\n transitions" - vuetifyLines += "\n} from 'vuetify'" - vuetifyLines += "\nimport '../node_modules/vuetify/src/stylus/app.styl'\n" - } else { - vuetifyLines += "\nimport Vuetify from 'vuetify'" - vuetifyLines += "\nimport 'vuetify/dist/vuetify.min.css'\n" - } + src.splice(vueImportIndex + 1, 0, 'import \'./plugins/vuetify\'') - if (opts.useAlaCarte || opts.useTheme) { - vuetifyLines += "\nVue.use(Vuetify, {" - - if (opts.useAlaCarte) { - vuetifyLines += "\n components: {" - vuetifyLines += "\n VApp," - vuetifyLines += "\n VNavigationDrawer," - vuetifyLines += "\n VFooter," - vuetifyLines += "\n VList," - vuetifyLines += "\n VBtn," - vuetifyLines += "\n VIcon," - vuetifyLines += "\n VGrid," - vuetifyLines += "\n VToolbar," - vuetifyLines += "\n transitions" - vuetifyLines += "\n }," - } + return src + }) - if (opts.useTheme) { - vuetifyLines += "\n theme: {" - vuetifyLines += "\n primary: '#ee44aa'," - vuetifyLines += "\n secondary: '#424242'," - vuetifyLines += "\n accent: '#82B1FF'," - vuetifyLines += "\n error: '#FF5252'," - vuetifyLines += "\n info: '#2196F3'," - vuetifyLines += "\n success: '#4CAF50'," - vuetifyLines += "\n warning: '#FFC107'" - vuetifyLines += "\n }," - } + // Add polyfill + if (opts.usePolyfill) { + helpers.updateBabelConfig(cfg => { + if (!cfg.presets) return - vuetifyLines += "\n})" - } else { - vuetifyLines += "\nVue.use(Vuetify)" - } + const vuePresetIndex = cfg.presets.findIndex(p => Array.isArray(p) ? p[0] === '@vue/app' : p === '@vue/app') + const isArray = Array.isArray(cfg.presets[vuePresetIndex]) - // Modify main.js - { - const tsPath = api.resolve('./src/main.ts') - const jsPath = api.resolve('./src/main.js') + if (vuePresetIndex < 0) return - const mainPath = fs.existsSync(tsPath) ? tsPath : jsPath - let content = fs.readFileSync(mainPath, { encoding: 'utf8' }) + if (isArray) { + cfg.presets[vuePresetIndex][1]['useBuiltIns'] = 'entry' + } else { + cfg.presets[vuePresetIndex] = [ + '@vue/app', + { + useBuiltIns: 'entry' + } + ] + } - const lines = content.split(/\r?\n/g).reverse() + return cfg + }) - // Inject import - const lastImportIndex = lines.findIndex(line => line.match(/^import/)) - lines[lastImportIndex] += vuetifyLines - // Modify app - content = lines.reverse().join('\n') - fs.writeFileSync(mainPath, content, { encoding: 'utf8' }) + helpers.updateMain(src => { + if (!src.find(l => l.match(/^(import|require).*@babel\/polyfill.*$/))) { + src.unshift('import \'@babel/polyfill\'') + } + + return src + }) } // If a-la-carte, update babel if (opts.useAlaCarte) { - let config - let configPath - function addBabelPlugin(cfg) { + helpers.updateBabelConfig(cfg => { if (cfg.plugins === undefined) { cfg.plugins = [] } @@ -123,32 +104,7 @@ module.exports = (api, opts, rootOpts) => { ]) return cfg - } - - const rcPath = api.resolve('./.babelrc') - if (fs.existsSync(rcPath)) { - configPath = rcPath - config = JSON.parse( fs.readFileSync(rcPath, { encoding: 'utf8' }) ) - config = addBabelPlugin(config) - } else { - const pkgPath = api.resolve('./package.json') - config = JSON.parse( fs.readFileSync(pkgPath, { encoding: 'utf8' }) ) - - if (config.babel) { - configPath = pkgPath - config.babel = addBabelPlugin(config.babel) - } - } - - if (configPath) { - fs.writeFileSync( - configPath, - JSON.stringify(config, null, 2), - { encoding: 'utf8' } - ) - } else { - // TODO handle if babel config doesn't exist - } + }) } // Add Material Icons @@ -165,13 +121,5 @@ module.exports = (api, opts, rootOpts) => { content = lines.reverse().join('\n') fs.writeFileSync(indexPath, content, { encoding: 'utf8' }) } - - // Based on router option, remove unneccessary vue components - const rimraf = require('rimraf') - if (opts.router) { - rimraf( api.resolve('./src/components'), () => {}) - } else { - rimraf( api.resolve('./src/views'), () => {}) - } }) } diff --git a/generator/templates/default/src/plugins/vuetify.js b/generator/templates/default/src/plugins/vuetify.js new file mode 100644 index 00000000..ee7af546 --- /dev/null +++ b/generator/templates/default/src/plugins/vuetify.js @@ -0,0 +1,46 @@ +import Vue from 'vue' +<%_ if (options.useAlaCarte) { _%> +import { + Vuetify, + VApp, + VNavigationDrawer, + VFooter, + VList, + VBtn, + VIcon, + VGrid, + VToolbar, + transitions +} from 'vuetify' +import '../node_modules/vuetify/src/stylus/app.styl' +<%_ } else { _%> +import Vuetify from 'vuetify' +import 'vuetify/dist/vuetify.min.css' +<%_ } _%> + +Vue.use(Vuetify, { +<%_ if (options.useAlaCarte) { _%> + components: { + VApp, + VNavigationDrawer, + VFooter, + VList, + VBtn, + VIcon, + VGrid, + VToolbar, + transitions + }, +<%_ } _%> +<%_ if (options.useTheme) { _%> + theme: { + primary: '#ee44aa', + secondary: '#424242', + accent: '#82B1FF', + error: '#FF5252', + info: '#2196F3', + success: '#4CAF50', + warning: '#FFC107' + }, +<%_ } _%> +}) \ No newline at end of file diff --git a/prompts.js b/prompts.js index 1d0192ca..824c3058 100644 --- a/prompts.js +++ b/prompts.js @@ -1,16 +1,26 @@ -module.exports = [{ - type: 'confirm', - name: 'replaceComponents', - message: 'Allow Vuetify to replace App.vue and HelloWorld.vue?', - default: true, -}, { - type: 'confirm', - name: 'useTheme', - message: 'Use custom theme?', - default: false, -}, { - type: 'confirm', - name: 'useAlaCarte', - message: 'Use a-la-carte components?', - default: false, -}] +module.exports = [ + { + type: 'confirm', + name: 'replaceComponents', + message: 'Allow Vuetify to replace App.vue and HelloWorld.vue?', + default: true, + }, + { + type: 'confirm', + name: 'useTheme', + message: 'Use custom theme?', + default: false, + }, + { + type: 'confirm', + name: 'useAlaCarte', + message: 'Use a-la-carte components?', + default: false, + }, + { + type: 'confirm', + name: 'usePolyfill', + message: 'Use babel/polyfill?', + default: true + } +] From 4c7783c44dc043585c6e02d164a710d25efdcc76 Mon Sep 17 00:00:00 2001 From: John Leider Date: Tue, 8 May 2018 19:23:33 -0400 Subject: [PATCH 2/2] refactor(index): updated font addition updated for upcoming font-weights --- generator/index.js | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) mode change 100644 => 100755 generator/index.js diff --git a/generator/index.js b/generator/index.js old mode 100644 new mode 100755 index 67120052..9b3d71c2 --- a/generator/index.js +++ b/generator/index.js @@ -116,7 +116,7 @@ module.exports = (api, opts, rootOpts) => { const lines = content.split(/\r?\n/g).reverse() const lastLink = lines.findIndex(line => line.match(/^\s*