From 033f7d47b849a8d9800736771f1737caf802220d Mon Sep 17 00:00:00 2001 From: linrui Date: Sun, 29 Apr 2018 20:29:16 +0800 Subject: [PATCH 01/13] =?UTF-8?q?=E4=BF=AE=E5=A4=8D=E6=97=A0=E6=B3=95?= =?UTF-8?q?=E5=BC=95=E5=85=A5=E7=9B=B8=E5=AF=B9=E8=B7=AF=E5=BE=84=E8=B5=84?= =?UTF-8?q?=E6=BA=90=E7=9A=84bug?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- lib/template-compiler/index.js | 5 ++- .../modules/transform-require.js | 39 +++++++++++++------ 2 files changed, 31 insertions(+), 13 deletions(-) diff --git a/lib/template-compiler/index.js b/lib/template-compiler/index.js index 9dfacd8..3f0ba06 100644 --- a/lib/template-compiler/index.js +++ b/lib/template-compiler/index.js @@ -16,7 +16,10 @@ module.exports = function (html) { var vueOptions = this.options.__vueOptions__ || {} var options = loaderUtils.getOptions(this) || {} - var defaultModules = [transformRequire(options.transformToRequire)] + var defaultModules = [transformRequire(options.transformToRequire, { + outputPath: this.options.output.path, + resourcePath: this.resourcePath + })] var userModules = vueOptions.compilerModules || options.compilerModules // for HappyPack cross-process use cases if (typeof userModules === 'string') { diff --git a/lib/template-compiler/modules/transform-require.js b/lib/template-compiler/modules/transform-require.js index 7d9be15..788f3a1 100644 --- a/lib/template-compiler/modules/transform-require.js +++ b/lib/template-compiler/modules/transform-require.js @@ -1,36 +1,40 @@ // vue compiler module for transforming `:` to `require` +var fs = require('fs') +var path = require('path') +var mkdirp = require('mkdirp') + var defaultOptions = { img: 'src', image: 'xlink:href' } -module.exports = userOptions => { +module.exports = (userOptions, fileOptions) => { var options = userOptions ? Object.assign({}, defaultOptions, userOptions) : defaultOptions return { postTransformNode: node => { - transform(node, options) + transform(node, options, fileOptions) } } } -function transform (node, options) { +function transform (node, options, fileOptions) { for (var tag in options) { if (node.tag === tag && node.attrs) { var attributes = options[tag] if (typeof attributes === 'string') { - node.attrs.some(attr => rewrite(attr, attributes)) + node.attrs.some(attr => rewrite(attr, node.attrsMap, attributes, fileOptions)) } else if (Array.isArray(attributes)) { - attributes.forEach(item => node.attrs.some(attr => rewrite(attr, item))) + attributes.forEach(item => node.attrs.some(attr => rewrite(attr, node.attrsMap, item, fileOptions))) } } } } -function rewrite (attr, name) { +function rewrite (attr, attrsMap, name, fileOptions) { if (attr.name === name) { var value = attr.value var isStatic = value.charAt(0) === '"' && value.charAt(value.length - 1) === '"' @@ -38,13 +42,24 @@ function rewrite (attr, name) { return } var firstChar = value.charAt(1) - if (firstChar === '.' || firstChar === '~') { - if (firstChar === '~') { - var secondChar = value.charAt(2) - value = '"' + value.slice(secondChar === '/' ? 3 : 2) - } - attr.value = `require(${value})` + if (firstChar === '.') { + // 资源路径 + var assetPath = path.join(path.dirname(fileOptions.resourcePath), value.slice(1, -1)) + // 重写路径,为了避免重名,在webpack输出目录下新建copy-asset目录,资源保存到这里 + var assetOutputPath = path.join('copy-asset', path.relative(process.cwd(), assetPath).replace(/^src/, '')) + attrsMap[name] = `/${assetOutputPath}` + // 拷贝资源 + copyAsset(assetPath, path.resolve(fileOptions.outputPath, assetOutputPath)) } return true } } + +function copyAsset (from, to) { + var readStream = fs.createReadStream(from) + mkdirp(path.dirname(to), err => { + if (err) console.error(err) + var writeStream = fs.createWriteStream(to) + readStream.pipe(writeStream) + }) +} From 9409b863320e40182d5fc53f97c385c87d53ebbd Mon Sep 17 00:00:00 2001 From: linrui Date: Mon, 30 Apr 2018 12:18:54 +0800 Subject: [PATCH 02/13] =?UTF-8?q?=E6=B7=BB=E5=8A=A0=E5=AF=B9base64?= =?UTF-8?q?=E7=9A=84=E6=94=AF=E6=8C=81?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- .../modules/transform-require.js | 49 ++++++++++++------- package.json | 5 +- 2 files changed, 34 insertions(+), 20 deletions(-) diff --git a/lib/template-compiler/modules/transform-require.js b/lib/template-compiler/modules/transform-require.js index 788f3a1..1059211 100644 --- a/lib/template-compiler/modules/transform-require.js +++ b/lib/template-compiler/modules/transform-require.js @@ -3,10 +3,12 @@ var fs = require('fs') var path = require('path') var mkdirp = require('mkdirp') +var mime = require('mime') var defaultOptions = { img: 'src', - image: 'xlink:href' + image: 'xlink:href', + limit: 10 * 1024 } module.exports = (userOptions, fileOptions) => { @@ -26,32 +28,43 @@ function transform (node, options, fileOptions) { if (node.tag === tag && node.attrs) { var attributes = options[tag] if (typeof attributes === 'string') { - node.attrs.some(attr => rewrite(attr, node.attrsMap, attributes, fileOptions)) + rewrite(node.attrsMap, attributes, fileOptions, options.limit) } else if (Array.isArray(attributes)) { - attributes.forEach(item => node.attrs.some(attr => rewrite(attr, node.attrsMap, item, fileOptions))) + attributes.forEach(item => rewrite(node.attrsMap, item, fileOptions, options.limit)) } } } } -function rewrite (attr, attrsMap, name, fileOptions) { - if (attr.name === name) { - var value = attr.value - var isStatic = value.charAt(0) === '"' && value.charAt(value.length - 1) === '"' - if (!isStatic) { - return - } - var firstChar = value.charAt(1) +function rewrite (attrsMap, name, fileOptions, limit) { + var value = attrsMap[name] + if (value) { + var firstChar = value.charAt(0) if (firstChar === '.') { // 资源路径 - var assetPath = path.join(path.dirname(fileOptions.resourcePath), value.slice(1, -1)) - // 重写路径,为了避免重名,在webpack输出目录下新建copy-asset目录,资源保存到这里 - var assetOutputPath = path.join('copy-asset', path.relative(process.cwd(), assetPath).replace(/^src/, '')) - attrsMap[name] = `/${assetOutputPath}` - // 拷贝资源 - copyAsset(assetPath, path.resolve(fileOptions.outputPath, assetOutputPath)) + var assetPath = path.join(path.dirname(fileOptions.resourcePath), value) + // 小于limit的资源转base64 + var str = assetToBase64(assetPath, limit) + if (str) { + attrsMap[name] = `data:${mime.getType(assetPath) || ''};base64,${str}` + } else { + // 重写路径,为了避免重名,在webpack输出目录下新建copy-asset目录,资源保存到这里 + var assetOutputPath = path.join('copy-asset', path.relative(process.cwd(), assetPath).replace(/^src/, '')) + attrsMap[name] = `/${assetOutputPath}` + copyAsset(assetPath, path.resolve(fileOptions.outputPath, assetOutputPath)) + } + } + } +} + +function assetToBase64 (assetPath, limit) { + try { + var buffer = fs.readFileSync(assetPath) + if (buffer.length <= limit) { + return buffer.toString('base64') } - return true + } catch (err) { + console.error('ReadFile Error:' + err) } } diff --git a/package.json b/package.json index af1fc8d..d8890bf 100644 --- a/package.json +++ b/package.json @@ -55,6 +55,8 @@ "js-beautify": "^1.6.14", "loader-utils": "^1.1.0", "lru-cache": "^4.1.1", + "mime": "^2.3.1", + "mkdirp": "^0.5.1", "postcss": "^6.0.6", "postcss-load-config": "^1.1.0", "postcss-selector-parser": "^2.0.0", @@ -89,9 +91,8 @@ "lint-staged": "^4.0.2", "marked": "^0.3.6", "memory-fs": "^0.4.1", - "mkdirp": "^0.5.1", - "mpvue-template-compiler": "^1.0.10", "mocha": "^3.4.2", + "mpvue-template-compiler": "^1.0.10", "node-libs-browser": "^2.0.0", "normalize-newline": "^3.0.0", "null-loader": "^0.1.1", From 9714887213c343936b679bd8102d697d416ab5b1 Mon Sep 17 00:00:00 2001 From: linrui Date: Tue, 1 May 2018 21:55:19 +0800 Subject: [PATCH 03/13] =?UTF-8?q?feature:=E6=96=B0=E5=A2=9E=E5=85=A8?= =?UTF-8?q?=E5=B1=80=E7=BB=84=E4=BB=B6=E5=8A=9F=E8=83=BD?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- lib/mp-compiler/index.js | 109 ++++++++++++++++++++++++++++----------- lib/mp-compiler/parse.js | 32 +++++++++++- package.json | 1 + 3 files changed, 112 insertions(+), 30 deletions(-) diff --git a/lib/mp-compiler/index.js b/lib/mp-compiler/index.js index d714eba..afd30b4 100644 --- a/lib/mp-compiler/index.js +++ b/lib/mp-compiler/index.js @@ -4,8 +4,9 @@ const compiler = require('mpvue-template-compiler') const babel = require('babel-core') const path = require('path') const fs = require('fs') +const deepEqual = require('deep-equal') -const { parseConfig, parseComponentsDeps } = require('./parse') +const { parseConfig, parseComponentsDeps, parseGlobalComponents, clearGlobalComponents } = require('./parse') const { parseComponentsDeps: parseComponentsDepsTs } = require('./parse-ts') const { genScript, genStyle, genPageWxml } = require('./templates') @@ -62,7 +63,11 @@ function genComponentWxml (compiled, options, emitFile, emitError, emitWarning) return htmlBeautify(wxmlCodeStr) } +// 更新全局组件时,需要重新生成wxml,用这个字段保存所有需要更新的页面及其参数 +const cacheCreateWxmlFns = {} + function createWxml (emitWarning, emitError, emitFile, resourcePath, rootComponent, compiled, html) { + cacheCreateWxmlFns[resourcePath] = arguments const { pageType, moduleId, components, src } = getFileInfo(resourcePath) || {} // 这儿一个黑魔法,和 webpack 约定的规范写法有点偏差! @@ -124,33 +129,18 @@ function compileMPScript (script, mpOptioins, moduleId) { // 处理子组件的信息 const components = {} + const fileInfo = resolveTarget(this.resourcePath, this.options.entry) if (originComponents) { - const allP = Object.keys(originComponents).map(k => { - return new Promise((resolve, reject) => { - this.resolve(this.context, originComponents[k], (err, realSrc) => { - if (err) return reject(err) - const com = covertCCVar(k) - const comName = getCompNameBySrc(realSrc) - components[com] = { src: comName, name: comName } - resolve() - }) - }) + resolveSrc(originComponents, components, this.resolve, this.context).then(() => { + resolveComponent(this.resourcePath, fileInfo, importsMap, components, moduleId) + }).catch(err => { + console.error(err) + resolveComponent(this.resourcePath, fileInfo, importsMap, components, moduleId) }) - Promise.all(allP) - .then(res => { - components.isCompleted = true - }) - .catch(err => { - console.error(err) - components.isCompleted = true - }) } else { - components.isCompleted = true + resolveComponent(this.resourcePath, fileInfo, importsMap, components, moduleId) } - const fileInfo = resolveTarget(this.resourcePath, this.options.entry) - cacheFileInfo(this.resourcePath, fileInfo, { importsMap, components, moduleId }) - return script } @@ -158,19 +148,52 @@ function compileMPScript (script, mpOptioins, moduleId) { // 编译出 app, page 的入口js/wxml/json const startPageReg = /^\^/ - +let globalComponents function compileMP (content, mpOptioins) { const { resourcePath, emitError, emitFile, emitWarning, resolve, context, options } = this + const fileInfo = resolveTarget(resourcePath, options.entry) + cacheFileInfo(resourcePath, fileInfo) + const { src, name, isApp, isPage } = fileInfo + const babelrc = getBabelrc(mpOptioins.globalBabelrc) - const { metadata } = babel.transform(content, { extends: babelrc, plugins: [parseConfig] }) + // app入口进行全局component解析 + const { metadata } = babel.transform(content, { extends: babelrc, plugins: isApp ? [parseConfig, parseGlobalComponents] : [parseConfig] }) // metadata: config - const { config, rootComponent } = metadata + const { config, rootComponent, globalComponents: globalComps } = metadata + + if (isApp) { + // 保存旧数据,用于对比 + const oldGlobalComponents = globalComponents + // 开始解析app入口文件时把全局组件清空,解析完成后再进行赋值,标志全局组件解析完成 + globalComponents = null + clearGlobalComponents() + + const handleResult = () => { + globalComponents = components + // 热更时,如果全局组件更新,需要重新生成所有的wxml + if (oldGlobalComponents && !deepEqual(oldGlobalComponents, globalComponents)) { + // 更新所有页面的组件 + Object.keys(cacheResolveComponents).forEach(k => { + resolveComponent(...cacheResolveComponents[k]) + }) + // 重新生成所有wxml + Object.keys(cacheCreateWxmlFns).forEach(k => { + createWxml(...cacheCreateWxmlFns[k]) + }) + } + } - const fileInfo = resolveTarget(resourcePath, options.entry) - cacheFileInfo(resourcePath, fileInfo) - const { src, name, isApp, isPage } = fileInfo + // 解析全局组件的路径 + const components = {} + resolveSrc(globalComps, components, resolve, context).then(() => { + handleResult() + }).catch(err => { + console.error(err) + handleResult() + }) + } if (isApp || isPage) { // 生成入口 json @@ -213,4 +236,32 @@ function compileMP (content, mpOptioins) { return content } +function resolveSrc (originComponents, components, resolveFn, context) { + return Promise.all(Object.keys(originComponents).map(k => { + return new Promise((resolve, reject) => { + 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 } + resolve() + }) + }) + })) +} + +const cacheResolveComponents = {} +function resolveComponent (resourcePath, fileInfo, importsMap, localComponents, moduleId) { + // 需要等待全局组件解析完成 + if (!globalComponents) { + setTimeout(resolveComponent, 20, ...arguments) + } else { + // 保存当前所有参数,在热更时如果全局组件发生变化,需要进行组件更新 + cacheResolveComponents[resourcePath] = arguments + const components = Object.assign({}, globalComponents, localComponents) + components.isCompleted = true + cacheFileInfo(resourcePath, fileInfo, { importsMap, components, moduleId }) + } +} + module.exports = { compileWxml, compileMPScript, compileMP } diff --git a/lib/mp-compiler/parse.js b/lib/mp-compiler/parse.js index 5301542..8c5901a 100644 --- a/lib/mp-compiler/parse.js +++ b/lib/mp-compiler/parse.js @@ -98,4 +98,34 @@ function parseComponentsDeps (babel) { return { visitor: componentsVisitor } } -module.exports = { parseConfig, parseComponentsDeps } +// 解析全局components +let globalComponents = {} +const globalComponentsVisitor = { + CallExpression (path) { + const { callee, arguments: args } = path.node + const { metadata } = path.hub.file + if (!callee.object || !callee.property) { + return + } + if (callee.object.name === 'Vue' && callee.property.name === 'component') { + if (!args[0] || args[0].type !== 'StringLiteral') { + throw new Error('Vue.component()的第一个参数必须为静态字符串') + } + if (!args[1]) { + throw new Error('Vue.component()需要两个参数') + } + const { importsMap } = getImportsMap(metadata) + globalComponents[args[0].value] = importsMap[args[1].name] + } + metadata.globalComponents = globalComponents + } +} + +function parseGlobalComponents (babel) { + return { visitor: globalComponentsVisitor } +} + +function clearGlobalComponents () { + globalComponents = {} +} +module.exports = { parseConfig, parseComponentsDeps, parseGlobalComponents, clearGlobalComponents } diff --git a/package.json b/package.json index dc82f46..2ed3fc2 100644 --- a/package.json +++ b/package.json @@ -51,6 +51,7 @@ "dependencies": { "babelon": "^1.0.5", "consolidate": "^0.14.0", + "deep-equal": "^1.0.1", "hash-sum": "^1.0.2", "js-beautify": "^1.6.14", "loader-utils": "^1.1.0", From 9cae1dffd5be119c7607d306e642bbdc24b85795 Mon Sep 17 00:00:00 2001 From: linrui Date: Wed, 2 May 2018 10:07:12 +0800 Subject: [PATCH 04/13] =?UTF-8?q?=E4=BF=AE=E6=94=B9=E6=B3=A8=E9=87=8A?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- lib/mp-compiler/index.js | 26 ++++++++++++++------------ 1 file changed, 14 insertions(+), 12 deletions(-) diff --git a/lib/mp-compiler/index.js b/lib/mp-compiler/index.js index afd30b4..7d991c0 100644 --- a/lib/mp-compiler/index.js +++ b/lib/mp-compiler/index.js @@ -155,6 +155,10 @@ function compileMP (content, mpOptioins) { const fileInfo = resolveTarget(resourcePath, options.entry) cacheFileInfo(resourcePath, fileInfo) const { src, name, isApp, isPage } = fileInfo + if (isApp) { + // 解析前将可能存在的全局组件清空 + clearGlobalComponents() + } const babelrc = getBabelrc(mpOptioins.globalBabelrc) // app入口进行全局component解析 @@ -166,11 +170,18 @@ function compileMP (content, mpOptioins) { if (isApp) { // 保存旧数据,用于对比 const oldGlobalComponents = globalComponents - // 开始解析app入口文件时把全局组件清空,解析完成后再进行赋值,标志全局组件解析完成 + // 开始解析组件路径时把全局组件清空,解析完成后再进行赋值,标志全局组件解析完成 globalComponents = null - clearGlobalComponents() - const handleResult = () => { + // 解析全局组件的路径 + const components = {} + resolveSrc(globalComps, components, resolve, context).then(() => { + handleResult(components) + }).catch(err => { + console.error(err) + handleResult(components) + }) + const handleResult = components => { globalComponents = components // 热更时,如果全局组件更新,需要重新生成所有的wxml if (oldGlobalComponents && !deepEqual(oldGlobalComponents, globalComponents)) { @@ -184,15 +195,6 @@ function compileMP (content, mpOptioins) { }) } } - - // 解析全局组件的路径 - const components = {} - resolveSrc(globalComps, components, resolve, context).then(() => { - handleResult() - }).catch(err => { - console.error(err) - handleResult() - }) } if (isApp || isPage) { From aeedf75169e37ffe3abb0f8cdd8ffe50c95bbc97 Mon Sep 17 00:00:00 2001 From: null <6347990+aOrz@users.noreply.github.com> Date: Fri, 4 May 2018 22:02:47 +0800 Subject: [PATCH 05/13] =?UTF-8?q?Revert=20"=E4=BF=AE=E5=A4=8D=E6=97=A0?= =?UTF-8?q?=E6=B3=95=E5=BC=95=E5=85=A5=E7=9B=B8=E5=AF=B9=E8=B7=AF=E5=BE=84?= =?UTF-8?q?=E8=B5=84=E6=BA=90=E7=9A=84bug"?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- lib/template-compiler/index.js | 5 +- .../modules/transform-require.js | 68 ++++++------------- package.json | 9 ++- 3 files changed, 25 insertions(+), 57 deletions(-) diff --git a/lib/template-compiler/index.js b/lib/template-compiler/index.js index 3f0ba06..9dfacd8 100644 --- a/lib/template-compiler/index.js +++ b/lib/template-compiler/index.js @@ -16,10 +16,7 @@ module.exports = function (html) { var vueOptions = this.options.__vueOptions__ || {} var options = loaderUtils.getOptions(this) || {} - var defaultModules = [transformRequire(options.transformToRequire, { - outputPath: this.options.output.path, - resourcePath: this.resourcePath - })] + var defaultModules = [transformRequire(options.transformToRequire)] var userModules = vueOptions.compilerModules || options.compilerModules // for HappyPack cross-process use cases if (typeof userModules === 'string') { diff --git a/lib/template-compiler/modules/transform-require.js b/lib/template-compiler/modules/transform-require.js index 1059211..7d9be15 100644 --- a/lib/template-compiler/modules/transform-require.js +++ b/lib/template-compiler/modules/transform-require.js @@ -1,78 +1,50 @@ // vue compiler module for transforming `:` to `require` -var fs = require('fs') -var path = require('path') -var mkdirp = require('mkdirp') -var mime = require('mime') - var defaultOptions = { img: 'src', - image: 'xlink:href', - limit: 10 * 1024 + image: 'xlink:href' } -module.exports = (userOptions, fileOptions) => { +module.exports = userOptions => { var options = userOptions ? Object.assign({}, defaultOptions, userOptions) : defaultOptions return { postTransformNode: node => { - transform(node, options, fileOptions) + transform(node, options) } } } -function transform (node, options, fileOptions) { +function transform (node, options) { for (var tag in options) { if (node.tag === tag && node.attrs) { var attributes = options[tag] if (typeof attributes === 'string') { - rewrite(node.attrsMap, attributes, fileOptions, options.limit) + node.attrs.some(attr => rewrite(attr, attributes)) } else if (Array.isArray(attributes)) { - attributes.forEach(item => rewrite(node.attrsMap, item, fileOptions, options.limit)) + attributes.forEach(item => node.attrs.some(attr => rewrite(attr, item))) } } } } -function rewrite (attrsMap, name, fileOptions, limit) { - var value = attrsMap[name] - if (value) { - var firstChar = value.charAt(0) - if (firstChar === '.') { - // 资源路径 - var assetPath = path.join(path.dirname(fileOptions.resourcePath), value) - // 小于limit的资源转base64 - var str = assetToBase64(assetPath, limit) - if (str) { - attrsMap[name] = `data:${mime.getType(assetPath) || ''};base64,${str}` - } else { - // 重写路径,为了避免重名,在webpack输出目录下新建copy-asset目录,资源保存到这里 - var assetOutputPath = path.join('copy-asset', path.relative(process.cwd(), assetPath).replace(/^src/, '')) - attrsMap[name] = `/${assetOutputPath}` - copyAsset(assetPath, path.resolve(fileOptions.outputPath, assetOutputPath)) - } +function rewrite (attr, name) { + if (attr.name === name) { + var value = attr.value + var isStatic = value.charAt(0) === '"' && value.charAt(value.length - 1) === '"' + if (!isStatic) { + return } - } -} - -function assetToBase64 (assetPath, limit) { - try { - var buffer = fs.readFileSync(assetPath) - if (buffer.length <= limit) { - return buffer.toString('base64') + var firstChar = value.charAt(1) + if (firstChar === '.' || firstChar === '~') { + if (firstChar === '~') { + var secondChar = value.charAt(2) + value = '"' + value.slice(secondChar === '/' ? 3 : 2) + } + attr.value = `require(${value})` } - } catch (err) { - console.error('ReadFile Error:' + err) + return true } } - -function copyAsset (from, to) { - var readStream = fs.createReadStream(from) - mkdirp(path.dirname(to), err => { - if (err) console.error(err) - var writeStream = fs.createWriteStream(to) - readStream.pipe(writeStream) - }) -} diff --git a/package.json b/package.json index d482165..2ed3fc2 100644 --- a/package.json +++ b/package.json @@ -1,6 +1,6 @@ { "name": "mpvue-loader", - "version": "1.0.13", + "version": "1.0.11", "description": "mpvue single-file component loader for Webpack", "main": "index.js", "repository": { @@ -56,8 +56,6 @@ "js-beautify": "^1.6.14", "loader-utils": "^1.1.0", "lru-cache": "^4.1.1", - "mime": "^2.3.1", - "mkdirp": "^0.5.1", "postcss": "^6.0.6", "postcss-load-config": "^1.1.0", "postcss-selector-parser": "^2.0.0", @@ -70,7 +68,7 @@ }, "peerDependencies": { "css-loader": "*", - "mpvue-template-compiler": "^1.0.10" + "mpvue-template-compiler": "^1.0.7" }, "devDependencies": { "babel-core": "^6.25.0", @@ -92,8 +90,9 @@ "lint-staged": "^4.0.2", "marked": "^0.3.6", "memory-fs": "^0.4.1", + "mkdirp": "^0.5.1", + "mpvue-template-compiler": "^1.0.7", "mocha": "^3.4.2", - "mpvue-template-compiler": "^1.0.10", "node-libs-browser": "^2.0.0", "normalize-newline": "^3.0.0", "null-loader": "^0.1.1", From eb58129eb6326cb866b9f9a93a9abdd123927a93 Mon Sep 17 00:00:00 2001 From: linrui Date: Sat, 5 May 2018 17:34:54 +0800 Subject: [PATCH 06/13] =?UTF-8?q?=E4=BF=AE=E5=A4=8D=E7=9B=B8=E5=AF=B9?= =?UTF-8?q?=E8=B7=AF=E5=BE=84=E8=B5=84=E6=BA=90=E6=97=A0=E6=B3=95=E6=AD=A3?= =?UTF-8?q?=E5=B8=B8=E5=BC=95=E5=85=A5=E7=9A=84bug?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- lib/template-compiler/index.js | 6 +- .../modules/transform-require.js | 70 +++++++++++++------ package.json | 5 +- 3 files changed, 57 insertions(+), 24 deletions(-) diff --git a/lib/template-compiler/index.js b/lib/template-compiler/index.js index 9dfacd8..bd993b9 100644 --- a/lib/template-compiler/index.js +++ b/lib/template-compiler/index.js @@ -16,7 +16,11 @@ module.exports = function (html) { var vueOptions = this.options.__vueOptions__ || {} var options = loaderUtils.getOptions(this) || {} - var defaultModules = [transformRequire(options.transformToRequire)] + var defaultModules = [transformRequire(options.transformToRequire, { + outputPath: this.options.output.path, + resourcePath: this.resourcePath + })] + var userModules = vueOptions.compilerModules || options.compilerModules // for HappyPack cross-process use cases if (typeof userModules === 'string') { diff --git a/lib/template-compiler/modules/transform-require.js b/lib/template-compiler/modules/transform-require.js index 7d9be15..80848f6 100644 --- a/lib/template-compiler/modules/transform-require.js +++ b/lib/template-compiler/modules/transform-require.js @@ -1,50 +1,78 @@ // vue compiler module for transforming `:` to `require` +var fs = require('fs') +var path = require('path') +var mkdirp = require('mkdirp') +var mime = require('mime') + var defaultOptions = { img: 'src', - image: 'xlink:href' + image: 'xlink:href', + limit: 10 * 1024 } -module.exports = userOptions => { +module.exports = (userOptions, fileOptions) => { var options = userOptions ? Object.assign({}, defaultOptions, userOptions) : defaultOptions return { postTransformNode: node => { - transform(node, options) + transform(node, options, fileOptions) } } } -function transform (node, options) { +function transform (node, options, fileOptions) { for (var tag in options) { - if (node.tag === tag && node.attrs) { + if (tag !== 'limit' && node.tag === tag && node.attrs) { var attributes = options[tag] if (typeof attributes === 'string') { - node.attrs.some(attr => rewrite(attr, attributes)) + rewrite(node.attrsMap, attributes, fileOptions, options.limit) } else if (Array.isArray(attributes)) { - attributes.forEach(item => node.attrs.some(attr => rewrite(attr, item))) + attributes.forEach(item => rewrite(node.attrsMap, item, fileOptions, options.limit)) } } } } -function rewrite (attr, name) { - if (attr.name === name) { - var value = attr.value - var isStatic = value.charAt(0) === '"' && value.charAt(value.length - 1) === '"' - if (!isStatic) { - return - } - var firstChar = value.charAt(1) - if (firstChar === '.' || firstChar === '~') { - if (firstChar === '~') { - var secondChar = value.charAt(2) - value = '"' + value.slice(secondChar === '/' ? 3 : 2) +function rewrite (attrsMap, name, fileOptions, limit) { + var value = attrsMap[name] + if (value) { + var firstChar = value.charAt(0) + if (firstChar === '.') { + // 资源路径 + var assetPath = path.resolve(path.dirname(fileOptions.resourcePath), value) + // 小于limit的资源转base64 + var str = assetToBase64(assetPath, limit) + if (str) { + attrsMap[name] = `data:${mime.getType(assetPath) || ''};base64,${str}` + } else { + // 重写路径,为了避免重名,在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)) } - attr.value = `require(${value})` } - return true } } + +function assetToBase64 (assetPath, limit) { + try { + var buffer = fs.readFileSync(assetPath) + if (buffer.length <= limit) { + return buffer.toString('base64') + } + } catch (err) { + console.error('ReadFile Error:' + err) + } +} + +function copyAsset (from, to) { + var readStream = fs.createReadStream(from) + mkdirp(path.dirname(to), err => { + if (err) console.error(err) + var writeStream = fs.createWriteStream(to) + readStream.pipe(writeStream) + }) +} diff --git a/package.json b/package.json index 2ed3fc2..23f2425 100644 --- a/package.json +++ b/package.json @@ -56,6 +56,8 @@ "js-beautify": "^1.6.14", "loader-utils": "^1.1.0", "lru-cache": "^4.1.1", + "mime": "^2.3.1", + "mkdirp": "^0.5.1", "postcss": "^6.0.6", "postcss-load-config": "^1.1.0", "postcss-selector-parser": "^2.0.0", @@ -90,9 +92,8 @@ "lint-staged": "^4.0.2", "marked": "^0.3.6", "memory-fs": "^0.4.1", - "mkdirp": "^0.5.1", - "mpvue-template-compiler": "^1.0.7", "mocha": "^3.4.2", + "mpvue-template-compiler": "^1.0.7", "node-libs-browser": "^2.0.0", "normalize-newline": "^3.0.0", "null-loader": "^0.1.1", From bc2a88d7be4b6de221604eca24f884f3054e9d3c Mon Sep 17 00:00:00 2001 From: F-loat <945852046@qq.com> Date: Sun, 6 May 2018 13:23:37 +0800 Subject: [PATCH 07/13] =?UTF-8?q?fix:=20=E4=BF=AE=E5=A4=8D=20new=20Vue=20?= =?UTF-8?q?=E8=A7=A3=E6=9E=90=E9=94=99=E8=AF=AF?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- lib/mp-compiler/parse.js | 5 +++++ 1 file changed, 5 insertions(+) diff --git a/lib/mp-compiler/parse.js b/lib/mp-compiler/parse.js index 8c5901a..c15cd7e 100644 --- a/lib/mp-compiler/parse.js +++ b/lib/mp-compiler/parse.js @@ -55,6 +55,11 @@ const configVisitor = { } const arg = path.node.arguments[0] + + if (!arg) { + return + } + const v = arg.type === 'Identifier' ? importsMap[arg.name] : importsMap['App'] metadata.rootComponent = v || importsMap['index'] || importsMap['main'] } From 61183b10cb2be0908aebae16ea87e943e8b772e5 Mon Sep 17 00:00:00 2001 From: Wing Gao Date: Tue, 8 May 2018 13:53:19 +0800 Subject: [PATCH 08/13] =?UTF-8?q?=E6=B7=BB=E5=8A=A0TS=E5=A4=84=E7=90=86as?= =?UTF-8?q?=E7=9A=84=E6=83=85=E5=86=B5=20https://github.com/WingGao/mpvue-?= =?UTF-8?q?ts-demo/issues/7?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- lib/mp-compiler/parse-ts.js | 7 +++++-- 1 file changed, 5 insertions(+), 2 deletions(-) diff --git a/lib/mp-compiler/parse-ts.js b/lib/mp-compiler/parse-ts.js index 5792a1f..aaa1ab1 100644 --- a/lib/mp-compiler/parse-ts.js +++ b/lib/mp-compiler/parse-ts.js @@ -2,7 +2,7 @@ let ts try { ts = require('typescript') } catch (e) { - + // console.error(e) } function parseComponentsDeps (scriptContent) { @@ -21,7 +21,10 @@ function delint (sourceFile) { if (node.expression.expression && node.expression.expression.escapedText === 'Component') { const compArgs = node.expression.arguments if (compArgs && compArgs.length === 1) { - const vueClassArg = compArgs[0] + let vueClassArg = compArgs[0] + if(vueClassArg.kind == ts.SyntaxKind.AsExpression) { // @Component({ components: ...,} as any) + vueClassArg = vueClassArg.expression + } if (vueClassArg.properties) { vueClassArg.properties.forEach((classProp) => { // 处理components属性 From 69b30bd2126f24177ca34bd07bbea468cae94aa9 Mon Sep 17 00:00:00 2001 From: Wing Gao Date: Tue, 8 May 2018 14:19:49 +0800 Subject: [PATCH 09/13] lint --- lib/mp-compiler/parse-ts.js | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/lib/mp-compiler/parse-ts.js b/lib/mp-compiler/parse-ts.js index aaa1ab1..feeba27 100644 --- a/lib/mp-compiler/parse-ts.js +++ b/lib/mp-compiler/parse-ts.js @@ -22,7 +22,7 @@ function delint (sourceFile) { const compArgs = node.expression.arguments if (compArgs && compArgs.length === 1) { let vueClassArg = compArgs[0] - if(vueClassArg.kind == ts.SyntaxKind.AsExpression) { // @Component({ components: ...,} as any) + if (vueClassArg.kind === ts.SyntaxKind.AsExpression) { // @Component({ components: ...,} as any) vueClassArg = vueClassArg.expression } if (vueClassArg.properties) { From e3f48432fdb00162d1371d194908e8b496c1faa9 Mon Sep 17 00:00:00 2001 From: Wing Gao Date: Tue, 8 May 2018 15:23:59 +0800 Subject: [PATCH 10/13] =?UTF-8?q?=E6=B7=BB=E5=8A=A0=E9=94=99=E8=AF=AF?= =?UTF-8?q?=E6=8F=90=E7=A4=BA=20https://github.com/Meituan-Dianping/mpvue/?= =?UTF-8?q?issues/425?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- lib/mp-compiler/parse-ts.js | 3 +++ 1 file changed, 3 insertions(+) diff --git a/lib/mp-compiler/parse-ts.js b/lib/mp-compiler/parse-ts.js index feeba27..44acaf4 100644 --- a/lib/mp-compiler/parse-ts.js +++ b/lib/mp-compiler/parse-ts.js @@ -6,6 +6,9 @@ try { } function parseComponentsDeps (scriptContent) { + if (ts === null) { + throw new Error('Please run `npm install -S typescript` to install TypeScript.') + } const sourceFile = ts.createSourceFile('test', scriptContent, ts.ScriptTarget.ESNext, /* setParentNodes */ true) return delint(sourceFile) } From 841235ee4aaa43b5de1ff3eb4da5f08bf677df9c Mon Sep 17 00:00:00 2001 From: linrui Date: Fri, 11 May 2018 11:01:35 +0800 Subject: [PATCH 11/13] drop base64 --- .../modules/transform-require.js | 37 +++++-------------- package.json | 1 - 2 files changed, 9 insertions(+), 29 deletions(-) diff --git a/lib/template-compiler/modules/transform-require.js b/lib/template-compiler/modules/transform-require.js index 80848f6..b144265 100644 --- a/lib/template-compiler/modules/transform-require.js +++ b/lib/template-compiler/modules/transform-require.js @@ -3,12 +3,10 @@ var fs = require('fs') var path = require('path') var mkdirp = require('mkdirp') -var mime = require('mime') var defaultOptions = { img: 'src', - image: 'xlink:href', - limit: 10 * 1024 + image: 'xlink:href' } module.exports = (userOptions, fileOptions) => { @@ -25,46 +23,29 @@ module.exports = (userOptions, fileOptions) => { function transform (node, options, fileOptions) { for (var tag in options) { - if (tag !== 'limit' && node.tag === tag && node.attrs) { + if (node.tag === tag && node.attrs) { var attributes = options[tag] if (typeof attributes === 'string') { - rewrite(node.attrsMap, attributes, fileOptions, options.limit) + rewrite(node.attrsMap, attributes, fileOptions) } else if (Array.isArray(attributes)) { - attributes.forEach(item => rewrite(node.attrsMap, item, fileOptions, options.limit)) + attributes.forEach(item => rewrite(node.attrsMap, item, fileOptions)) } } } } -function rewrite (attrsMap, name, fileOptions, limit) { +function rewrite (attrsMap, name, fileOptions) { var value = attrsMap[name] if (value) { var firstChar = value.charAt(0) if (firstChar === '.') { // 资源路径 var assetPath = path.resolve(path.dirname(fileOptions.resourcePath), value) - // 小于limit的资源转base64 - var str = assetToBase64(assetPath, limit) - if (str) { - attrsMap[name] = `data:${mime.getType(assetPath) || ''};base64,${str}` - } else { - // 重写路径,为了避免重名,在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)) - } - } - } -} - -function assetToBase64 (assetPath, limit) { - try { - var buffer = fs.readFileSync(assetPath) - if (buffer.length <= limit) { - return buffer.toString('base64') + // 重写路径,为了避免重名,在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)) } - } catch (err) { - console.error('ReadFile Error:' + err) } } diff --git a/package.json b/package.json index 23f2425..286c586 100644 --- a/package.json +++ b/package.json @@ -56,7 +56,6 @@ "js-beautify": "^1.6.14", "loader-utils": "^1.1.0", "lru-cache": "^4.1.1", - "mime": "^2.3.1", "mkdirp": "^0.5.1", "postcss": "^6.0.6", "postcss-load-config": "^1.1.0", From 4933275a15d464ce16ce76918fd931ee0160d621 Mon Sep 17 00:00:00 2001 From: JK Date: Wed, 16 May 2018 17:22:36 +0800 Subject: [PATCH 12/13] =?UTF-8?q?refactor:=20=E7=A7=BB=E9=99=A4timeout?= =?UTF-8?q?=E9=AD=94=E6=B3=95=20(#21)?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit * refactor: use async strategy intead of timeout * refactor: remove timeout in createSlotWxml * refactor: use compilation hook to create slots file --- lib/mp-compiler/index.js | 102 +++++++++++++++++---------------- lib/template-compiler/index.js | 98 +++++++++++++++---------------- 2 files changed, 103 insertions(+), 97 deletions(-) diff --git a/lib/mp-compiler/index.js b/lib/mp-compiler/index.js index 7d991c0..345a8b8 100644 --- a/lib/mp-compiler/index.js +++ b/lib/mp-compiler/index.js @@ -23,22 +23,7 @@ const { getPageSrc } = require('./util') -let emitFileTimer = null - -function createSlotsWxml (emitFile, slots, importCode) { - cacheSlots(slots, importCode) - const content = getSlots() - // 100 delay 比较符合当前策略 - const delay = 100 - if (content.trim()) { - if (emitFileTimer) { - clearTimeout(emitFileTimer) - } - emitFileTimer = setTimeout(function () { - emitFile('components/slots.wxml', htmlBeautify(content)) - }, delay) - } -} +let slotsHookAdded = false // 调用 compiler 生成 wxml function genComponentWxml (compiled, options, emitFile, emitError, emitWarning) { @@ -47,7 +32,7 @@ function genComponentWxml (compiled, options, emitFile, emitError, emitWarning) const { mpErrors, mpTips } = cp // 缓存 slots,延迟编译 - createSlotsWxml(emitFile, slots, importCode) + cacheSlots(slots, importCode) if (mpErrors && mpErrors.length) { emitError( @@ -63,47 +48,66 @@ function genComponentWxml (compiled, options, emitFile, emitError, emitWarning) return htmlBeautify(wxmlCodeStr) } +function createAppWxml (emitFile, resourcePath, rootComponent) { + const { src } = getFileInfo(resourcePath) || {} + const componentName = getCompNameBySrc(rootComponent) + const wxmlContent = genPageWxml(componentName, src) + const wxmlSrc = src + emitFile(`${wxmlSrc}.wxml`, wxmlContent) +} // 更新全局组件时,需要重新生成wxml,用这个字段保存所有需要更新的页面及其参数 const cacheCreateWxmlFns = {} function createWxml (emitWarning, emitError, emitFile, resourcePath, rootComponent, compiled, html) { cacheCreateWxmlFns[resourcePath] = arguments - const { pageType, moduleId, components, src } = getFileInfo(resourcePath) || {} - - // 这儿一个黑魔法,和 webpack 约定的规范写法有点偏差! - if (!pageType || (components && !components.isCompleted)) { - return setTimeout(createWxml, 20, ...arguments) - } - - let wxmlContent = '' - let wxmlSrc = '' - - if (rootComponent) { - const componentName = getCompNameBySrc(rootComponent) - wxmlContent = genPageWxml(componentName, src) - wxmlSrc = src - } else { - // TODO, 这儿传 options 进去 - // { - // components: { - // 'com-a': { src: '../../components/comA$hash', name: 'comA$hash' } - // }, - // pageType: 'component', - // name: 'comA$hash', - // moduleId: 'moduleId' - // } - const name = getCompNameBySrc(resourcePath) - const options = { components, pageType, name, moduleId } - wxmlContent = genComponentWxml(compiled, options, emitFile, emitError, emitWarning) - wxmlSrc = `components/${name}` - } + const { pageType, moduleId, components } = getFileInfo(resourcePath) || {} + + // TODO, 这儿传 options 进去 + // { + // components: { + // 'com-a': { src: '../../components/comA$hash', name: 'comA$hash' } + // }, + // pageType: 'component', + // name: 'comA$hash', + // moduleId: 'moduleId' + // } + const name = getCompNameBySrc(resourcePath) + const options = { components, pageType, name, moduleId } + const wxmlContent = genComponentWxml(compiled, options, emitFile, emitError, emitWarning) + const wxmlSrc = `components/${name}` emitFile(`${wxmlSrc}.wxml`, wxmlContent) } // 编译出 wxml function compileWxml (compiled, html) { - return createWxml(this.emitWarning, this.emitError, this.emitFile, this.resourcePath, null, compiled, html) + if (!slotsHookAdded) { + // avoid add hook several times during compilation + slotsHookAdded = true + // TODO: support webpack4 + this._compilation.plugin('seal', () => { + const content = getSlots() + if (content.trim()) { + this.emitFile('components/slots.wxml', htmlBeautify(content)) + } + // reset flag after slots file emited + slotsHookAdded = false + }) + } + return new Promise(resolve => { + const pollComponentsStatus = () => { + const { pageType, components } = getFileInfo(this.resourcePath) || {} + if (!pageType || (components && !components.isCompleted)) { + setTimeout(pollComponentsStatus, 20) + } else { + resolve() + } + } + pollComponentsStatus() + }) + .then(() => { + createWxml(this.emitWarning, this.emitError, this.emitFile, this.resourcePath, null, compiled, html) + }) } // 针对 .vue 单文件的脚本逻辑的处理 @@ -150,7 +154,7 @@ function compileMPScript (script, mpOptioins, moduleId) { const startPageReg = /^\^/ let globalComponents function compileMP (content, mpOptioins) { - const { resourcePath, emitError, emitFile, emitWarning, resolve, context, options } = this + const { resourcePath, emitFile, resolve, context, options } = this const fileInfo = resolveTarget(resourcePath, options.entry) cacheFileInfo(resourcePath, fileInfo) @@ -230,7 +234,7 @@ function compileMP (content, mpOptioins) { resolve(context, rootComponent, (err, rootComponentSrc) => { if (err) return // 这儿需要搞定 根组件的 路径 - createWxml(emitWarning, emitError, emitFile, resourcePath, rootComponentSrc) + createAppWxml(emitFile, resourcePath, rootComponentSrc) }) } } diff --git a/lib/template-compiler/index.js b/lib/template-compiler/index.js index 9dfacd8..0fab149 100644 --- a/lib/template-compiler/index.js +++ b/lib/template-compiler/index.js @@ -10,6 +10,7 @@ var transformRequire = require('./modules/transform-require') var compileWxml = require('../mp-compiler').compileWxml module.exports = function (html) { + this.async() this.cacheable() var isServer = this.target === 'node' var isProduction = this.minimize || process.env.NODE_ENV === 'production' @@ -38,56 +39,57 @@ module.exports = function (html) { // for mp => *.wxml compileWxml.call(this, compiled, html) + .then(() => { + // tips + if (compiled.tips && compiled.tips.length) { + compiled.tips.forEach(tip => { + this.emitWarning(tip) + }) + } - // tips - if (compiled.tips && compiled.tips.length) { - compiled.tips.forEach(tip => { - this.emitWarning(tip) - }) - } - - var code - if (compiled.errors && compiled.errors.length) { - this.emitError( - `\n Error compiling template:\n${pad(html)}\n` + - compiled.errors.map(e => ` - ${e}`).join('\n') + '\n' - ) - code = vueOptions.esModule - ? `var esExports = {render:function(){},staticRenderFns: []}\nexport default esExports` - : 'module.exports={render:function(){},staticRenderFns:[]}' - } else { - var bubleOptions = options.buble - code = transpile( - 'var render = ' + toFunction(compiled.render) + '\n' + - 'var staticRenderFns = [' + compiled.staticRenderFns.map(toFunction).join(',') + ']', - bubleOptions - ) + '\n' - // mark with stripped (this enables Vue to use correct runtime proxy detection) - if (!isProduction && ( - !bubleOptions || - !bubleOptions.transforms || - bubleOptions.transforms.stripWith !== false - )) { - code += `render._withStripped = true\n` - } - var exports = `{ render: render, staticRenderFns: staticRenderFns }` - code += vueOptions.esModule - ? `var esExports = ${exports}\nexport default esExports` - : `module.exports = ${exports}` - } - // hot-reload - if (!isServer && !isProduction) { - var exportsName = vueOptions.esModule ? 'esExports' : 'module.exports' - code += - '\nif (module.hot) {\n' + - ' module.hot.accept()\n' + - ' if (module.hot.data) {\n' + - ' require("' + hotReloadAPIPath + '").rerender("' + options.id + '", ' + exportsName + ')\n' + - ' }\n' + - '}' - } + var code + if (compiled.errors && compiled.errors.length) { + this.emitError( + `\n Error compiling template:\n${pad(html)}\n` + + compiled.errors.map(e => ` - ${e}`).join('\n') + '\n' + ) + code = vueOptions.esModule + ? `var esExports = {render:function(){},staticRenderFns: []}\nexport default esExports` + : 'module.exports={render:function(){},staticRenderFns:[]}' + } else { + var bubleOptions = options.buble + code = transpile( + 'var render = ' + toFunction(compiled.render) + '\n' + + 'var staticRenderFns = [' + compiled.staticRenderFns.map(toFunction).join(',') + ']', + bubleOptions + ) + '\n' + // mark with stripped (this enables Vue to use correct runtime proxy detection) + if (!isProduction && ( + !bubleOptions || + !bubleOptions.transforms || + bubleOptions.transforms.stripWith !== false + )) { + code += `render._withStripped = true\n` + } + var exports = `{ render: render, staticRenderFns: staticRenderFns }` + code += vueOptions.esModule + ? `var esExports = ${exports}\nexport default esExports` + : `module.exports = ${exports}` + } + // hot-reload + if (!isServer && !isProduction) { + var exportsName = vueOptions.esModule ? 'esExports' : 'module.exports' + code += + '\nif (module.hot) {\n' + + ' module.hot.accept()\n' + + ' if (module.hot.data) {\n' + + ' require("' + hotReloadAPIPath + '").rerender("' + options.id + '", ' + exportsName + ')\n' + + ' }\n' + + '}' + } - return code + this.callback(null, code) + }) } function toFunction (code) { From b99643236990a8326e89767b02c253b23a25e1cd Mon Sep 17 00:00:00 2001 From: aorz Date: Sat, 19 May 2018 22:10:09 +0800 Subject: [PATCH 13/13] new version 1.0.14 --- package.json | 6 +++--- 1 file changed, 3 insertions(+), 3 deletions(-) diff --git a/package.json b/package.json index 286c586..773a5e4 100644 --- a/package.json +++ b/package.json @@ -1,6 +1,6 @@ { "name": "mpvue-loader", - "version": "1.0.11", + "version": "1.0.14", "description": "mpvue single-file component loader for Webpack", "main": "index.js", "repository": { @@ -69,7 +69,7 @@ }, "peerDependencies": { "css-loader": "*", - "mpvue-template-compiler": "^1.0.7" + "mpvue-template-compiler": "^1.0.12" }, "devDependencies": { "babel-core": "^6.25.0", @@ -92,7 +92,7 @@ "marked": "^0.3.6", "memory-fs": "^0.4.1", "mocha": "^3.4.2", - "mpvue-template-compiler": "^1.0.7", + "mpvue-template-compiler": "^1.0.12", "node-libs-browser": "^2.0.0", "normalize-newline": "^3.0.0", "null-loader": "^0.1.1",