forked from codesandbox/codesandbox-client
-
Notifications
You must be signed in to change notification settings - Fork 0
Expand file tree
/
Copy pathloader.js
More file actions
129 lines (113 loc) · 3.54 KB
/
loader.js
File metadata and controls
129 lines (113 loc) · 3.54 KB
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
/* eslint-disable no-use-before-define */
import transpile from 'vue-template-es2015-compiler';
import * as compiler from 'vue-template-compiler';
import vueHotReloadAPIRaw from '!raw-loader!vue-hot-reload-api';
import { type LoaderContext } from '../../../transpiled-module';
import transformRequire from './modules/transform-require';
import transformSrcset from './modules/transform-srcset';
const hotReloadAPIPath = '!noop-loader!/node_modules/vue-hot-reload-api.js';
export default function(html: string, loaderContext: LoaderContext) {
loaderContext.emitModule(
hotReloadAPIPath,
vueHotReloadAPIRaw,
'/',
false,
false
);
const { options } = loaderContext;
const vueOptions = options.vueOptions || {};
const needsHotReload = true;
const defaultModules = [
transformRequire(options.transformRequire, loaderContext),
transformSrcset(),
];
const userModules = vueOptions.compilerModules || options.compilerModules;
const compilerOptions = {
preserveWhitespace: options.preserveWhitespace,
modules: defaultModules.concat(userModules || []),
directives:
vueOptions.compilerDirectives || options.compilerDirectives || {},
scopeId: options.hasScoped ? options.id : null,
comments: options.hasComment,
};
const compiled = compiler.compile(html, compilerOptions);
// tips
if (compiled.tips && compiled.tips.length) {
compiled.tips.forEach(tip => {
loaderContext.emitWarning({
name: 'vue-warning',
message: tip,
fileName: loaderContext._module.module.parent
? loaderContext._module.module.parent.path
: loaderContext.path,
lineNumber: 1,
columnNumber: 1,
source: 'vue-template-compiler',
});
});
}
let code;
if (compiled.errors && compiled.errors.length) {
loaderContext.emitError(
new Error(
`\n Error compiling template:\n${pad(html)}\n` +
compiled.errors.map(e => ` - ${e}`).join('\n') +
'\n'
)
);
code = 'module.exports={render:function(){},staticRenderFns:[]}';
} else {
const bubleOptions = options.buble;
const stripWith = bubleOptions.transforms.stripWith !== false;
const { stripWithFunctional } = bubleOptions.transforms;
const staticRenderFns = compiled.staticRenderFns.map(fn =>
toFunction(fn, stripWithFunctional)
);
code =
transpile(
'var render = ' +
toFunction(compiled.render, stripWithFunctional) +
'\n' +
'var staticRenderFns = [' +
staticRenderFns.join(',') +
']',
bubleOptions
) + '\n';
// mark with stripped (this enables Vue to use correct runtime proxy detection)
if (stripWith) {
code += `render._withStripped = true\n`;
}
const exports = `{ render: render, staticRenderFns: staticRenderFns }`;
code += `module.exports = ${exports}`;
}
// hot-reload
if (needsHotReload) {
const 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;
}
function toFunction(code, stripWithFunctional) {
return (
'function (' + (stripWithFunctional ? '_h,_vm' : '') + ') {' + code + '}'
);
}
function pad(html) {
return html
.split(/\r?\n/)
.map(line => ` ${line}`)
.join('\n');
}