Browse Source

remove source-map generation from sfc parser

dev
Evan You 9 years ago
parent
commit
2af9f68bd9
  1. 1
      .flowconfig
  2. 3
      build/alias.js
  3. 2
      build/build.js
  4. 3
      flow/compiler.js
  5. 6
      flow/modules.js
  6. 2
      package.json
  7. 2
      src/entries/web-compiler.js
  8. 45
      src/sfc/deindent.js
  9. 46
      src/sfc/parser.js
  10. 60
      test/unit/modules/compiler/sfc-parser.spec.js

1
.flowconfig

@ -17,3 +17,4 @@ module.name_mapper='^shared/\(.*\)$' -> '<PROJECT_ROOT>/src/shared/\1'
module.name_mapper='^web/\(.*\)$' -> '<PROJECT_ROOT>/src/platforms/web/\1'
module.name_mapper='^server/\(.*\)$' -> '<PROJECT_ROOT>/src/server/\1'
module.name_mapper='^entries/\(.*\)$' -> '<PROJECT_ROOT>/src/entries/\1'
module.name_mapper='^sfc/\(.*\)$' -> '<PROJECT_ROOT>/src/sfc/\1'

3
build/alias.js

@ -7,5 +7,6 @@ module.exports = {
shared: path.resolve(__dirname, '../src/shared'),
web: path.resolve(__dirname, '../src/platforms/web'),
server: path.resolve(__dirname, '../src/server'),
entries: path.resolve(__dirname, '../src/entries')
entries: path.resolve(__dirname, '../src/entries'),
sfc: path.resolve(__dirname, '../src/sfc')
}

2
build/build.js

