-
Notifications
You must be signed in to change notification settings - Fork 0
/
Copy pathindex.js
158 lines (124 loc) · 3.91 KB
/
index.js
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
142
143
144
145
146
147
148
149
150
151
152
153
154
155
156
157
158
/**
* Vue单文件组件编译
*
* @author Yang,junlong at 2018-11-14 15:26:46 build.
* @version $Id$
*/
var crypto = require('crypto');
var compiler = require('vue-template-compiler');
var transpile = require('vue-template-es2015-compiler');
var babel = require('babel-core');
var preset2015 = require('babel-preset-es2015');
var rewriteStyle = require('./lib/style-rewriter');
module.exports = function(content, secretKey, conf) {
var output = [];
var script = '';
var deps = [];
var hash = crypto.createHmac('sha256', secretKey);
var scopeId = '_v-' + hash.update(content).digest('hex').substring(0, 8);
// Parse a SFC (single-file component, or *.vue file) into a descriptor
var descriptor = compiler.parseComponent(content.toString(), { pad: true });
// check for scoped style nodes
var scoped = descriptor.styles.some(function (style) {
return style.scoped
});
if(descriptor.script) {
// babel transform
script = babel.transform(descriptor.script.content, {
presets: [preset2015],
}).code;
} else {
script += 'module.exports = {}';
}
deps = depsParser(script);
output.push(script);
output.push('var __vue__options__;');
output.push('if(exports && exports.__esModule && exports.default){');
output.push(' __vue__options__ = exports.default;');
output.push('}else{');
output.push(' __vue__options__ = module.exports;');
output.push('}');
if(descriptor.template) {
var templated = compileTemplate(descriptor.template.content);
output.push('__vue__options__.render = ' + templated.render + ';');
output.push('__vue__options__.staticRenderFns = ' + templated.staticRenderFns + ';');
}
if(scoped) {
output.push('__vue__options__._scopeId = ' + JSON.stringify(scopeId) + ';');
}
var styles = [];
descriptor.styles.forEach(function(item, index) {
var content = item.content.trim();
if(!content){
return;
}
// rewrite style add scopedId
content = rewriteStyle(scopeId, content, item.scoped, {});
styles.push(content);
});
if(styles.length > 0) {
// mod.js require.loaddCss method support
output.push('require.loadCss({content: '+JSON.stringify(styles.join('\n'))+'})');
}
return {
deps: deps,
code: output.join('\n')
}
};
// utils
function compileTemplate (template) {
var compiled = compiler.compile(template)
if (compiled.errors.length) {
compiled.errors.forEach(function (msg) {
console.error('\n' + msg + '\n')
})
throw new Error('Vue template compilation failed')
} else {
return {
render: toFunction(compiled.render),
staticRenderFns: '[' + compiled.staticRenderFns.map(toFunction).join(',') + ']'
}
}
}
function toFunction (code) {
return transpile('function render () {' + code + '}')
}
var rRequire = /"(?:[^\\"\r\n\f]|\\[\s\S])*"|'(?:[^\\'\n\r\f]|\\[\s\S])*'|(\/\/[^\r\n\f]+|\/\*[\s\S]+?(?:\*\/|$))|\b(require\.async|require\.ensure|require)\s*\(\s*("(?:[^\\"\r\n\f]|\\[\s\S])*"|'(?:[^\\'\n\r\f]|\\[\s\S])*'|\[[\s\S]*?\])\s*/g;
function depsParser (script) {
var deps = [];
script.replace(rRequire, function(m, comment, type, params) {
if (type) {
var moduleId = params.trim().replace(/^["|'](.*)["|']$/g, '$1');
switch (type) {
// 异步依赖
case 'require.async':
deps.push({
moduleId: moduleId,
mode: 'require.async'
});
break;
case 'require.ensure':
deps.push({
moduleId: moduleId,
mode: 'require.ensure'
});
break;
case 'require':
deps.push({
moduleId: moduleId,
mode: 'require'
});
break;
}
}
// 注释
if(comment) {
}
});
return deps;
}
// test
// var fs = require('fs');
// var content = fs.readFileSync('./test.vue', 'utf8');
// var result = module.exports(content, '11', {});
// console.log(result);