Skip to content

Commit

Permalink
feat: allow/require compiler to be passed in for parse
Browse files Browse the repository at this point in the history
BREAKING CHANGE: vue template compiler must now be passed to `parse`
via options.
  • Loading branch information
yyx990803 committed Jun 3, 2018
1 parent 9ce8522 commit caa1538
Show file tree
Hide file tree
Showing 6 changed files with 46 additions and 13 deletions.
17 changes: 14 additions & 3 deletions README.md
Original file line number Diff line number Diff line change
Expand Up @@ -6,16 +6,26 @@ This package contains lower level utilities that you can use if you are writing

The API surface is intentionally minimal - the goal is to reuse as much as possible while being as flexible as possible.

## Why isn't `vue-template-compiler` a peerDependency?

Since this package is more often used as a low-level utility, it is usually a transitive dependency in an actual Vue project. It is therefore the responsibility of the higher-level package (e.g. `vue-loader`) to inject `vue-template-compiler` via options when calling the `parse` and `compileTemplate` methods.

Not listing it as a peer depedency also allows tooling authors to use a non-default template compiler instead of `vue-template-compiler` without having to include it just to fullfil the peer dep requirement.

## API

### parse(ParseOptions): SFCDescriptor

Parse raw single file component source into a descriptor with source maps.
Parse raw single file component source into a descriptor with source maps. The actual compiler (`vue-template-compiler`) must be passed in via the `compiler` option so that the specific version used can be determined by the end user.

