Skip to content

Commit 27757f7

Browse files
authored
Merge pull request #27 from Treri/master
添加原因, 我倾向于将css内联到js中进行加载, 做到css和模板js的强关联, 而且还能同时加载. 如果内容太多的话, 可以分每个commit进行review - 将template-compiler放到单独文件里, 方便和 vueify 还有 vue-loader进行比照升级 - 将runtimeOnly和template进行判断的逻辑更改了一下, 先去判断有没有template, 有的话, 才会进一步判断runtimeOnly的执行. 所以最终的结果是, 如果没有写模板的话, 就不会生成 `module.exports.render = function(){} module.exports.staticRenderFns = []` 这样的语句 - 在选项中增加extractCSS 默认为 true, 和目前逻辑保持一致. 如果设置为false, 则会将CSS内联到js中, 通过一个简化版的 `insert-css` 将css字符串添加到 head 中. 在做这一块的内容时, 曾经想过把 `output['styles']` 的所有内容整合成一个文件, 或者一个css字符串, 但是试验后发现, 如果使用scss的话, 会在文件头部插入 `@charset "UTF-8"`, 而这个 `@rule` 要求在css文件的顶部, 否则就是不合法的. 所以最终没有把css进行合并. 后续计划: 将 `scoped CSS` 做成和 vueify 还有 vue-loader一样的效果, 不需要在模板中手动去写占位符就自动的生成 scopedId
2 parents 160b594 + 8a7f2e3 commit 27757f7

File tree

4 files changed

+92
-73
lines changed

4 files changed

+92
-73
lines changed

index.js

Lines changed: 55 additions & 73 deletions
Original file line numberDiff line numberDiff line change
@@ -1,18 +1,19 @@
11
var path = require('path');
2-
var chalk = require('chalk')
32
var objectAssign = require('object-assign');
43
var hashSum = require('hash-sum');
54
var compiler = require('vue-template-compiler');
6-
var transpile = require('vue-template-es2015-compiler');
5+
6+
var compileTemplate = require('./lib/template-compiler');
7+
var insertCSS = require('./lib/insert-css');
78

