Skip to content

Commit 95e6d6e

Browse files
authored
Merge pull request #50 from mpvue/feature/smartprograme
百度小程序支持和代码重构
2 parents 0bf0604 + bdaf962 commit 95e6d6e

File tree

6 files changed

+103
-93
lines changed

6 files changed

+103
-93
lines changed

lib/loader.js

+7-2
Original file line numberDiff line numberDiff line change
@@ -101,7 +101,7 @@ module.exports = function (content) {
101101
var output = ''
102102
var parts = parse(content, fileName, this.sourceMap)
103103

104-
// fix #153: 根组件没有 style 模块,不生成页面的 wxss,补齐内容方便加载 vendor.wxss
104+
// fix #153: 根组件没有 style 模块,不生成页面的样式文件,补齐内容方便加载 vendor
105105
if (!parts.styles.length) {
106106
parts.styles.push(defaultPart('style'))
107107
}
@@ -119,6 +119,11 @@ module.exports = function (content) {
119119
hasComment: hasComment,
120120
transformToRequire: options.transformToRequire,
121121
preserveWhitespace: options.preserveWhitespace,
122+
fileExt: options.fileExt || {
123+
template: 'wxml',
124+
style: 'wxss',
125+
script: 'js'
126+
},
122127
buble: options.buble,
123128
// only pass compilerModules if it's a path string
124129
compilerModules: typeof options.compilerModules === 'string'
@@ -258,7 +263,7 @@ module.exports = function (content) {
258263
var script = parts.script
259264
if (script) {
260265
// for mp js
261-
// 需要解析组件的 components 给 wxml 生成用
266+
// 需要解析组件的 components 给 mpml 生成用
262267
script = compileMPScript.call(this, script, mpOptions, moduleId)
263268

264269
if (options.esModule) {

lib/mp-compiler/index.js

+67-81
Original file line numberDiff line numberDiff line change
@@ -1,19 +1,17 @@
1-
// for mp
2-
const compiler = require('mpvue-template-compiler')
3-
41
const babel = require('babel-core')
52
const path = require('path')
63
const fs = require('fs')
74
const deepEqual = require('deep-equal')
5+
const compiler = require('mpvue-template-compiler')
86

97
const { parseConfig, parseComponentsDeps, parseGlobalComponents, clearGlobalComponents } = require('./parse')
108
const { parseComponentsDeps: parseComponentsDepsTs } = require('./parse-ts')
11-
const { genPageWxml } = require('./templates')
9+
const { genPageML } = require('./templates')
1210

1311
const {
1412
cacheFileInfo,
1513
getFileInfo,
16-
getCompNameAndSrc,
14+
getCompInfo,
1715
resolveTarget,
1816
covertCCVar,
1917
cacheSlots,
@@ -22,73 +20,57 @@ const {
2220
getBabelrc
2321
} = require('./util')
2422

25-
let slotsHookAdded = false
26-
27-
// 调用 compiler 生成 wxml
28-
function genComponentWxml (compiled, options, emitFile, emitError, emitWarning) {
23+
function genComponentMPML (compiled, options, emitFile, emitError, emitWarning, fileExt) {
2924
options.components['slots'] = { src: '/components/slots', name: 'slots' }
30-
const { code: wxmlCodeStr, compiled: cp, slots, importCode } = compiler.compileToWxml(compiled, options)
31-
const { mpErrors, mpTips } = cp
25+
const { code: mpmlContent, compiled: compiledResult, slots, importCode } = compiler.compileToWxml(compiled, options, fileExt)
26+
const { mpErrors, mpTips } = compiledResult
3227
// 缓存 slots,延迟编译
3328
cacheSlots(slots, importCode)
3429

3530
if (mpErrors && mpErrors.length) {
36-
emitError(
37-
`\n Error compiling template:\n` +
38-
mpErrors.map(e => ` - ${e}`).join('\n') + '\n'
39-
)
31+
emitError('\n Error compiling template:\n' + mpErrors.map(e => ` - ${e}`).join('\n') + '\n')
4032
}
4133
if (mpTips && mpTips.length) {
42-
emitWarning(
43-
mpTips.map(e => ` - ${e}`).join('\n') + '\n'
44-
)
34+
emitWarning(mpTips.map(e => ` - ${e}`).join('\n') + '\n')
4535
}
46-
return htmlBeautify(wxmlCodeStr)
36+
return htmlBeautify(mpmlContent)
4737
}
4838

49-
function createAppWxml (emitFile, resourcePath, rootComponent, context) {
39+
function createPageMPML (emitFile, resourcePath, rootComponent, context, fileExt) {
5040
const { src } = getFileInfo(resourcePath) || {}
51-
const { name: componentName, filePath: wxmlSrc } = getCompNameAndSrc(context, rootComponent)
52-
const wxmlContent = genPageWxml(componentName, wxmlSrc)
53-
emitFile(`${src}.wxml`, wxmlContent)
41+
const { name, filePath } = getCompInfo(context, rootComponent, fileExt)
42+
const MPMLContent = genPageML(name, filePath, fileExt)
43+
emitFile(`${src}.${fileExt.template}`, MPMLContent)
5444
}
55-
// 更新全局组件时,需要重新生成wxml,用这个字段保存所有需要更新的页面及其参数
56-
const cacheCreateWxmlFns = {}
5745

58-
function createWxml ({ emitWarning, emitError, emitFile, resourcePath, context, compiled }) {
59-
cacheCreateWxmlFns[resourcePath] = arguments
60-
const { pageType, moduleId, components } = getFileInfo(resourcePath) || {}
46+
// 更新全局组件时,需要重新生成 mpml,用这个字段保存所有需要更新的页面及其参数
47+
const cacheCreateMPMLFns = {}
6148

62-
// TODO, 这儿传 options 进去
63-
// {
64-
// components: {
65-
// 'com-a': { src: '../../components/comA$hash', name: 'comA$hash' }
66-
// },
67-
// pageType: 'component',
68-
// name: 'comA$hash',
69-
// moduleId: 'moduleId'
70-
// }
71-
const { name, filePath: wxmlSrc } = getCompNameAndSrc(context, resourcePath)
49+
function createComponentMPML ({ emitWarning, emitError, emitFile, resourcePath, context, compiled, fileExt }) {
50+
cacheCreateMPMLFns[resourcePath] = arguments
51+
const { pageType, moduleId, components } = getFileInfo(resourcePath) || {}
52+
const { name, filePath } = getCompInfo(context, resourcePath, fileExt)
7253
const options = { components, pageType, name, moduleId }
73-
const wxmlContent = genComponentWxml(compiled, options, emitFile, emitError, emitWarning)
74-
emitFile(wxmlSrc, wxmlContent)
54+
const MPMLContent = genComponentMPML(compiled, options, emitFile, emitError, emitWarning, fileExt)
55+
emitFile(filePath, MPMLContent)
7556
}
7657

77-
// 编译出 wxml
78-
function compileWxml (compiled, html) {
58+
let slotsHookAdded = false
59+
function compileMPML (compiled, html, options) {
60+
const fileExt = options.fileExt
7961
if (!slotsHookAdded) {
8062
// avoid add hook several times during compilation
8163
slotsHookAdded = true
8264
// TODO: support webpack4
8365
this._compilation.plugin('seal', () => {
8466
const content = getSlots()
8567
if (content.trim()) {
86-
this.emitFile('components/slots.wxml', htmlBeautify(content))
68+
this.emitFile(`components/slots.${fileExt.template}`, htmlBeautify(content))
8769
}
88-
// reset flag after slots file emited
8970
slotsHookAdded = false
9071
})
9172
}
73+
9274
return new Promise(resolve => {
9375
const pollComponentsStatus = () => {
9476
const { pageType, components } = getFileInfo(this.resourcePath) || {}
@@ -99,66 +81,66 @@ function compileWxml (compiled, html) {
9981
}
10082
}
10183
pollComponentsStatus()
102-
})
103-
.then(() => {
104-
createWxml({
105-
emitWarning: this.emitWarning,
106-
emitError: this.emitError,
107-
emitFile: this.emitFile,
108-
resourcePath: this.resourcePath,
109-
context: this.options.context,
110-
rootComponent: null,
111-
compiled, html
112-
})
84+
}).then(() => {
85+
createComponentMPML({
86+
emitWarning: this.emitWarning,
87+
emitError: this.emitError,
88+
emitFile: this.emitFile,
89+
resourcePath: this.resourcePath,
90+
context: this.options.context,
91+
rootComponent: null,
92+
compiled, html,
93+
fileExt
11394
})
95+
})
11496
}
11597

11698
// 针对 .vue 单文件的脚本逻辑的处理
11799
// 处理出当前单文件组件的子组件依赖
118100
function compileMPScript (script, mpOptioins, moduleId) {
119101
const { resourcePath, options, resolve, context } = this
120102
const babelrc = getBabelrc(mpOptioins.globalBabelrc)
121-
let result, metadata
103+
122104
let scriptContent = script.content
123105
const babelOptions = { extends: babelrc, plugins: [parseComponentsDeps] }
124-
if (script.src) { // 处理src
106+
if (script.src) {
125107
const scriptpath = path.join(path.dirname(resourcePath), script.src)
126108
scriptContent = fs.readFileSync(scriptpath).toString()
127109
}
128-
if (script.lang === 'ts') { // 处理ts
110+
111+
let metadata
112+
if (script.lang === 'ts') {
129113
metadata = parseComponentsDepsTs(scriptContent)
130114
} else {
131-
result = babel.transform(scriptContent, babelOptions)
115+
const result = babel.transform(scriptContent, babelOptions)
132116
metadata = result.metadata
133117
}
134-
135118
// metadata: importsMap, components
136119
const { importsMap, components: originComponents } = metadata
137120

138121
// 处理子组件的信息
139122
const components = {}
140123
const fileInfo = resolveTarget(resourcePath, options.entry)
124+
125+
const callback = () => resolveComponent(resourcePath, fileInfo, importsMap, components, moduleId)
141126
if (originComponents) {
142-
resolveSrc(originComponents, components, resolve, context, options.context).then(() => {
143-
resolveComponent(resourcePath, fileInfo, importsMap, components, moduleId)
144-
}).catch(err => {
145-
console.error(err)
146-
resolveComponent(resourcePath, fileInfo, importsMap, components, moduleId)
147-
})
127+
resolveSrc(originComponents, components, resolve, context, options.context, mpOptioins.fileExt)
128+
.then(() => callback())
129+
.catch(err => {
130+
console.error(err)
131+
callback()
132+
})
148133
} else {
149-
resolveComponent(resourcePath, fileInfo, importsMap, components, moduleId)
134+
callback()
150135
}
151136

152137
return script
153138
}
154139

155-
// checkMPEntry 针对 entry main.js 的入口处理
156-
// 编译出 app, page 的入口js/wxml/json
157-
140+
// checkMPEntry 针对 entry main.js 的入口处理: 编译出 app, page 的入口js、mpml、json
158141
let globalComponents
159142
function compileMP (content, mpOptioins) {
160143
const { resourcePath, emitFile, resolve, context, options } = this
161-
162144
const fileInfo = resolveTarget(resourcePath, options.entry)
163145
cacheFileInfo(resourcePath, fileInfo)
164146
const { isApp, isPage } = fileInfo
@@ -182,50 +164,50 @@ function compileMP (content, mpOptioins) {
182164

183165
// 解析全局组件的路径
184166
const components = {}
185-
resolveSrc(globalComps, components, resolve, context, options.context).then(() => {
167+
resolveSrc(globalComps, components, resolve, context, options.context, mpOptioins.fileExt).then(() => {
186168
handleResult(components)
187169
}).catch(err => {
188170
console.error(err)
189171
handleResult(components)
190172
})
191173
const handleResult = components => {
192174
globalComponents = components
193-
// 热更时,如果全局组件更新,需要重新生成所有的wxml
175+
// 热更时,如果全局组件更新,需要重新生成所有的 mpml
194176
if (oldGlobalComponents && !deepEqual(oldGlobalComponents, globalComponents)) {
195177
// 更新所有页面的组件
196178
Object.keys(cacheResolveComponents).forEach(k => {
197179
resolveComponent(...cacheResolveComponents[k])
198180
})
199-
// 重新生成所有wxml
200-
Object.keys(cacheCreateWxmlFns).forEach(k => {
201-
createWxml(...cacheCreateWxmlFns[k])
181+
// 重新生成所有 mpml
182+
Object.keys(cacheCreateMPMLFns).forEach(k => {
183+
createComponentMPML(...cacheCreateMPMLFns[k])
202184
})
203185
}
204186
}
205187
}
206188

207189
if (isApp || isPage) {
208190
// 这儿应该异步在所有的模块都清晰后再生成
209-
// 生成入口 wxml
191+
// 生成入口 mpml
210192
if (isPage && rootComponent) {
211193
resolve(context, rootComponent, (err, rootComponentSrc) => {
212194
if (err) return
213195
// 这儿需要搞定 根组件的 路径
214-
createAppWxml(emitFile, resourcePath, rootComponentSrc, this.options.context)
196+
createPageMPML(emitFile, resourcePath, rootComponentSrc, this.options.context, mpOptioins.fileExt)
215197
})
216198
}
217199
}
218200

219201
return content
220202
}
221203

222-
function resolveSrc (originComponents, components, resolveFn, context, projectRoot) {
204+
function resolveSrc (originComponents, components, resolveFn, context, projectRoot, fileExt) {
223205
return Promise.all(Object.keys(originComponents).map(k => {
224206
return new Promise((resolve, reject) => {
225207
resolveFn(context, originComponents[k], (err, realSrc) => {
226208
if (err) return reject(err)
227209
const com = covertCCVar(k)
228-
const { filePath, name } = getCompNameAndSrc(projectRoot, realSrc)
210+
const { filePath, name } = getCompInfo(projectRoot, realSrc, fileExt)
229211
components[com] = { src: filePath, name }
230212
resolve()
231213
})
@@ -247,4 +229,8 @@ function resolveComponent (resourcePath, fileInfo, importsMap, localComponents,
247229
}
248230
}
249231

250-
module.exports = { compileWxml, compileMPScript, compileMP }
232+
module.exports = {
233+
compileMP,
234+
compileMPML,
235+
compileMPScript
236+
}

lib/mp-compiler/templates.js

+21-2
Original file line numberDiff line numberDiff line change
@@ -1,5 +1,24 @@
1-
function genPageWxml (templateName, src) {
1+
function genWXML (templateName, src) {
22
return `<import src="${src}" /><template is="${templateName}" data="{{ ...$root['0'], $root }}"/>`
33
}
44

5-
module.exports = { genPageWxml }
5+
function genSWANML (templateName, src) {
6+
return `<import src="${src}" /><template is="${templateName}" data="{{{ ...$root['0'], $root }}}"/>`
7+
}
8+
9+
function genPageML (templateName, src, fileExt = {}) {
10+
let code
11+
switch (fileExt.platform) {
12+
case 'swan':
13+
code = genSWANML(templateName, src)
14+
break
15+
case 'wx':
16+
code = genWXML(templateName, src)
17+
break
18+
default:
19+
code = genWXML(templateName, src)
20+
}
21+
return code
22+
}
23+
24+
module.exports = { genPageML }

lib/mp-compiler/util.js

+4-4
Original file line numberDiff line numberDiff line change
@@ -15,8 +15,8 @@ function getFileInfo (resourcePath) {
1515
// TODO: 调试时取个全名
1616
var hash = require('hash-sum')
1717
const cache = Object.create(null)
18-
function getCompNameAndSrc (context, file) {
19-
const filePath = `/${resolveSrc(context, file)}.wxml`
18+
function getCompInfo (context, file, fileExt) {
19+
const filePath = `/${resolveSrc(context, file)}.${fileExt.template}`
2020
if (!cache[file]) {
2121
cache[file] = hash(file)
2222
}
@@ -91,7 +91,7 @@ function getSlots () {
9191
return allImportCode + allSlots
9292
}
9393

94-
// 包大小优化: build 模式不需要美化 wxml
94+
// 包大小优化: build 模式不需要美化 mpml
9595
const jsBeautify = require('js-beautify')
9696
const isProduction = process.env.NODE_ENV === 'production'
9797
function htmlBeautify (content) {
@@ -142,7 +142,7 @@ module.exports = {
142142
defaultPart,
143143
cacheFileInfo,
144144
getFileInfo,
145-
getCompNameAndSrc,
145+
getCompInfo,
146146
resolveTarget,
147147
covertCCVar,
148148
cacheSlots,

lib/template-compiler/index.js

+3-3
Original file line numberDiff line numberDiff line change
@@ -7,7 +7,7 @@ var hotReloadAPIPath = normalize.dep('vue-hot-reload-api')
77
var transformRequire = require('./modules/transform-require')
88

99
// for mp
10-
var compileWxml = require('../mp-compiler').compileWxml
10+
var compileMPML = require('../mp-compiler').compileMPML
1111

1212
module.exports = function (html) {
1313
this.async()
@@ -43,8 +43,8 @@ module.exports = function (html) {
4343
var compiled = compile(html, compilerOptions)
4444
var code
4545

46-
// for mp => *.wxml
47-
compileWxml.call(this, compiled, html)
46+
// for mp => *.mpml
47+
compileMPML.call(this, compiled, html, options)
4848
.then(() => {
4949
// tips
5050
if (compiled.tips && compiled.tips.length) {

package.json

+1-1
Original file line numberDiff line numberDiff line change
@@ -1,6 +1,6 @@
11
{
22
"name": "mpvue-loader",
3-
"version": "1.1.4",
3+
"version": "1.2.0",
44
"description": "mpvue single-file component loader for Webpack",
55
"main": "index.js",
66
"repository": {

0 commit comments

Comments
 (0)