Skip to content
This repository was archived by the owner on May 8, 2025. It is now read-only.

Commit 350e09d

Browse files
authored
Merge pull request #8 from vuetifyjs/bug-fixes
fix/enh: restructured code, fixed bugs
2 parents 58ff6ad + 4c7783c commit 350e09d

File tree

4 files changed

+181
-126
lines changed

4 files changed

+181
-126
lines changed

generator/helpers.js

Lines changed: 51 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,51 @@
1+
const fs = require('fs')
2+
3+
module.exports = function (api) {
4+
return {
5+
updateBabelConfig (callback) {
6+
let config, configPath
7+
8+
const rcPath = api.resolve('./.babelrc')
9+
const pkgPath = api.resolve('./package.json')
10+
if (fs.existsSync(rcPath)) {
11+
configPath = rcPath
12+
config = JSON.parse(fs.readFileSync(rcPath, { encoding: 'utf8' }))
13+
config = callback(config)
14+
} else if (fs.existsSync(pkgPath)) {
15+
configPath = pkgPath
16+
config = JSON.parse(fs.readFileSync(pkgPath, { encoding: 'utf8' }))
17+
18+
if (config.babel) {
19+
config.babel = callback(config.babel)
20+
} else {
21+
// TODO: error handling here?
22+
}
23+
}
24+
25+
if (configPath) {
26+
fs.writeFileSync(
27+
configPath,
28+
JSON.stringify(config, null, 2),
29+
{ encoding: 'utf8' }
30+
)
31+
} else {
32+
// TODO: handle if babel config doesn't exist
33+
}
34+
},
35+
36+
updateMain (callback) {
37+
const tsPath = api.resolve('./src/main.ts')
38+
const jsPath = api.resolve('./src/main.js')
39+
40+
const mainPath = fs.existsSync(tsPath) ? tsPath : jsPath
41+
let content = fs.readFileSync(mainPath, { encoding: 'utf8' })
42+
43+
let lines = content.split(/\r?\n/g)
44+
45+
lines = callback(lines)
46+
47+
content = lines.join('\n')
48+
fs.writeFileSync(mainPath, content, { encoding: 'utf8' })
49+
}
50+
}
51+
}

generator/index.js

