diff --git a/.gitignore b/.gitignore
index e45d3c7..44a66dd 100644
--- a/.gitignore
+++ b/.gitignore
@@ -5,3 +5,4 @@ docs/_book
.DS_Store
.idea
*.iml
+yarn.lock
diff --git a/lib/mp-compiler/index.js b/lib/mp-compiler/index.js
index 345a8b8..753d8d3 100644
--- a/lib/mp-compiler/index.js
+++ b/lib/mp-compiler/index.js
@@ -5,22 +5,22 @@ const babel = require('babel-core')
const path = require('path')
const fs = require('fs')
const deepEqual = require('deep-equal')
+const relative = require('../utils/relative')
const { parseConfig, parseComponentsDeps, parseGlobalComponents, clearGlobalComponents } = require('./parse')
const { parseComponentsDeps: parseComponentsDepsTs } = require('./parse-ts')
-const { genScript, genStyle, genPageWxml } = require('./templates')
+const { genPageWxml } = require('./templates')
const {
cacheFileInfo,
getFileInfo,
- getCompNameBySrc,
+ getCompNameAndSrc,
resolveTarget,
covertCCVar,
cacheSlots,
getSlots,
htmlBeautify,
- getBabelrc,
- getPageSrc
+ getBabelrc
} = require('./util')
let slotsHookAdded = false
@@ -48,17 +48,16 @@ function genComponentWxml (compiled, options, emitFile, emitError, emitWarning)
return htmlBeautify(wxmlCodeStr)
}
-function createAppWxml (emitFile, resourcePath, rootComponent) {
+function createAppWxml (emitFile, resourcePath, rootComponent, context) {
const { src } = getFileInfo(resourcePath) || {}
- const componentName = getCompNameBySrc(rootComponent)
- const wxmlContent = genPageWxml(componentName, src)
- const wxmlSrc = src
- emitFile(`${wxmlSrc}.wxml`, wxmlContent)
+ const { name: componentName, filePath: wxmlSrc } = getCompNameAndSrc(context, rootComponent)
+ const wxmlContent = genPageWxml(componentName, relative(`/${src}.wxml`, `/${wxmlSrc}`))
+ emitFile(`${src}.wxml`, wxmlContent)
}
// 更新全局组件时,需要重新生成wxml,用这个字段保存所有需要更新的页面及其参数
const cacheCreateWxmlFns = {}
-function createWxml (emitWarning, emitError, emitFile, resourcePath, rootComponent, compiled, html) {
+function createWxml ({ emitWarning, emitError, emitFile, resourcePath, context, compiled }) {
cacheCreateWxmlFns[resourcePath] = arguments
const { pageType, moduleId, components } = getFileInfo(resourcePath) || {}
@@ -71,12 +70,10 @@ function createWxml (emitWarning, emitError, emitFile, resourcePath, rootCompone
// name: 'comA$hash',
// moduleId: 'moduleId'
// }
- const name = getCompNameBySrc(resourcePath)
+ const { name, filePath: wxmlSrc } = getCompNameAndSrc(context, resourcePath)
const options = { components, pageType, name, moduleId }
const wxmlContent = genComponentWxml(compiled, options, emitFile, emitError, emitWarning)
- const wxmlSrc = `components/${name}`
-
- emitFile(`${wxmlSrc}.wxml`, wxmlContent)
+ emitFile(wxmlSrc, wxmlContent)
}
// 编译出 wxml
@@ -106,7 +103,15 @@ function compileWxml (compiled, html) {
pollComponentsStatus()
})
.then(() => {
- createWxml(this.emitWarning, this.emitError, this.emitFile, this.resourcePath, null, compiled, html)
+ createWxml({
+ emitWarning: this.emitWarning,
+ emitError: this.emitError,
+ emitFile: this.emitFile,
+ resourcePath: this.resourcePath,
+ context: this.options.context,
+ rootComponent: null,
+ compiled, html
+ })
})
}
@@ -151,14 +156,13 @@ function compileMPScript (script, mpOptioins, moduleId) {
// checkMPEntry 针对 entry main.js 的入口处理
// 编译出 app, page 的入口js/wxml/json
-const startPageReg = /^\^/
let globalComponents
function compileMP (content, mpOptioins) {
const { resourcePath, emitFile, resolve, context, options } = this
const fileInfo = resolveTarget(resourcePath, options.entry)
cacheFileInfo(resourcePath, fileInfo)
- const { src, name, isApp, isPage } = fileInfo
+ const { isApp, isPage } = fileInfo
if (isApp) {
// 解析前将可能存在的全局组件清空
clearGlobalComponents()
@@ -169,7 +173,7 @@ function compileMP (content, mpOptioins) {
const { metadata } = babel.transform(content, { extends: babelrc, plugins: isApp ? [parseConfig, parseGlobalComponents] : [parseConfig] })
// metadata: config
- const { config, rootComponent, globalComponents: globalComps } = metadata
+ const { rootComponent, globalComponents: globalComps } = metadata
if (isApp) {
// 保存旧数据,用于对比
@@ -202,39 +206,13 @@ function compileMP (content, mpOptioins) {
}
if (isApp || isPage) {
- // 生成入口 json
- if (config) {
- const configObj = config.value
-
- // 只有 app 才处理 pages
- if (isApp) {
- const pages = Object.keys(options.entry).concat(configObj.pages).filter(v => v && v !== 'app').map(getPageSrc)
-
- // ^ 开头的放在第一个
- const startPageIndex = pages.findIndex(v => startPageReg.test(v))
- if (startPageIndex !== -1) {
- const startPage = pages[startPageIndex].slice(1)
- pages.splice(startPageIndex, 1)
- pages.unshift(startPage)
- }
- configObj.pages = [...new Set(pages)]
- }
- emitFile(`${src}.json`, JSON.stringify(configObj, null, ' '))
- }
-
- // 生成入口 js
- emitFile(`${src}.js`, genScript(name, isPage, src))
-
- // 生成入口 wxss
- emitFile(`${src}.wxss`, genStyle(name, isPage, src))
-
// 这儿应该异步在所有的模块都清晰后再生成
// 生成入口 wxml
if (isPage && rootComponent) {
resolve(context, rootComponent, (err, rootComponentSrc) => {
if (err) return
// 这儿需要搞定 根组件的 路径
- createAppWxml(emitFile, resourcePath, rootComponentSrc)
+ createAppWxml(emitFile, resourcePath, rootComponentSrc, this.options.context)
})
}
}
@@ -248,8 +226,8 @@ function resolveSrc (originComponents, components, resolveFn, context) {
resolveFn(context, originComponents[k], (err, realSrc) => {
if (err) return reject(err)
const com = covertCCVar(k)
- const comName = getCompNameBySrc(realSrc)
- components[com] = { src: comName, name: comName }
+ const { filePath, name } = getCompNameAndSrc(context, realSrc)
+ components[com] = { src: filePath, name }
resolve()
})
})
diff --git a/lib/mp-compiler/templates.js b/lib/mp-compiler/templates.js
index 4b73f32..d6680c9 100644
--- a/lib/mp-compiler/templates.js
+++ b/lib/mp-compiler/templates.js
@@ -1,22 +1,5 @@
-const { getPathPrefix } = require('./util')
-
-function genScript (name, isPage, src) {
- const prefix = isPage ? getPathPrefix(src) : './'
-
- return `
-require('${prefix}static/js/manifest')
-require('${prefix}static/js/vendor')
-require('${prefix}static/js/${name}')
-`
-}
-
-function genStyle (name, isPage, src) {
- const prefix = isPage ? getPathPrefix(src) : './'
- return `@import "${prefix}static/css/${name}.wxss";`
-}
-
function genPageWxml (templateName, src) {
- return ``
+ return ``
}
-module.exports = { genScript, genStyle, genPageWxml }
+module.exports = { genPageWxml }
diff --git a/lib/mp-compiler/util.js b/lib/mp-compiler/util.js
index 657cd1f..4bfeb42 100644
--- a/lib/mp-compiler/util.js
+++ b/lib/mp-compiler/util.js
@@ -1,5 +1,6 @@
const path = require('path')
const fs = require('fs')
+const relative = require('../utils/relative')
const pagesNameMap = Object.create(null)
@@ -15,14 +16,22 @@ function getFileInfo (resourcePath) {
// TODO: 调试时取个全名
var hash = require('hash-sum')
const cache = Object.create(null)
-function getCompNameBySrc (file) {
- return cache[file] || (cache[file] = `${getNameByFile(file)}$${hash(file)}`)
+function getCompNameAndSrc (context, file) {
+ const filePath = `${relative(context, file).replace(/^src\//, '')}.wxml`
+ if (!cache[file]) {
+ cache[file] = hash(file)
+ }
+ return {
+ filePath,
+ name: cache[file]
+ }
}
// 根据路径获得组件名
function getNameByFile (dir) {
// const arr = dir.match(/[pages?/components?]\/(.*?)(\/)/)
const arr = dir.match(/pages\/(.*?)\//)
+ // 兼容 win 下的路径格式不统一的问题
if (arr && arr[1]) {
return arr[1]
}
@@ -31,7 +40,7 @@ function getNameByFile (dir) {
function getKeyFromObjByVal (obj, val) {
for (const i in obj) {
- if (obj[i] === val) {
+ if (path.resolve(obj[i]) === path.resolve(val)) {
return i
}
}
@@ -138,7 +147,7 @@ module.exports = {
defaultStylePart,
cacheFileInfo,
getFileInfo,
- getCompNameBySrc,
+ getCompNameAndSrc,
resolveTarget,
covertCCVar,
cacheSlots,
diff --git a/lib/template-compiler/index.js b/lib/template-compiler/index.js
index f45bd47..02651bd 100644
--- a/lib/template-compiler/index.js
+++ b/lib/template-compiler/index.js
@@ -19,7 +19,8 @@ module.exports = function (html) {
var defaultModules = [transformRequire(options.transformToRequire, {
outputPath: this.options.output.path,
- resourcePath: this.resourcePath
+ resourcePath: this.resourcePath,
+ context: this.options.context
})]
var userModules = vueOptions.compilerModules || options.compilerModules
diff --git a/lib/template-compiler/modules/transform-require.js b/lib/template-compiler/modules/transform-require.js
index b144265..960d72f 100644
--- a/lib/template-compiler/modules/transform-require.js
+++ b/lib/template-compiler/modules/transform-require.js
@@ -3,6 +3,7 @@
var fs = require('fs')
var path = require('path')
var mkdirp = require('mkdirp')
+var relative = require('../../utils/relative')
var defaultOptions = {
img: 'src',
@@ -39,12 +40,12 @@ function rewrite (attrsMap, name, fileOptions) {
if (value) {
var firstChar = value.charAt(0)
if (firstChar === '.') {
- // 资源路径
- var assetPath = path.resolve(path.dirname(fileOptions.resourcePath), value)
- // 重写路径,为了避免重名,在webpack输出目录下新建copy-asset目录,资源保存到这里
- var assetOutputPath = path.join('copy-asset', path.relative(process.cwd(), assetPath).replace(/^src/, ''))
- attrsMap[name] = `/${assetOutputPath.split(path.sep).join('/')}`
- copyAsset(assetPath, path.resolve(fileOptions.outputPath, assetOutputPath))
+ var { resourcePath, outputPath, context } = fileOptions
+ var assetPath = path.resolve(resourcePath, '..', value)
+ // 资源路径, 为了分包,去掉了 src 目录
+ var toPath = relative(context, assetPath).replace(/^\/src\//, '')
+ attrsMap[name] = path.join(outputPath, toPath)
+ copyAsset(assetPath, attrsMap[name])
}
}
}
diff --git a/lib/utils/relative.js b/lib/utils/relative.js
new file mode 100644
index 0000000..f68aed4
--- /dev/null
+++ b/lib/utils/relative.js
@@ -0,0 +1,6 @@
+const relative = require('relative')
+const upath = require('upath')
+
+module.exports = function (...arv) {
+ return upath.normalize(relative(...arv))
+}
diff --git a/package.json b/package.json
index e5c5efc..5db4bf6 100644
--- a/package.json
+++ b/package.json
@@ -1,6 +1,6 @@
{
"name": "mpvue-loader",
- "version": "1.0.15",
+ "version": "1.1.0",
"description": "mpvue single-file component loader for Webpack",
"main": "index.js",
"repository": {
@@ -60,8 +60,10 @@
"postcss": "^6.0.6",
"postcss-load-config": "^1.1.0",
"postcss-selector-parser": "^2.0.0",
+ "relative": "^3.0.2",
"resolve": "^1.3.3",
"source-map": "^0.5.6",
+ "upath": "^1.1.0",
"vue-hot-reload-api": "^2.1.0",
"vue-loader": "^13.0.4",
"vue-style-loader": "^3.0.0",