From caa1538960ab97b70e4fff8ce84d446a7431226c Mon Sep 17 00:00:00 2001 From: Evan You Date: Sun, 3 Jun 2018 15:43:54 -0400 Subject: [PATCH] feat: allow/require compiler to be passed in for `parse` BREAKING CHANGE: vue template compiler must now be passed to `parse` via options. --- README.md | 17 ++++++++++++++--- lib/parse.ts | 13 ++++++++++--- lib/types.ts | 11 +++++++++++ package.json | 5 +---- test/compileStyle.spec.ts | 9 +++++++-- test/compileTemplate.spec.ts | 4 +++- 6 files changed, 46 insertions(+), 13 deletions(-) diff --git a/README.md b/README.md index 6eda2aa..4cc8600 100644 --- a/README.md +++ b/README.md @@ -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 } @@ -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/). @@ -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 diff --git a/lib/parse.ts b/lib/parse.ts index c66f9cf..3378f1e 100644 --- a/lib/parse.ts +++ b/lib/parse.ts @@ -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 @@ -11,6 +14,8 @@ const emptyRE = /^(?:\/\/)?\s*$/ export interface ParseOptions { source: string filename?: string + compiler: VueTemplateCompiler + compilerParseOptions?: VueTemplateCompilerParseOptions sourceRoot?: string needMap?: boolean } @@ -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( diff --git a/lib/types.ts b/lib/types.ts index 75b499d..6d45be8 100644 --- a/lib/types.ts +++ b/lib/types.ts @@ -1,3 +1,5 @@ +import { SFCDescriptor } from './parse' + export interface StartOfSourceMap { file?: string; sourceRoot?: string; @@ -12,6 +14,11 @@ export interface RawSourceMap extends StartOfSourceMap { } export interface VueTemplateCompiler { + parseComponent( + source: string, + options?: any + ): SFCDescriptor + compile( template: string, options: VueTemplateCompilerOptions @@ -30,6 +37,10 @@ export interface VueTemplateCompilerOptions { modules?: Object[] } +export interface VueTemplateCompilerParseOptions { + pad?: 'line' | 'space' +} + export interface VueTemplateCompilerResults { ast: Object | void render: string diff --git a/package.json b/package.json index 8e607d0..0822f12 100644 --- a/package.json +++ b/package.json @@ -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", @@ -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" } } diff --git a/test/compileStyle.spec.ts b/test/compileStyle.spec.ts index 9ecaf05..c027d08 100644 --- a/test/compileStyle.spec.ts +++ b/test/compileStyle.spec.ts @@ -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({ @@ -8,6 +9,7 @@ test('preprocess less', () => { '@red: rgb(255, 0, 0);\n' + '.color { color: @red; }\n' + '\n', + compiler, filename: 'example.vue', needMap: true }).styles[0] @@ -32,6 +34,7 @@ test('preprocess scss', () => { '$red: rgb(255, 0, 0);\n' + '.color { color: $red; }\n' + '\n', + compiler, filename: 'example.vue', needMap: true }).styles[0] @@ -57,6 +60,7 @@ test('preprocess sass', () => { '.color\n' + ' color: $red\n' + '\n', + compiler, filename: 'example.vue', needMap: true }).styles[0] @@ -82,6 +86,7 @@ test('preprocess stylus', () => { '.color\n' + ' color: red-color\n' + '\n', + compiler, filename: 'example.vue', needMap: true }).styles[0] @@ -101,7 +106,7 @@ test('preprocess stylus', () => { test('custom postcss plugin', () => { const spy = jest.fn() - + compileStyle({ id: 'v-scope-xxx', filename: 'example.vue', @@ -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')) diff --git a/test/compileTemplate.spec.ts b/test/compileTemplate.spec.ts index e638456..98b052e 100644 --- a/test/compileTemplate.spec.ts +++ b/test/compileTemplate.spec.ts @@ -11,6 +11,7 @@ test('preprocess pug', () => { ' div.container\n' + ' p Cool Pug example!\n' + '\n', + compiler, filename: 'example.vue', needMap: true }).template @@ -30,6 +31,7 @@ test('warn missing preprocessor', () => { source: '\n', + compiler, filename: 'example.vue', needMap: true }).template @@ -42,4 +44,4 @@ test('warn missing preprocessor', () => { }) expect(result.errors.length).toBe(1) -}) \ No newline at end of file +})