8000 roughly working for 2.0 · rspack-contrib/rspack-vue-loader@4768112 · GitHub
[go: up one dir, main page]

Skip to content

Commit 4768112

Browse files
committed
roughly working for 2.0
1 parent bc90d83 commit 4768112

File tree

5 files changed

+113
-294
lines changed

5 files changed

+113
-294
lines changed

lib/loader.js

Lines changed: 62 additions & 78 deletions
Original file line numberDiff line numberDiff line change
@@ -7,21 +7,20 @@ var path = require('path')
77

88
var defaultLang = {
99
template: 'html',
10-
style: 'css',
10+
styles: 'css',
1111
script: 'js'
1212
}
1313

14-
var rewriterInjectRE = /\b((css|(vue-)?html)(-loader)?(\?[^!]+)?)(?:!|$)/
14+
var rewriterInjectRE = /\b(css(-loader)?(\?[^!]+)?)(?:!|$)/
1515
var rewriters = {
16-
template: require.resolve('./template-rewriter'),
17-
style: require.resolve('./style-rewriter')
16+
styles: require.resolve('./style-rewriter')
1817
}
1918

2019
var templateLoader = require.resolve('./template-loader')
2120

2221
module.exports = function (content) {
2322
var defaultLoaders = {
24-
html: 'vue-html-loader',
23+
html: require.resolve('./template-compiler'),
2524
css: 'vue-style-loader!css-loader',
2625
js: 'babel-loader?presets[]=es2015&plugins[]=transform-runtime&comments=false'
2726
}
@@ -106,8 +105,8 @@ module.exports = function (content) {
106105
// unknown lang, infer the loader to be used
107106
switch (type) {
108107
case 'template':
109-
return defaultLoaders.html + '!' + rewriter + templateLoader + '?raw&engine=' + lang + '!'
110-
case 'style':
108+
return defaultLoaders.html + '!' + templateLoader + '?raw&engine=' + lang + '!'
109+
case 'styles':
111110
return defaultLoaders.css + '!' + rewriter + lang + '!'
112111
case 'script':
113112
return injectString + lang + '!'
@@ -143,35 +142,25 @@ module.exports = function (content) {
143142

144143
var parts = parse(content, fileName, this.sourceMap)
145144
var hasLocalStyles = false
146-
var output = 'var __vue_script__, __vue_template__\n'
147-
148-
// check if there are any template syntax errors
149-
var templateWarnings = parts.template.length && parts.template[0].warnings
150-
if (templateWarnings) {
151-
templateWarnings.forEach(this.emitError)
152-
}
153-
154-
// add requires for src imports
155-
parts.styleImports.forEach(function (impt) {
156-
if (impt.scoped) hasLocalStyles = true
157-
output += getRequireForImport('style', impt, impt.scoped)
158-
})
145+
var output = ''
159146

160147
// add requires for styles
161-
parts.style.forEach(function (style, i) {
162-
if (style.scoped) hasLocalStyles = true
163-
output += getRequire('style', style, i, style.scoped)
148+
parts.styles.forEach(function (style, i) {
149+
var scoped = style.scoped
150+
if (scoped) hasLocalStyles = true
151+
output += style.src
152+
? getRequireForImport('styles', style.src, scoped)
153+
: getRequire('styles', style, i, scoped)
164154
})
165155

166156
// add require for script
167-
var script
168-
if (parts.script.length) {
169-
script = parts.script[0]
157+
var script = parts.script
158+
if (script) {
170159
output +=
171-
'__vue_script__ = ' + (
160+
'var __vue_script__ = ' + (
172161
script.src
173-
? getRequireForImport('script', script, 0)
174-
: getRequire('script', script, 0)
162+
? getRequireForImport('script', script)
163+
: getRequire('script', script)
175164
)
176165
// check and warn named exports
177166
if (!this.minimize) {
@@ -187,68 +176,63 @@ module.exports = function (content) {
187176
}
188177
}
189178

179+
// plain require() compatibility
180+
var exports = 'if (__exports__.__esModule) __exports__ = __exports__.default\n'
181+
190182
// add require for template
191-
var template
192-
if (parts.template.length) {
193-
template = parts.template[0]
194-
output += '__vue_template__ = ' + (
195-
template.src
196-
? getRequireForImport('template', template, hasLocalStyles)
197-
: getRequire('template', template, 0, hasLocalStyles)
198-
)
183+
var template = parts.template
184+
if (template) {
185+
output += 'var __vue_template__ = ' + (
186+
template.src
187+
? getRequireForImport('template', template, hasLocalStyles)
188+
: getRequire('template', template, null, hasLocalStyles)
189+
)
190+
// attach render functions to exported options
191+
exports +=
192+
'var __vue_options__ = (typeof __exports__ === "function" ' +
193+
'? (__exports__.options || (__exports__.options = {})) ' +
194+
': __exports__)\n' +
195+
'__vue_options__.render = __vue_template__.render\n' +
196+
'__vue_options__.staticRenderFns = __vue_template__.staticRenderFns\n'
199197
}
200198

201199
if (!query.inject) {
202-
// attach template
203200
output +=
204-
'module.exports = __vue_script__ || {}\n' +
205-
'if (module.exports.__esModule) module.exports = module.exports.default\n' +
206-
'if (__vue_template__) {\n' +
207-
'(typeof module.exports === "function" ' +
208-
'? (module.exports.options || (module.exports.options = {})) ' +
209-
': module.exports).template = __vue_template__\n' +
210-
'}\n'
201+
'var __exports__ = __vue_script__ || {}\n' +
202+
exports +
203+
'module.exports = __exports__'
211204
// hot reload
212-
if (
213-
!this.minimize &&
214-
process.env.NODE_ENV !== 'production' &&
215-
(parts.script.length || parts.template.length)
216-
) {
217-
output +=
218-
'if (module.hot) {(function () {' +
219-
' module.hot.accept()\n' +
220-
' var hotAPI = require("vue-hot-reload-api")\n' +
221-
' hotAPI.install(require("vue"), false)\n' +
222-
' if (!hotAPI.compatible) return\n' +
223-
' var id = ' + loaderUtils.stringifyRequest(loaderContext, filePath) + '\n' +
224-
' if (!module.hot.data) {\n' +
225-
// initial insert
226-
' hotAPI.createRecord(id, module.exports)\n' +
227-
' } else {\n' +
228-
// update
229-
' hotAPI.update(id, module.exports, __vue_template__)\n' +
230-
' }\n' +
231-
'})()}'
232-
}
205+
// if (
206+
// !this.minimize &&
207+
// process.env.NODE_ENV !== 'production' &&
208+
// (parts.script.length || parts.template.length)
209+
// ) {
210+
// output +=
211+
// 'if (module.hot) {(function () {' +
212+
// ' module.hot.accept()\n' +
213+
// ' var hotAPI = require("vue-hot-reload-api")\n' +
214+
// ' hotAPI.install(require("vue"), false)\n' +
215+
// ' if (!hotAPI.compatible) return\n' +
216+
// ' var id = ' + loaderUtils.stringifyRequest(loaderContext, filePath) + '\n' +
217+
// ' if (!module.hot.data) {\n' +
218+
// // initial insert
219+
// ' hotAPI.createRecord(id, module.exports)\n' +
220+
// ' } else {\n' +
221+
// // update
222+
// ' hotAPI.update(id, module.exports, __vue_template__)\n' +
223+
// ' }\n' +
224+
// '})()}'
225+
// }
233226
} else {
234227
output +=
235228
'module.exports = function (injections) {\n' +
236-
' var mod = __vue_script__\n' +
229+
' var __exports__ = __vue_script__\n' +
237230
' ? __vue_script__(injections)\n' +
238-
' : {}\n' +
239-
' if (mod.__esModule) mod = mod.default\n' +
240-
' if (__vue_template__) { (typeof mod === "function" ? mod.options : mod).template = __vue_template__ }\n' +
241-
' return mod\n' +
231+
' : {}\n' + exports +
232+
' return __exports__\n' +
242233
'}'
243234
}
244235

245236
// done
246237
return output
247238
}
248-
249-
module.exports.withLoaders = function () {
250-
throw new Error(
251-
'vue.withLoaders has been deprecated in vue-loader 6.0. ' +
252-
'Add a "vue" section to the webpack config instead.'
253-
)
254-
}

lib/parser.js

Lines changed: 2 additions & 181 deletions
Original file line numberDiff line numberDiff line change
@@ -1,193 +1,14 @@
1-
var parse5 = require('parse5')
2-
var validateTemplate = require('vue-template-validator')
1+
var compiler = require('vue-template-compiler')
32
var cache = require('lru-cache')(100)
4-
var SourceMapGenerator = require('source-map').SourceMapGenerator
53
var hash = require('hash-sum')
6-
var deindent = require('de-indent')
7-
var splitRE = /\r?\n/g
8-
var emptyRE = /^\s*$/
9-
var commentSymbols = {
10-
'iced': '#',
11-
'iced-jsx': '#',
12-
'iced-redux': '#',
13-
'coffee': '#',
14-
'coffee-jsx': '#',
15-
'coffee-redux': '#',
16-
'purs': '--',
17-
'ulmus': '--'
18-
}
194

205
module.exports = function (content, filename, needMap) {
216
var cacheKey = hash(filename + content)
227
// source-map cache busting for hot-reloadded modules
238
var filenameWithHash = filename + '?' + cacheKey
249
var output = cache.get(cacheKey)
2510
if (output) return output
26-
27-
output = {
28-
template: [],
29-
style: [],
30-
script: [],
31-
styleImports: []
32-
}
33-
34-
var fragment = parse5.parseFragment(content, {
35-
locationInfo: true
36-
})
37-
38-
fragment.childNodes.forEach(function (node) {
39-
var type = node.tagName
40-
var lang = getAttribute(node, 'lang')
41-
var src = getAttribute(node, 'src')
42-
var scoped = getAttribute(node, 'scoped') != null
43-
var warnings = null
44-
var map = null
45-
46-
if (!output[type]) {
47-
return
48-
}
49-
50-
// node count check
51-
if (
52-
(type === 'script' || type === 'template') &&
53-
output[type].length > 0
54-
) {
55-
throw new Error(
56-
'[vue-loader] Only one <script> or <template> tag is ' +
57-
'allowed inside a Vue component.'
58-
)
59-
}
60-
61-
// handle src imports
62-
if (src) {
63-
if (type === 'style') {
64-
output.styleImports.push({
65-
src: src,
66-
lang: lang,
67-
scoped: scoped
68-
})
69-
} else if (type === 'template') {
70-
output.template.push({
71-
src: src,
72-
lang: lang
73-
})
74-
} else if (type === 'script') {
75-
output.script.push({
76-
src: src,
77-
lang: lang
78-
})
79-
}
80-
return
81-
}
82-
83-
// skip empty script/style tags
84-
if (type !== 'template' && (!node.childNodes || !node.childNodes.length)) {
85-
return
86-
}
87-
88-
// template content is nested inside the content fragment
89-
if (type === 'template') {
90-
node = node.content
91-
if (!lang) {
92-
warnings = validateTemplate(node, content)
93-
}
94-
}
95-
96-
// extract part
97-
var start = node.childNodes[0].__location.startOffset
98-
var end = node.childNodes[node.childNodes.length - 1].__location.endOffset
99-
var result
100-
if (type === 'script') {
101-
// preserve other parts as commenets so that linters
102-
// and babel can output correct line numbers in warnings
103-
result =
104-
commentScript(content.slice(0, start), lang) +
105-
deindent(content.slice(start, end)) +
106-
commentScript(content.slice(end), lang)
107-
} else {
108-
var lineOffset = content.slice(0, start).split(splitRE).length - 1
109-
result = deindent(content.slice(start, end))
110-
111-
// pad whith whitespace so that error messages are correct
112-
result = Array(lineOffset + 1).join('\n') + result
113-
}
114-
115-
if (needMap) {
116-
// generate source map
117-
map = new SourceMapGenerator()
118-
map.setSourceContent(filenameWithHash, content)
119-
120-
// do not add mappings for comment lines - babel's source map
121-
// somehow gets messed up because of it
122-
var isCommentLine = function (line) {
123-
return type === 'script' &&
124-
line.indexOf(getCommentSymbol(lang)) === 0
125-
}
126-
127-
result.split(splitRE).forEach(function (line, index) {
128-
if (!emptyRE.test(line) && !isCommentLine(line)) {
129-
map.addMapping({
130-
source: filenameWithHash,
131-
original: {
132-
line: index + 1,
133-
column: 0
134-
},
135-
generated: {
136-
line: index + 1,
137-
column: 0
138-
}
139-
})
140-
}
141-
})
142-
// workaround for Webpack eval-source-map bug
143-
// https://github.com/webpack/webpack/pull/1816
144-
// in case the script was piped through another loader
145-
// that doesn't pass down the source map properly.
146-
if (type === 'script' && !lang) {
147-
result += '\n/* generated by vue-loader */\n'
148-
}
149-
}
150-
151-
output[type].push({
152-
lang: lang,
153-
scoped: scoped,
154-
content: result,
155-
map: map && map.toJSON(),
156-
warnings: warnings
157-
})
158-
})
159-
11+
output = compiler.parseComponent(content)
16012
cache.set(cacheKey, output)
16113
return output
16214
}
163-
164-
function commentScript (content, lang) {
165-
var symbol = getCommentSymbol(lang)
166-
var lines = content.split(splitRE)
167-
return lines.map(function (line, index) {
168-
// preserve EOL
169-
if (index === lines.length - 1 && emptyRE.test(line)) {
170-
return ''
171-
} else {
172-
return symbol + (emptyRE.test(line) ? '' : ' ' + line)
173-
}
174-
})
175-
.join('\n')
176-
}
177-
178-
function getCommentSymbol (lang) {
179-
return commentSymbols[lang] || '//'
180-
}
181-
182-
function getAttribute (node, name) {
183-
if (node.attrs) {
184-
var i = node.attrs.length
185-
var attr
186-
while (i--) {
187-
attr = node.attrs[i]
188-
if (attr.name === name) {
189-
return attr.value
190-
}
191-
}
192-
}
193-
}

0 commit comments

Comments
 (0)
0