Skip to content

Commit c93ce4e

Browse files
committed
feat: add vuefront-loader
1 parent 02b20d1 commit c93ce4e

File tree

13 files changed

+621
-250
lines changed

13 files changed

+621
-250
lines changed

src/index.js

Lines changed: 22 additions & 149 deletions
Original file line numberDiff line numberDiff line change
@@ -1,61 +1,13 @@
1-
import { readFileSync } from 'fs'
2-
1+
import setupRoutes from './setupRoutes'
2+
import setupConfig from './setupConfig'
3+
import setupBuild from './setupBuild'
4+
import setupImages from './setupImages'
35
const path = require('path')
4-
let seoConfig = require('vuefront/seo').default
56
const _ = require('lodash')
6-
const ApolloClient = require('apollo-boost').default
7-
require('isomorphic-fetch')
87
const ampify = require('./plugins/ampify')
98
var fs = require('fs');
109

11-
const readConfigFile = (path) => {
12-
const result = {}
13-
try {
14-
var filename = require.resolve(path);
15-
const configContent = fs.readFileSync(filename, 'utf8');
16-
let matched = /css.*:[\s\n\r]+\{([^{]+)\}/.exec(configContent)
17-
if(!_.isEmpty(matched)) {
18-
const cssConfig =
19-
matched[1]
20-
.replace(/\s\n/, '')
21-
.split(',')
22-
.map((str) =>
23-
str
24-
.split(':')
25-
.map(strV =>
26-
strV
27-
.trim()
28-
.replace(/\'/g, '')
29-
)
30-
).reduce((accumulator, currentValue) => {
31-
accumulator[currentValue[0]] = currentValue[1]
32-
return accumulator
33-
}, {})
34-
35-
result.css = cssConfig
36-
}
37-
matched = /theme: \'(.*)\'/.exec(configContent)
38-
if(!_.isEmpty(matched)) {
39-
result.theme = matched[1]
40-
}
41-
} catch (e) {
42-
}
43-
44-
return result
45-
}
46-
47-
const mergeConfig = (objValue, srcValue) => {
48-
if (_.isArray(objValue)) {
49-
return objValue.concat(srcValue)
50-
} else if (_.isObject(objValue)) {
51-
return _.merge(objValue, srcValue)
52-
} else {
53-
return srcValue
54-
}
55-
}
56-
5710
export default async function vuefrontModule(_moduleOptions) {
58-
const isNuxtVersion2 = this.options.build.transpile
5911
const moduleOptions = { ...this.options.vuefront, ..._moduleOptions }
6012

6113
const theme = process.env.VUEFRONT_THEME || 'default'
@@ -95,85 +47,21 @@ export default async function vuefrontModule(_moduleOptions) {
9547
browserBaseURL = moduleOptions.proxy ? prefix : baseURL
9648
}
9749

98-
const client = new ApolloClient({
99-
uri: baseURL
100-
})
101-
102-
let whiteList = []
103-
let routes = []
104-
for (const url in seoConfig) {
105-
const pageComponent = seoConfig[url]
106-
if (_.isObject(pageComponent)) {
107-
if (!_.isUndefined(pageComponent.generate) && pageComponent.generate) {
108-
whiteList = [...whiteList, url, '/amp' + url]
109-
} else if (_.isUndefined(pageComponent.generate) && !url.includes(':')) {
110-
whiteList = [...whiteList, url, '/amp' + url]
111-
}
112-
let result = []
113-
if (!_.isUndefined(pageComponent.seo)) {
114-
let seoResolver = pageComponent.seo
50+
const themeOptions = setupConfig(this.options.rootDir)
11551

116-
result = await seoResolver({ client })
117-
}
118-
routes.push({
119-
name: url.replace('/', '_').replace(':', '_'),
120-
path: url,
121-
component: pageComponent.component
122-
})
123-
routes.push({
124-
name: 'amp_' + url.replace('/', '_').replace(':', '_'),
125-
path: '/amp' + url,
126-
component: pageComponent.component
127-
})
128-
if (!_.isUndefined(pageComponent.seo) && !_.isEmpty(result)) {
129-
for (const urlKey in result) {
130-
if (result[urlKey].keyword !== '') {
131-
if (
132-
!_.isUndefined(pageComponent.generate) &&
133-
pageComponent.generate
134-
) {
135-
whiteList = [
136-
...whiteList,
137-
'/' + result[urlKey].keyword,
138-
'/amp/' + result[urlKey].keyword
139-
]
140-
} else if (_.isUndefined(pageComponent.generate)) {
141-
whiteList = [
142-
...whiteList,
143-
'/' + result[urlKey].keyword,
144-
'/amp/' + result[urlKey].keyword
145-
]
146-
}
147-
routes.push({
148-
name: result[urlKey].keyword,
149-
path: '/' + result[urlKey].keyword,
150-
component: pageComponent.component,
151-
props: { ...result[urlKey], url }
152-
})
153-
routes.push({
154-
name: 'amp_' + result[urlKey].keyword,
155-
path: '/amp/' + result[urlKey].keyword,
156-
component: pageComponent.component,
157-
props: { ...result[urlKey], url }
158-
})
159-
}
160-
}
161-
}
162-
} else {
163-
whiteList = [...whiteList, url, '/amp' + url]
164-
routes.push({
165-
name: url.replace('/', '_').replace(':', '_'),
166-
path: url,
167-
component: pageComponent.component
168-
})
169-
routes.push({
170-
name: 'amp_' + url.replace('/', '_').replace(':', '_'),
171-
path: '/amp' + url,
172-
component: pageComponent.component
173-
})
52+
if(!this.options.css) {
53+
this.options.css = []
54+
}
55+
if(themeOptions.css) {
56+
for (const key in themeOptions.css) {
57+
this.options.css.push(themeOptions.css[key])
17458
}
17559
}
17660

61+
const images = setupImages(themeOptions)
62+
63+
const {routes, whiteList} = await setupRoutes(baseURL, themeOptions)
64+
17765
const pages = _.ceil(routes.length / 500)
17866

17967
for (var i = 0; i < pages; i++) {
@@ -182,7 +70,8 @@ export default async function vuefrontModule(_moduleOptions) {
18270
src: path.resolve(__dirname, './routes.js'),
18371
options: {
18472
routes: _.slice(routes, i * 500, i * 500 + 500),
185-
theme
73+
theme,
74+
themeOptions
18675
}
18776
})
18877
}
@@ -208,21 +97,12 @@ export default async function vuefrontModule(_moduleOptions) {
20897
src: defaultRouter
20998
})
21099

211-
let themeOptions = readConfigFile('vuefront')
212-
213-
const config = readConfigFile(this.options.rootDir + '/vuefront.config.js')
214-
215-
if (typeof config.theme !== 'undefined') {
216-
const customThemeOptions = readConfigFile(config.theme)
217-
themeOptions = _.mergeWith(themeOptions, customThemeOptions, mergeConfig)
218-
}
219-
220-
themeOptions = _.mergeWith(themeOptions, config, mergeConfig)
221100

222101
this.addPlugin({
223102
fileName: 'vuefront.js',
224103
src: path.resolve(__dirname, './plugin.js'),
225104
options: {
105+
images,
226106
theme,
227107
debug: this.options.dev,
228108
browserBaseURL,
@@ -249,6 +129,10 @@ export default async function vuefrontModule(_moduleOptions) {
249129
page.html = ampify(page.html, url)
250130
})
251131

132+
this.nuxt.hook('build:before', () => {
133+
setupBuild.call(this, moduleOptions);
134+
})
135+
252136
this.extendBuild((config, { isServer }) => {
253137
const { rules } = config.module
254138

@@ -277,16 +161,5 @@ export default async function vuefrontModule(_moduleOptions) {
277161
}
278162
rules.push(blockRules)
279163
}
280-
281-
const vuefrontRe = 'vuefront'
282-
if (isNuxtVersion2) {
283-
this.options.build.transpile.push(vuefrontRe)
284-
} else {
285-
config.externals = [
286-
nodeExternals({
287-
whitelist: [vuefrontRe]
288-
})
289-
]
290-
}
291164
})
292165
}

src/plugin.js

Lines changed: 43 additions & 75 deletions
Original file line numberDiff line numberDiff line change
@@ -3,36 +3,6 @@ import VueI18n from 'vue-i18n'
33
import ApolloClient from "apollo-boost";
44
import _ from 'lodash'
55
import 'isomorphic-fetch'
6-
import mainConfig from 'vuefront'
7-
import userConfig from '~/vuefront.config'
8-
<% if (options.theme !== 'default' ) { %>
9-
import themeConfig from '<%= options.theme %>'
10-
<% } %>
11-
<% if (typeof options.themeOptions.css !== 'undefined' ) { %>
12-
<% for (const key in options.themeOptions.css) { %>
13-
<% if (options.themeOptions.css[key] !== 'null' ) { %>
14-
import '<%= options.themeOptions.css[key] %>'
15-
<% } %>
16-
<% } %>
17-
<% } %>
18-
19-
20-
const mergeConfig = (objValue, srcValue) => {
21-
if (_.isArray(objValue)) {
22-
return objValue.concat(srcValue)
23-
} else if (_.isObject(objValue)) {
24-
return _.merge(objValue, srcValue)
25-
} else {
26-
return srcValue
27-
}
28-
}
29-
30-
let themeOptions = mainConfig
31-
32-
if (typeof themeConfig !== 'undefined') {
33-
themeOptions = _.mergeWith(themeOptions, themeConfig, mergeConfig)
34-
}
35-
themeOptions = _.mergeWith(themeOptions, userConfig, mergeConfig)
366

377
Vue.use(VueI18n)
388

@@ -100,14 +70,21 @@ function loadLocaleMessages(options) {
10070
const locales = require.context(`~/locales`, true, /\.json$/)
10171
const messages = {}
10272

103-
for (var key in options.locales) {
104-
if(_.isUndefined(messages[key])) {
105-
messages[key] = {}
106-
}
107-
for (var key2 in options.locales[key]) {
108-
messages[key] = _.merge({}, messages[key], options.locales[key][key2])
73+
<% for (var key in options.themeOptions.locales) { %>
74+
if(_.isUndefined(messages['<%= key %>'])) {
75+
messages['<%= key %>'] = {}
10976
}
110-
}
77+
78+
<% for (var key2 in options.themeOptions.locales[key]) { %>
79+
<% if (options.themeOptions.locales[key][key2].type === 'full') { %>
80+
messages['<%= key %>'] = _.merge({}, messages['<%= key %>'], require('<%= options.themeOptions.locales[key][key2].path %>'))
81+
<% } else { %>
82+
messages['<%= key %>'] = _.merge({}, messages['<%= key %>'], require('<%= options.themeOptions.locales[key][key2].path %>')['<%= options.themeOptions.locales[key][key2].component %>'])
83+
<% } %>
84+
<% } %>
85+
86+
<% } %>
87+
11188
locales.keys().forEach(key => {
11289
const local = /^.\/([a-zA-Z-]+)\//.exec(key)[1]
11390
if(_.isUndefined(messages[local])) {
@@ -126,57 +103,48 @@ export default async (ctx, inject) => {
126103

127104
init(ctx, inject)
128105

129-
const components = {
130-
element: {},
131-
template: {},
132-
position: {},
133-
module: {}
134-
}
135-
136106
const opts = {}
137107

138108
if(process.client) {
139109
if(_.isUndefined(window.__NUXT__)) {
140110
opts.preserveState = false
141111
}
142112
}
113+
114+
<% for (var key in options.themeOptions.store) { %>
115+
<% if (typeof options.themeOptions.store[key].module !== 'undefined') {%>
116+
<% if (options.themeOptions.store[key].module.type === 'full') { %>
117+
ctx.store.registerModule(<%= JSON.stringify(options.themeOptions.store[key].path) %>, {namespaced: true, ...require('<%= options.themeOptions.store[key].module.path %>')}, opts)
118+
<% } else { %>
119+
ctx.store.registerModule(<%= JSON.stringify(options.themeOptions.store[key].path) %>, {namespaced: true, ...require('<%= options.themeOptions.store[key].module.path %>')['<%= options.themeOptions.store[key].module.component %>']}, opts)
120+
<% } %>
121+
<% } else { %>
122+
ctx.store.registerModule(<%= JSON.stringify(options.themeOptions.store[key].path) %>, {namespaced: true}, opts)
123+
<% } %>
124+
<% } %>
143125

144-
for (var key in themeOptions.store) {
145-
if (typeof themeOptions.store[key].module !== 'undefined') {
146-
ctx.store.registerModule(themeOptions.store[key].path, {namespaced: true, ...themeOptions.store[key].module}, opts)
147-
} else {
148-
ctx.store.registerModule(themeOptions.store[key].path, {namespaced: true}, opts)
149-
}
150-
}
126+
const extensions = {}
151127

152-
for (var key in themeOptions.atoms) {
153-
components[`vfA${key}`] = Vue.component(`vfA${key}`, themeOptions.atoms[key])
154-
}
128+
<% for (var key in options.themeOptions.extensions) { %>
129+
<% if (options.themeOptions.extensions[key].type === 'full') { %>
130+
extensions.<%= key %> = () => import('<%= options.themeOptions.extensions[key].component %>');
131+
<% } else { %>
132+
extensions.<%= key %> = () => import('<%= options.themeOptions.extensions[key].path %>').then(m => m.<%= options.themeOptions.extensions[key].component %>);<% } %><% } %>
155133

156-
for (var key in themeOptions.molecules) {
157-
components[`vfM${key}`] = Vue.component(`vfM${key}`, themeOptions.molecules[key])
158-
}
134+
const images = {}
159135

160-
for (var key in themeOptions.organisms) {
161-
components[`vfO${key}`] = Vue.component(`vfO${key}`, themeOptions.organisms[key])
162-
}
136+
<% for (var key in options.images) { %>
163137

164-
for (var key in themeOptions.templates) {
165-
components[`vfT${key}`] = Vue.component(`vfT${key}`, themeOptions.templates[key])
166-
}
167-
for (var key in themeOptions.components) {
168-
components[`vf${key}`] = Vue.component(`vf${key}`, themeOptions.components[key])
169-
}
170-
for (var key in themeOptions.extensions) {
171-
components[`vfE${key}`] = Vue.component(`vfE${key}`, themeOptions.extensions[key])
172-
}
173-
for (var key in themeOptions.loaders) {
174-
components[`vfL${key}`] = Vue.component(`vfL${key}`, themeOptions.loaders[key])
175-
}
138+
images.<%= key %> = {}<% if (typeof options.images[key].image !== 'undefined') { %>
139+
images.<%= key %>.image = <%= options.images[key].image %>;
140+
<% } %><% if (typeof options.images[key].width !== 'undefined') { %>
141+
images.<%= key %>.width = <%= options.images[key].width %>;
142+
images.<%= key %>.height = <%= options.images[key].height %>;<% } %><% } %>
176143

177144
inject('vuefront', {
178-
options: themeOptions,
179-
components,
145+
layouts: <%= JSON.stringify(options.themeOptions.layouts) %>,
146+
extensions,
147+
images,
180148
baseURL,
181149
get isAuth() {
182150
return ctx.store.getters['common/customer/auth']
@@ -210,7 +178,7 @@ export default async (ctx, inject) => {
210178

211179
ctx.app.i18n = new VueI18n({
212180
locale: ctx.store.getters['common/language/locale'],
213-
messages: loadLocaleMessages(themeOptions)
181+
messages: loadLocaleMessages()
214182
})
215183

216184
}

src/router.js

Lines changed: 2 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -11,7 +11,8 @@ export function createRouter(ssrContext) {
1111
const defaultRouter = createDefaultRouter(ssrContext)
1212
return new Router({
1313
...defaultRouter.options,
14-
routes: [<% for(var i=0; i < options.pages; i++) {%>
14+
routes: [
15+
<% for(var i=0; i < options.pages; i++) {%>
1516
...routes<%= i+1%>,<% } %>
1617
...defaultRouter.options.routes
1718
]

0 commit comments

Comments
 (0)