``` ts
interface ParseOptions {
source: string
filename?: string
compiler: VueTemplateCompiler
// https://github.com/vuejs/vue/tree/dev/packages/vue-template-compiler#compilerparsecomponentfile-options
// defualt: { pad: 'line' }
compilerParseOptions?: VueTemplateCompilerParseOptions
sourceRoot?: string
needMap?: boolean
}
Expand Down Expand Up @@ -46,7 +56,7 @@ interface SFCBlock extends SFCCustomBlock {

### compileTemplate(TemplateCompileOptions): TemplateCompileResults

Takes raw template source and compile it into JavaScript code. The actual compiler (`vue-template-compiler`) must be passed so that the specific version used can be determined by the end user.
Takes raw template source and compile it into JavaScript code. The actual compiler (`vue-template-compiler`) must be passed in via the `compiler` option so that the specific version used can be determined by the end user.

It can also optionally perform pre-processing for any templating engine supported by [consolidate](https://github.com/tj/consolidate.js/).

Expand All @@ -55,8 +65,9 @@ interface TemplateCompileOptions {
source: string
filename: string

// See https://github.com/vuejs/vue/tree/dev/packages/vue-template-compiler
compiler: VueTemplateCompiler
https://github.com/vuejs/vue/tree/dev/packages/vue-template-compiler#compilercompiletemplate-options
// default: {}
compilerOptions?: VueTemplateCompilerOptions

// Template preprocessor
Expand Down
13 changes: 10 additions & 3 deletions lib/parse.ts
Original file line number Diff line number Diff line change
@@ -1,8 +1,11 @@
import { RawSourceMap } from './types'
import {
RawSourceMap,
VueTemplateCompiler,
VueTemplateCompilerParseOptions
} from './types'

const hash = require('hash-sum')
const cache = require('lru-cache')(100)
const compiler = require('vue-template-compiler')
const { SourceMapGenerator } = require('source-map')

const splitRE = /\r?\n/g
Expand All @@ -11,6 +14,8 @@ const emptyRE = /^(?:\/\/)?\s*$/
export interface ParseOptions {
source: string
filename?: string
compiler: VueTemplateCompiler
compilerParseOptions?: VueTemplateCompilerParseOptions
sourceRoot?: string
needMap?: boolean
}
Expand Down Expand Up @@ -42,13 +47,15 @@ export function parse(options: ParseOptions): SFCDescriptor {
const {
source,
filename = '',
compiler,
compilerParseOptions = { pad: 'line' },
sourceRoot = process.cwd(),
needMap = true
} = options
const cacheKey = hash(filename + source)
let output: SFCDescriptor = cache.get(cacheKey)
if (output) return output
output = compiler.parseComponent(source, { pad: 'line' })
output = compiler.parseComponent(source, compilerParseOptions)
if (needMap) {
if (output.script && !output.script.src) {
output.script.map = generateSourceMap(
Expand Down
11 changes: 11 additions & 0 deletions lib/types.ts
Original file line number Diff line number Diff line change
@@ -1,3 +1,5 @@
import { SFCDescriptor } from './parse'

export interface StartOfSourceMap {
file?: string;
sourceRoot?: string;
Expand All @@ -12,6 +14,11 @@ export interface RawSourceMap extends StartOfSourceMap {
}

export interface VueTemplateCompiler {
parseComponent(
source: string,
options?: any
): SFCDescriptor

compile(
template: string,
options: VueTemplateCompilerOptions
Expand All @@ -30,6 +37,10 @@ export interface VueTemplateCompilerOptions {
modules?: Object[]
}

export interface VueTemplateCompilerParseOptions {
pad?: 'line' | 'space'
}

export interface VueTemplateCompilerResults {
ast: Object | void
render: string
Expand Down
5 changes: 1 addition & 4 deletions package.json
Original file line number Diff line number Diff line change
@@ -1,6 +1,6 @@
{
"name": "@vue/component-compiler-utils",
"version": "1.3.1",
"version": "1.4.0",
"description": "Lower level utilities for compiling Vue single file components",
"main": "dist/index.js",
"typings": "dist/index.d.ts",
Expand Down Expand Up @@ -48,8 +48,5 @@
"prettier": "^1.13.0",
"source-map": "^0.5.6",
"vue-template-es2015-compiler": "^1.6.0"
},
"peerDependencies": {
"vue-template-compiler": "^2.0.0"
}
}
9 changes: 7 additions & 2 deletions test/compileStyle.spec.ts
Original file line number Diff line number Diff line change
@@ -1,5 +1,6 @@
import { parse } from '../lib/parse'
import { compileStyle, compileStyleAsync } from '../lib/compileStyle'
import * as compiler from 'vue-template-compiler'

test('preprocess less', () => {
const style = parse({
Expand All @@ -8,6 +9,7 @@ test('preprocess less', () => {
'@red: rgb(255, 0, 0);\n' +
'.color { color: @red; }\n' +
'</style>\n',
compiler,
filename: 'example.vue',
needMap: true
}).styles[0]
Expand All @@ -32,6 +34,7 @@ test('preprocess scss', () => {
'$red: rgb(255, 0, 0);\n' +
'.color { color: $red; }\n' +
'</style>\n',
compiler,
filename: 'example.vue',
needMap: true
}).styles[0]
Expand All @@ -57,6 +60,7 @@ test('preprocess sass', () => {
'.color\n' +
' color: $red\n' +
'</style>\n',
compiler,
filename: 'example.vue',
needMap: true
}).styles[0]
Expand All @@ -82,6 +86,7 @@ test('preprocess stylus', () => {
'.color\n' +
' color: red-color\n' +
'</style>\n',
compiler,
filename: 'example.vue',
needMap: true
}).styles[0]
Expand All @@ -101,7 +106,7 @@ test('preprocess stylus', () => {

test('custom postcss plugin', () => {
const spy = jest.fn()

compileStyle({
id: 'v-scope-xxx',
filename: 'example.vue',
Expand Down Expand Up @@ -148,7 +153,7 @@ test('async postcss plugin', async () => {
})

expect(promise instanceof Promise).toBe(true)

const result = await promise
expect(result.errors).toHaveLength(0)
expect(result.code).toEqual(expect.stringContaining('color: red'))
Expand Down
4 changes: 3 additions & 1 deletion test/compileTemplate.spec.ts
Original file line number Diff line number Diff line change
Expand Up @@ -11,6 +11,7 @@ test('preprocess pug', () => {
' div.container\n' +
' p Cool Pug example!\n' +
'</template>\n',
compiler,
filename: 'example.vue',
needMap: true
}).template
Expand All @@ -30,6 +31,7 @@ test('warn missing preprocessor', () => {
source:
'<template lang="unknownLang">\n' +
'</template>\n',
compiler,
filename: 'example.vue',
needMap: true
}).template
Expand All @@ -42,4 +44,4 @@ test('warn missing preprocessor', () => {
})

expect(result.errors.length).toBe(1)
})
})

0 comments on commit caa1538

Please sign in to comment.