89
// exports
910
module.exports = function(content, file, conf) {
1011
var scriptStr = '';
11-
var templateFileName, templateFile, templateContent;
12-
var fragment, output, configs, vuecId, jsLang;
12+
var output, configs, vuecId, jsLang;
1313

1414
// configs
1515
configs = objectAssign({
16+
extractCSS: true,
1617
cssScopedFlag: '__vuec__',
1718
cssScopedIdPrefix: '_v-',
1819
cssScopedHashType: 'sum',
@@ -64,89 +65,70 @@ module.exports = function(content, file, conf) {
6465
isJsLike: true
6566
});
6667

67-
// template
68-
if (configs.runtimeOnly) {
68+
if(output.template){
69+
var templateContent = fis.compile.partial(output.template.content, file, {
70+
ext: output.template.lang || 'html',
71+
isHtmlLike: true
72+
});
6973
// runtimeOnly
70-
71-
function toFunction (code) {
72-
// console.log(code);
73-
return transpile('function render () {' + code + '}')
74-
}
75-
76-
if (output.template) {
77-
templateContent = fis.compile.partial(output.template.content, file, {
78-
ext: output.template.lang || 'html',
79-
isHtmlLike: true
80-
});
81-
82-
var compiled = compiler.compile(templateContent);
83-
var renderFun, staticRenderFns;
84-
85-
if (compiled.errors.length) {
86-
compiled.errors.forEach(function (err) {
87-
console.error('\n' + chalk.red(err) + '\n')
88-
});
89-
throw new Error('Vue template compilation failed');
90-
} else {
91-
renderFun = toFunction(compiled.render);
92-
staticRenderFns = '[' + compiled.staticRenderFns.map(toFunction).join(',') + ']';
74+
if(configs.runtimeOnly){
75+
var result = compileTemplate(templateContent);
76+
if(result){
77+
scriptStr += '\n;\n(function(renderFun, staticRenderFns){\n'
78+
scriptStr += '\nif(module && module.exports){ module.exports.render=renderFun; module.exports.staticRenderFns=staticRenderFns;}\n';
79+
scriptStr += '\nif(exports && exports.default){ exports.default.render=renderFun; exports.default.staticRenderFns=staticRenderFns;}\n';
80+
scriptStr += '\n})(' + result.render + ',' + result.staticRenderFns + ');\n';
9381
}
94-
} else {
95-
renderFun = 'function(){}';
96-
staticRenderFns = '[]';
97-
}
98-
99-
scriptStr += '\n;\n(function(renderFun, staticRenderFns){\n'
100-
scriptStr += '\nif(module && module.exports){ module.exports.render=renderFun; module.exports.staticRenderFns=staticRenderFns;}\n';
101-
scriptStr += '\nif(exports && exports.default){ exports.default.render=renderFun; exports.default.staticRenderFns=staticRenderFns;}\n';
102-
scriptStr += '\n})(' + renderFun + ',' + staticRenderFns + ');\n';
103-
} else {
104-
// template
105-
if (output.template) {
106-
templateContent = fis.compile.partial(output.template.content, file, {
107-
ext: output.template.lang || 'html',
108-
isHtmlLike: true
109-
});
110-
82+
}else{
83+
// template
11184
scriptStr += '\n;\n(function(template){\n'
11285
scriptStr += '\nmodule && module.exports && (module.exports.template = template);\n';
11386
scriptStr += '\nexports && exports.default && (exports.default.template = template);\n';
11487
scriptStr += '\n})(' + JSON.stringify(templateContent) + ');\n';
115-
} else {
116-
scriptStr += '\nmodule && module.exports && (module.exports.template = "");\n';
117-
scriptStr += '\nexports && exports.default && (exports.default.template = "");\n';
11888
}
11989
}
12090

12191
// style
12292
output['styles'].forEach(function(item, index) {
123-
if (item.content) {
124-
var styleFileName, styleFile, styleContent;
93+
if(!item.content){
94+
return;
95+
}
12596

126-
if (output['styles'].length == 1) {
127-
styleFileName = file.realpathNoExt + configs.styleNameJoin + '.css';
128-
} else {
129-
styleFileName = file.realpathNoExt + configs.styleNameJoin + '-' + index + '.css';
130-
}
97+
// empty string, or all space line
98+
if(/^\s*$/.test(item.content)){
99+
return;
100+
}
101+
102+
// css也采用片段编译,更好的支持less、sass等其他语言
103+
var styleContent = fis.compile.partial(item.content, file, {
104+
ext: item.lang || 'css',
105+
isCssLike: true
106+
});
131107

132-
styleFile = fis.file.wrap(styleFileName);
133-
134-
// css也采用片段编译,更好的支持less、sass等其他语言
135-
styleContent = fis.compile.partial(item.content, file, {
136-
ext: item.lang || 'css',
137-
isCssLike: true
138-
});
139-
140-
styleFile.cache = file.cache;
141-
styleFile.isCssLike = true;
142-
styleFile.setContent(styleContent);
143-
fis.compile.process(styleFile);
144-
styleFile.links.forEach(function(derived) {
145-
file.addLink(derived);
146-
});
147-
file.derived.push(styleFile);
148-
file.addRequire(styleFile.getId());
108+
if(!configs.extractCSS){
109+
scriptStr += '\n;(' + insertCSS + ')(' + JSON.stringify(styleContent) + ');\n';
110+
return;
149111
}
112+
113+
var styleFileName, styleFile;
114+
115+
if (output['styles'].length == 1) {
116+
styleFileName = file.realpathNoExt + configs.styleNameJoin + '.css';
117+
} else {
118+
styleFileName = file.realpathNoExt + configs.styleNameJoin + '-' + index + '.css';
119+
}
120+
121+
styleFile = fis.file.wrap(styleFileName);
122+
123+
styleFile.cache = file.cache;
124+
styleFile.isCssLike = true;
125+
styleFile.setContent(styleContent);
126+
fis.compile.process(styleFile);
127+
styleFile.links.forEach(function(derived) {
128+
file.addLink(derived);
129+
});
130+
file.derived.push(styleFile);
131+
file.addRequire(styleFile.getId());
150132
});
151133

152134
// 处理一遍scoped css

lib/insert-css.js

Lines changed: 14 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,14 @@
1+
var uglifyJS = require('uglify-js');
2+
3+
function insertCSS(styleContent) {
4+
var styleNode = document.createElement("style");
5+
styleNode.setAttribute("type", "text/css");
6+
if (styleNode.styleSheet) {
7+
styleNode.styleSheet.cssText = styleContent;
8+
} else {
9+
styleNode.appendChild(document.createTextNode(styleContent));
10+
}
11+
document.getElementsByTagName("head")[0].appendChild(styleNode);
12+
};
13+
14+
module.exports = uglifyJS.minify(insertCSS.toString(), {fromString: true}).code;

lib/template-compiler.js

Lines changed: 22 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,22 @@
1+
var chalk = require('chalk')
2+
var vueCompiler = require('vue-template-compiler')
3+
var transpile = require('vue-template-es2015-compiler')
4+
5+
module.exports = function compileTemplate (template) {
6+
var compiled = vueCompiler.compile(template)
7+
if (compiled.errors.length) {
8+
compiled.errors.forEach(function (msg) {
9+
console.error('\n' + chalk.red(msg) + '\n')
10+
})
11+
throw new Error('Vue template compilation failed')
12+
} else {
13+
return {
14+
render: toFunction(compiled.render),
15+
staticRenderFns: '[' + compiled.staticRenderFns.map(toFunction).join(',') + ']'
16+
}
17+
}
18+
}
19+
20+
function toFunction (code) {
21+
return transpile('function render () {' + code + '}')
22+
}

package.json

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -14,6 +14,7 @@
1414
"chalk": "^1.1.3",
1515
"hash-sum": "^1.0.2",
1616
"object-assign": "^4.1.0",
17+
"uglify-js": "^2.8.14",
1718
"vue-template-compiler": "^2.1.6",
1819
"vue-template-es2015-compiler": "^1.4.0"
1920
},

0 commit comments

Comments
 (0)