@ -65,7 +65,7 @@ var builds = [
{
entry: 'src/entries/web-compiler.js',
format: 'cjs',
external: ['entities', 'de-indent', 'source-map'],
external: ['entities'],
out: 'packages/vue-template-compiler/index.js'
},
// Web server renderer (CommonJS).

3
flow/compiler.js

@ -140,6 +140,5 @@ declare type SFCBlock = {
end?: number,
lang?: string,
src?: string,
scoped?: boolean,
map?: Object
scoped?: boolean
}

6
flow/modules.js

@ -3,12 +3,6 @@ declare module 'entities' {
declare function decodeHTML(html: string): string;
}
declare module 'de-indent' {
declare var exports: {
(str: string): string;
}
}
declare module 'source-map' {
declare class SourceMapGenerator {
setSourceContent(filename: string, content: string): void;

2
package.json

@ -52,7 +52,6 @@
"chromedriver": "^2.21.2",
"codecov.io": "^0.1.6",
"cross-spawn": "^4.0.0",
"de-indent": "^1.0.2",
"entities": "^1.1.1",
"eslint": "^2.11.0",
"eslint-config-vue": "^1.0.3",
@ -81,7 +80,6 @@
"rollup-plugin-babel": "^2.4.0",
"rollup-plugin-replace": "^1.1.0",
"selenium-server": "2.53.0",
"source-map": "^0.5.6",
"uglify-js": "^2.6.2",
"webpack": "^1.13.1"
}

2
src/entries/web-compiler.js

@ -2,7 +2,7 @@ import { extend } from 'shared/util'
import { compile as baseCompile, baseOptions } from 'web/compiler/index'
import { detectErrors } from 'compiler/error-detector'
export { parseComponent } from 'compiler/parser/sfc-parser'
export { parseComponent } from 'sfc/parser'
export { compileToFunctions } from 'web/compiler/index'
export function compile (

45
src/sfc/deindent.js

@ -0,0 +1,45 @@
/* @flow */
const splitRE = /\r?\n/g
const emptyRE = /^\s*$/
const needFixRE = /^(\r?\n)*[\t\s]/
export default function deindent (str: string): string {
if (!needFixRE.test(str)) {
return str
}
const lines = str.split(splitRE)
let min = Infinity
let type, cur, c
for (let i = 0; i < lines.length; i++) {
var line = lines[i]
if (!emptyRE.test(line)) {
if (!type) {
c = line.charAt(0)
if (c === ' ' || c === '\t') {
type = c
cur = count(line, type)
if (cur < min) {
min = cur
}
} else {
return str
}
} else {
cur = count(line, type)
if (cur < min) {
min = cur
}
}
}
}
return lines.map(line => line.slice(min)).join('\n')
}
function count (line: string, type: string): number {
var i = 0
while (line.charAt(i) === type) {
i++
}
return i
}

46
src/compiler/parser/sfc-parser.js → src/sfc/parser.js

@ -1,15 +1,10 @@
/* @flow */
// this file is used in the vue-template-compiler npm package
// and assumes its dependencies and a Node/CommonJS environment
import deindent from 'de-indent'
import { SourceMapGenerator } from 'source-map'
import { parseHTML } from './html-parser'
import deindent from './deindent'
import { parseHTML } from 'compiler/parser/html-parser'
import { makeMap } from 'shared/util'
const splitRE = /\r?\n/g
const emptyRE = /^(?:\/\/)?\s*$/
const isSpecialTag = makeMap('script,style,template', true)
type Attribute = {
@ -82,50 +77,17 @@ export function parseComponent (
text = padContent(currentBlock) + text
}
currentBlock.content = text
if (options.map && !currentBlock.src) {
addSourceMap(currentBlock)
}
currentBlock = null
}
depth--
}
function padContent (block: SFCBlock) {
const offset = content.slice(0, block.start).split(splitRE).length
const padChar = block.type === 'script' && !block.lang
? '//\n'
: '\n'
return Array(getPaddingOffset(block) + 1).join(padChar)
}
function getPaddingOffset (block: SFCBlock) {
return content.slice(0, block.start).split(splitRE).length - 1
}
function addSourceMap (block: SFCBlock) {
const filename = options.map.filename
/* istanbul ignore if */
if (!filename) {
throw new Error('Should provide original filename in the map option.')
}
const offset = options.pad ? 0 : getPaddingOffset(block)
const map = new SourceMapGenerator()
map.setSourceContent(filename, content)
block.content.split(splitRE).forEach((line, index) => {
if (!emptyRE.test(line)) {
map.addMapping({
source: filename,
original: {
line: index + 1 + offset,
column: 0
},
generated: {
line: index + 1,
column: 0
}
})
}
})
block.map = JSON.parse(map.toString())
return Array(offset).join(padChar)
}
parseHTML(content, {

60
test/unit/modules/compiler/sfc-parser.spec.js

@ -1,5 +1,4 @@
import { parseComponent } from 'compiler/parser/sfc-parser'
import { SourceMapConsumer } from 'source-map'
import { parseComponent } from 'sfc/parser'
describe('Single File Component parser', () => {
it('should parse', () => {
@ -64,61 +63,4 @@ describe('Single File Component parser', () => {
expect(res.script.content).toBe(Array(3 + 1).join('//\n') + '\nexport default {}\n')
expect(res.styles[0].content).toBe(Array(6 + 1).join('\n') + '\nh1 { color: red }\n')
})
it('source map (without pad)', () => {
const res = parseComponent(`
<script>
export default {}
</script>
<style>
h1 { color: red }
</style>
`.trim(), {
map: {
filename: 'test.vue'
}
})
const scriptConsumer = new SourceMapConsumer(res.script.map)
const scriptPos = scriptConsumer.originalPositionFor({
line: 2,
column: 1
})
expect(scriptPos.line).toBe(2)
const styleConsumer = new SourceMapConsumer(res.styles[0].map)
const stylePos = styleConsumer.originalPositionFor({
line: 2,
column: 1
})
expect(stylePos.line).toBe(5)
})
it('source map (with pad)', () => {
const res = parseComponent(`
<script>
export default {}
</script>
<style>
h1 { color: red }
</style>
`.trim(), {
pad: true,
map: {
filename: 'test.vue'
}
})
const scriptConsumer = new SourceMapConsumer(res.script.map)
const scriptPos = scriptConsumer.originalPositionFor({
line: 2,
column: 1
})
expect(scriptPos.line).toBe(2)
const styleConsumer = new SourceMapConsumer(res.styles[0].map)
const stylePos = styleConsumer.originalPositionFor({
line: 5,
column: 1
})
expect(stylePos.line).toBe(5)
})
})

Loading…
Cancel
Save