Skip to content

Commit b0b9691

Browse files
committed
add pad/map option to sfc parser
1 parent d94225e commit b0b9691

File tree

10 files changed

+110
-31
lines changed

10 files changed

+110
-31
lines changed

build/build.js

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -65,7 +65,7 @@ var builds = [
6565
{
6666
entry: 'src/entries/web-compiler.js',
6767
format: 'cjs',
68-
external: ['entities', 'de-indent'],
68+
external: ['entities', 'de-indent', 'source-map'],
6969
out: 'packages/vue-template-compiler/index.js'
7070
},
7171
// Web server renderer (CommonJS).

build/webpack.compiler.dev.config.js

Lines changed: 29 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,29 @@
1+
var path = require('path')
2+
var alias = require('./alias')
3+
4+
module.exports = {
5+
entry: path.resolve(__dirname, '../src/entries/web-compiler.js'),
6+
target: 'node',
7+
output: {
8+
path: path.resolve(__dirname, '../packages/vue-template-compiler'),
9+
filename: 'index.js',
10+
libraryTarget: 'commonjs2'
11+
},
12+
resolve: {
13+
alias: alias
14+
},
15+
externals: {
16+
'entities': true,
17+
'de-indent': true,
18+
'source-map': true
19+
},
20+
module: {
21+
loaders: [
22+
{
23+
test: /\.js/,
24+
loader: 'babel!eslint',
25+
exclude: /node_modules/
26+
}
27+
]
28+
}
29+
}

build/webpack.dist.dev.config.js

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -3,7 +3,7 @@ var alias = require('./alias')
33
var webpack = require('webpack')
44

55
module.exports = {
6-
entry: path.resolve(__dirname, 'dist.dev.entry.js'),
6+
entry: path.resolve(__dirname, 'webpack.dist.dev.entry.js'),
77
output: {
88
path: path.resolve(__dirname, '../dist'),
99
filename: 'vue.js',
File renamed without changes.

build/webpack.ssr.dev.config.js

Lines changed: 3 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -2,11 +2,11 @@ var path = require('path')
22
var alias = require('./alias')
33

44
module.exports = {
5-
entry: path.resolve(__dirname, 'ssr.dev.entry.js'),
5+
entry: path.resolve(__dirname, 'webpack.ssr.dev.entry.js'),
66
target: 'node',
77
output: {
8-
path: path.resolve(__dirname, '../dist'),
9-
filename: 'server-renderer.js',
8+
path: path.resolve(__dirname, '../packages/vue-server-renderer'),
9+
filename: 'index.js',
1010
libraryTarget: 'commonjs2'
1111
},
1212
resolve: {
File renamed without changes.

flow/compiler.js

Lines changed: 12 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -133,6 +133,14 @@ declare module 'de-indent' {
133133
}
134134
}
135135

136+
declare module 'source-map' {
137+
declare class SourceMapGenerator {
138+
setSourceContent(filename: string, content: string): void;
139+
addMapping(mapping: Object): void;
140+
toString(): string;
141+
}
142+
}
143+
136144
// an object format describing a single-file component.
137145
declare type SFCDescriptor = {
138146
template: ?SFCBlock,
@@ -141,10 +149,12 @@ declare type SFCDescriptor = {
141149
}
142150

143151
declare type SFCBlock = {
144-
type: "template" | "script" | "style",
152+
type: string,
145153
content: string,
154+
start?: number,
155+
end?: number,
146156
lang?: string,
157+
src?: string,
147158
scoped?: boolean,
148-
src?: boolean,
149159
map?: Object
150160
}

package.json

Lines changed: 1 addition & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -15,6 +15,7 @@
1515
"dev": "webpack --watch --config build/webpack.dist.dev.config.js",
1616
"dev:test": "karma start build/karma.dev.config.js",
1717
"dev:ssr": "webpack --watch --config build/webpack.ssr.dev.config.js",
18+
"dev:compiler": "webpack --watch --config build/webpack.compiler.dev.config.js",
1819
"test": "npm run lint && flow check && npm run test:unit && npm run test:e2e && npm run test:ssr",
1920
"ci": "npm run lint && flow check && npm run test:cover && npm run test:ssr",
2021
"build": "NODE_ENV=production node build/build.js",
@@ -51,8 +52,6 @@
5152
"chromedriver": "^2.21.2",
5253
"codecov.io": "^0.1.6",
5354
"cross-spawn": "^4.0.0",
54-
"de-indent": "^1.0.2",
55-
"entities": "^1.1.1",
5655
"eslint": "^2.11.0",
5756
"eslint-config-vue": "^1.0.3",
5857
"eslint-loader": "^1.3.0",

packages/vue-template-compiler/package.json

Lines changed: 2 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -19,6 +19,7 @@
1919
"homepage": "https://github.com/vuejs/vue#readme",
2020
"dependencies": {
2121
"de-indent": "^1.0.2",
22-
"entities": "^1.1.1"
22+
"entities": "^1.1.1",
23+
"source-map": "^0.5.6"
2324
}
2425
}

src/compiler/parser/sfc-parser.js

Lines changed: 61 additions & 21 deletions
Original file line numberDiff line numberDiff line change
@@ -1,64 +1,104 @@
11
/* @flow */
22

3+
// this file is used in the vue-template-compiler npm package
4+
// and assumes its dependencies and a Node/CommonJS environment
5+
import deindent from 'de-indent'
6+
import { SourceMapGenerator } from 'source-map'
7+
38
import { parseHTML } from './html-parser'
49
import { makeMap } from 'shared/util'
5-
import deindent from 'de-indent'
610

11+
const splitRE = /\r?\n/g
712
const isSpecialTag = makeMap('script,style,template', true)
813

14+
type Attribute = {
15+
name: string,
16+
value: string
17+
}
18+
919
/**
1020
* Parse a single-file component (*.vue) file into an SFC Descriptor Object.
1121
*/
12-
export function parseComponent (content: string): SFCDescriptor {
22+
export function parseComponent (
23+
content: string,
24+
options?: Object
25+
): SFCDescriptor {
1326
const sfc: SFCDescriptor = {
1427
template: null,
1528
script: null,
1629
styles: []
1730
}
1831
let depth = 0
19-
let currentBlock
32+
let currentBlock: ?SFCBlock = null
2033

21-
function start (tag, attrs) {
34+
function start (tag: string, attrs: Array<Attribute>) {
2235
depth++
2336
if (depth > 1) {
2437
return
2538
}
2639
if (isSpecialTag(tag)) {
27-
const block: SFCBlock = currentBlock = {
40+
currentBlock = {
2841
type: tag,
2942
content: ''
3043
}
31-
for (let i = 0; i < attrs.length; i++) {
32-
const attr = attrs[i]
33-
if (attr.name === 'lang') {
34-
block.lang = attr.value
35-
}
36-
if (attr.name === 'scoped') {
37-
block.scoped = true
38-
}
39-
if (attr.name === 'src') {
40-
block.src = attr.value
41-
}
42-
}
44+
checkAttrs(currentBlock, attrs)
4345
if (tag === 'style') {
44-
sfc.styles.push(block)
46+
sfc.styles.push(currentBlock)
4547
} else {
46-
sfc[tag] = block
48+
sfc[tag] = currentBlock
49+
}
50+
}
51+
}
52+
53+
function checkAttrs (block: SFCBlock, attrs: Array<Attribute>) {
54+
for (let i = 0; i < attrs.length; i++) {
55+
const attr = attrs[i]
56+
if (attr.name === 'lang') {
57+
block.lang = attr.value
58+
}
59+
if (attr.name === 'scoped') {
60+
block.scoped = true
61+
}
62+
if (attr.name === 'src') {
63+
block.src = attr.value
4764
}
4865
}
4966
}
5067

5168
function end () {
5269
depth--
70+
if (currentBlock && options && options.map) {
71+
addSourceMap(currentBlock)
72+
}
5373
currentBlock = null
5474
}
5575

56-
function chars (text) {
76+
function chars (text: string) {
5777
if (currentBlock) {
58-
currentBlock.content = deindent(text)
78+
currentBlock.start = content.indexOf(text)
79+
currentBlock.end = currentBlock.start + text.length
80+
text = deindent(text)
81+
// pad content so that linters and pre-processors can output correct
82+
// line numbers in errors and warnings
83+
if (currentBlock.type !== 'template' && options && options.pad) {
84+
text = padContent(currentBlock) + text
85+
}
86+
currentBlock.content = text
5987
}
6088
}
6189

90+
function padContent (block: SFCBlock) {
91+
const leadingContent = content.slice(0, block.start)
92+
const padChar = block.type === 'script' && !block.lang
93+
? '//\n'
94+
: '\n'
95+
return Array(leadingContent.split(splitRE).length).join(padChar)
96+
}
97+
98+
function addSourceMap (block: SFCBlock) {
99+
100+
}
101+
62102
parseHTML(content, {
63103
isSpecialTag,
64104
start,

0 commit comments

Comments
 (0)