Skip to content
Merged
Show file tree
Hide file tree
Changes from 1 commit
Commits
File filter

Filter by extension

Filter by extension


Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
6 changes: 5 additions & 1 deletion lib/template-compiler/index.js
Original file line number Diff line number Diff line change
Expand Up @@ -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') {
Expand Down
70 changes: 49 additions & 21 deletions lib/template-compiler/modules/transform-require.js
Original file line number Diff line number Diff line change
@@ -1,50 +1,78 @@
// vue compiler module for transforming `<tag>:<attribute>` 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
Copy link
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

对啦,在小程序里没有必要转 base64 啊。。。一整个就一个离线包,base64 反而可能影响解析速度

Copy link
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

主要是背景图还有字体啥的本地只能用 base64 格式的

Copy link
Member Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

好像是没什么必要,背景图那些这里不会处理到,可以把limit默认设置为0吧

Copy link
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

所以背景图和字体还是不会被转换吗?有这个需求的人好像还挺多

Copy link
Member Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

在css中引入的背景图是url-loader处理的,如果只有base64支持,可以把url-loader的配置limit调大

Copy link
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

背景图我记得好像没问题,字体没试过,理论上应该也可以,不知道为什么之前好多人说这个问题。。

Copy link
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

这里主要是处理 img 标签这类引用相对资源的话,确实不是很有必要转 base64

Copy link
Member

@F-loat F-loat May 11, 2018

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

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)
})
}
5 changes: 3 additions & 2 deletions package.json
Original file line number Diff line number Diff line change
Expand Up @@ -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",
Expand Down Expand Up @@ -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",
Expand Down