100644100755
Lines changed: 58 additions & 110 deletions
Original file line numberDiff line numberDiff line change
@@ -1,4 +1,6 @@
11
module.exports = (api, opts, rootOpts) => {
2+
const helpers = require('./helpers')(api)
3+
24
api.extendPackage({
35
dependencies: {
46
vuetify: "^1.0.16"
@@ -15,99 +17,78 @@ module.exports = (api, opts, rootOpts) => {
1517
})
1618
}
1719

18-
// Handle if router exists
19-
{
20-
const fs = require('fs')
21-
const routerPath = api.resolve('./src/router.js')
22-
opts.router = fs.existsSync(routerPath)
20+
// Render vuetify plugin file
21+
api.render({
22+
'./src/plugins/vuetify.js': './templates/default/src/plugins/vuetify.js'
23+
}, opts)
24+
25+
// Render files if we're replacing
26+
const fs = require('fs')
27+
const routerPath = api.resolve('./src/router.js')
28+
opts.router = fs.existsSync(routerPath)
2329

24-
if (opts.replaceComponents) {
25-
api.render('./templates/default', { ...opts })
30+
if (opts.replaceComponents) {
31+
const files = {
32+
'./src/App.vue': './templates/default/src/App.vue',
33+
'./src/assets/logo.png': './templates/default/src/assets/logo.png'
2634
}
35+
36+
if (opts.router) {
37+
files['./src/views/Home.vue'] = './templates/default/src/views/Home.vue'
38+
} else {
39+
files['./src/components/HelloWorld.vue'] = './templates/default/src/components/HelloWorld.vue'
40+
}
41+
42+
api.render(files, opts)
2743
}
2844

2945
// adapted from https://github.com/Akryum/vue-cli-plugin-apollo/blob/master/generator/index.js#L68-L91
3046
api.onCreateComplete(() => {
31-
const fs = require('fs')
47+
// Modify main.js
48+
helpers.updateMain(src => {
49+
const vueImportIndex = src.findIndex(line => line.match(/^import Vue/))
3250

33-
// Setup Vuetify import for main.js
34-
let vuetifyLines = ''
35-
if (opts.useAlaCarte) {
36-
vuetifyLines += "\nimport {"
37-
vuetifyLines += "\n Vuetify,"
38-
vuetifyLines += "\n VApp,"
39-
vuetifyLines += "\n VNavigationDrawer,"
40-
vuetifyLines += "\n VFooter,"
41-
vuetifyLines += "\n VList,"
42-
vuetifyLines += "\n VBtn,"
43-
vuetifyLines += "\n VIcon,"
44-
vuetifyLines += "\n VGrid,"
45-
vuetifyLines += "\n VToolbar,"
46-
vuetifyLines += "\n transitions"
47-
vuetifyLines += "\n} from 'vuetify'"
48-
vuetifyLines += "\nimport '../node_modules/vuetify/src/stylus/app.styl'\n"
49-
} else {
50-
vuetifyLines += "\nimport Vuetify from 'vuetify'"
51-
vuetifyLines += "\nimport 'vuetify/dist/vuetify.min.css'\n"
52-
}
51+
src.splice(vueImportIndex + 1, 0, 'import \'./plugins/vuetify\'')
5352

54-
if (opts.useAlaCarte || opts.useTheme) {
55-
vuetifyLines += "\nVue.use(Vuetify, {"
56-
57-
if (opts.useAlaCarte) {
58-
vuetifyLines += "\n components: {"
59-
vuetifyLines += "\n VApp,"
60-
vuetifyLines += "\n VNavigationDrawer,"
61-
vuetifyLines += "\n VFooter,"
62-
vuetifyLines += "\n VList,"
63-
vuetifyLines += "\n VBtn,"
64-
vuetifyLines += "\n VIcon,"
65-
vuetifyLines += "\n VGrid,"
66-
vuetifyLines += "\n VToolbar,"
67-
vuetifyLines += "\n transitions"
68-
vuetifyLines += "\n },"
69-
}
53+
return src
54+
})
7055

71-
if (opts.useTheme) {
72-
vuetifyLines += "\n theme: {"
73-
vuetifyLines += "\n primary: '#ee44aa',"
74-
vuetifyLines += "\n secondary: '#424242',"
75-
vuetifyLines += "\n accent: '#82B1FF',"
76-
vuetifyLines += "\n error: '#FF5252',"
77-
vuetifyLines += "\n info: '#2196F3',"
78-
vuetifyLines += "\n success: '#4CAF50',"
79-
vuetifyLines += "\n warning: '#FFC107'"
80-
vuetifyLines += "\n },"
81-
}
56+
// Add polyfill
57+
if (opts.usePolyfill) {
58+
helpers.updateBabelConfig(cfg => {
59+
if (!cfg.presets) return
8260

83-
vuetifyLines += "\n})"
84-
} else {
85-
vuetifyLines += "\nVue.use(Vuetify)"
86-
}
61+
const vuePresetIndex = cfg.presets.findIndex(p => Array.isArray(p) ? p[0] === '@vue/app' : p === '@vue/app')
62+
const isArray = Array.isArray(cfg.presets[vuePresetIndex])
8763

88-
// Modify main.js
89-
{
90-
const tsPath = api.resolve('./src/main.ts')
91-
const jsPath = api.resolve('./src/main.js')
64+
if (vuePresetIndex < 0) return
9265

93-
const mainPath = fs.existsSync(tsPath) ? tsPath : jsPath
94-
let content = fs.readFileSync(mainPath, { encoding: 'utf8' })
66+
if (isArray) {
67+
cfg.presets[vuePresetIndex][1]['useBuiltIns'] = 'entry'
68+
} else {
69+
cfg.presets[vuePresetIndex] = [
70+
'@vue/app',
71+
{
72+
useBuiltIns: 'entry'
73+
}
74+
]
75+
}
9576

96-
const lines = content.split(/\r?\n/g).reverse()
77+
return cfg
78+
})
9779

98-
// Inject import
99-
const lastImportIndex = lines.findIndex(line => line.match(/^import/))
100-
lines[lastImportIndex] += vuetifyLines
101-
// Modify app
102-
content = lines.reverse().join('\n')
103-
fs.writeFileSync(mainPath, content, { encoding: 'utf8' })
80+
helpers.updateMain(src => {
81+
if (!src.find(l => l.match(/^(import|require).*@babel\/polyfill.*$/))) {
82+
src.unshift('import \'@babel/polyfill\'')
83+
}
84+
85+
return src
86+
})
10487
}
10588

10689
// If a-la-carte, update babel
10790
if (opts.useAlaCarte) {
108-
let config
109-
let configPath
110-
function addBabelPlugin(cfg) {
91+
helpers.updateBabelConfig(cfg => {
11192
if (cfg.plugins === undefined) {
11293
cfg.plugins = []
11394
}
@@ -123,32 +104,7 @@ module.exports = (api, opts, rootOpts) => {
123104
])
124105

125106
return cfg
126-
}
127-
128-
const rcPath = api.resolve('./.babelrc')
129-
if (fs.existsSync(rcPath)) {
130-
configPath = rcPath
131-
config = JSON.parse( fs.readFileSync(rcPath, { encoding: 'utf8' }) )
132-
config = addBabelPlugin(config)
133-
} else {
134-
const pkgPath = api.resolve('./package.json')
135-
config = JSON.parse( fs.readFileSync(pkgPath, { encoding: 'utf8' }) )
136-
137-
if (config.babel) {
138-
configPath = pkgPath
139-
config.babel = addBabelPlugin(config.babel)
140-
}
141-
}
142-
143-
if (configPath) {
144-
fs.writeFileSync(
145-
configPath,
146-
JSON.stringify(config, null, 2),
147-
{ encoding: 'utf8' }
148-
)
149-
} else {
150-
// TODO handle if babel config doesn't exist
151-
}
107+
})
152108
}
153109

154110
// Add Material Icons
@@ -160,18 +116,10 @@ module.exports = (api, opts, rootOpts) => {
160116
const lines = content.split(/\r?\n/g).reverse()
161117

162118
const lastLink = lines.findIndex(line => line.match(/^\s*<link/))
163-
lines[lastLink] += '\n<link href="https://fonts.googleapis.com/css?family=Roboto:300,400,500,700|Material+Icons" rel="stylesheet">'
119+
lines[lastLink] += '\n\t\t<link href="https://fonts.googleapis.com/css?family=Roboto:100:300,400,500,700,900|Material+Icons" rel="stylesheet">'
164120

165121
content = lines.reverse().join('\n')
166122
fs.writeFileSync(indexPath, content, { encoding: 'utf8' })
167123
}
168-
169-
// Based on router option, remove unneccessary vue components
170-
const rimraf = require('rimraf')
171-
if (opts.router) {
172-
rimraf( api.resolve('./src/components'), () => {})
173-
} else {
174-
rimraf( api.resolve('./src/views'), () => {})
175-
}
176124
})
177125
}
Lines changed: 46 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,46 @@
1+
import Vue from 'vue'
2+
<%_ if (options.useAlaCarte) { _%>
3+
import {
4+
Vuetify,
5+
VApp,
6+
VNavigationDrawer,
7+
VFooter,
8+
VList,
9+
VBtn,
10+
VIcon,
11+
VGrid,
12+
VToolbar,
13+
transitions
14+
} from 'vuetify'
15+
import '../node_modules/vuetify/src/stylus/app.styl'
16+
<%_ } else { _%>
17+
import Vuetify from 'vuetify'
18+
import 'vuetify/dist/vuetify.min.css'
19+
<%_ } _%>
20+
21+
Vue.use(Vuetify, {
22+
<%_ if (options.useAlaCarte) { _%>
23+
components: {
24+
VApp,
25+
VNavigationDrawer,
26+
VFooter,
27+
VList,
28+
VBtn,
29+
VIcon,
30+
VGrid,
31+
VToolbar,
32+
transitions
33+
},
34+
<%_ } _%>
35+
<%_ if (options.useTheme) { _%>
36+
theme: {
37+
primary: '#ee44aa',
38+
secondary: '#424242',
39+
accent: '#82B1FF',
40+
error: '#FF5252',
41+
info: '#2196F3',
42+
success: '#4CAF50',
43+
warning: '#FFC107'
44+
},
45+
<%_ } _%>
46+
})

prompts.js

Lines changed: 26 additions & 16 deletions
Original file line numberDiff line numberDiff line change
@@ -1,16 +1,26 @@
1-
module.exports = [{
2-
type: 'confirm',
3-
name: 'replaceComponents',
4-
message: 'Allow Vuetify to replace App.vue and HelloWorld.vue?',
5-
default: true,
6-
}, {
7-
type: 'confirm',
8-
name: 'useTheme',
9-
message: 'Use custom theme?',
10-
default: false,
11-
}, {
12-
type: 'confirm',
13-
name: 'useAlaCarte',
14-
message: 'Use a-la-carte components?',
15-
default: false,
16-
}]
1+
module.exports = [
2+
{
3+
type: 'confirm',
4+
name: 'replaceComponents',
5+
message: 'Allow Vuetify to replace App.vue and HelloWorld.vue?',
6+
default: true,
7+
},
8+
{
9+
type: 'confirm',
10+
name: 'useTheme',
11+
message: 'Use custom theme?',
12+
default: false,
13+
},
14+
{
15+
type: 'confirm',
16+
name: 'useAlaCarte',
17+
message: 'Use a-la-carte components?',
18+
default: false,
19+
},
20+
{
21+
type: 'confirm',
22+
name: 'usePolyfill',
23+
message: 'Use babel/polyfill?',
24+
default: true
25+
}
26+
]

0 commit comments

Comments
 (0)