Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

feat: support <script setup> in Vue 2.7 #483

Closed
wants to merge 5 commits into from
Closed
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension


Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
4 changes: 2 additions & 2 deletions e2e/2.x/babel-in-package/package.json
Original file line number Diff line number Diff line change
Expand Up @@ -8,8 +8,8 @@
},
"dependencies": {
"source-map": "0.5.6",
"vue": "^2.5.21",
"vue-template-compiler": "^2.5.21"
"vue": "^2.7.7",
"vue-template-compiler": "^2.7.7"
},
"devDependencies": {
"@babel/core": "^7.9.0",
Expand Down
20 changes: 20 additions & 0 deletions e2e/2.x/basic/components/ScriptSetup.vue
Original file line number Diff line number Diff line change
@@ -0,0 +1,20 @@
<template>
<div>
<button @click="increase">Count: {{ num }}</button>
<Basic />
<span>{{ msg }}</span>
</div>
</template>

<script lang="ts" setup>
import { ref } from 'vue'
import Basic from './Basic.vue'

const num = ref(5)
const greet = () => console.log('greet')
const increase = () => {
greet()
num.value++
}
const msg = 'hello world'
</script>
4 changes: 2 additions & 2 deletions e2e/2.x/basic/package.json
Original file line number Diff line number Diff line change
Expand Up @@ -7,8 +7,8 @@
"test": "jest --no-cache --coverage test.js"
},
"dependencies": {
"vue": "^2.5.21",
"vue-template-compiler": "^2.5.21"
"vue": "^2.7.7",
"vue-template-compiler": "^2.7.7"
},
"devDependencies": {
"@babel/core": "^7.9.0",
Expand Down
7 changes: 7 additions & 0 deletions e2e/2.x/basic/test.js
Original file line number Diff line number Diff line change
Expand Up @@ -20,6 +20,7 @@ import PugRelative from './components/PugRelativeExtends.vue'
import Jsx from './components/Jsx.vue'
import Constructor from './components/Constructor.vue'
import { compileStyle } from '@vue/component-compiler-utils'
import ScriptSetup from './components/ScriptSetup'
jest.mock('@vue/component-compiler-utils', () => ({
...jest.requireActual('@vue/component-compiler-utils'),
compileStyle: jest.fn(() => ({ errors: [], code: '' }))
Expand Down Expand Up @@ -156,6 +157,12 @@ test('processes SFC with no template', () => {
expect(wrapper.element.tagName).toBe('SECTION')
})

test('processes SFC with <script setup>', () => {
const wrapper = mount(ScriptSetup)
expect(wrapper.html()).toContain('Count: 5')
expect(wrapper.html()).toContain('Welcome to Your Vue.js App')
})

test('should pass properly "styleOptions" into "preprocessOptions"', () => {
const filePath = resolve(__dirname, './components/Basic.vue')
const fileString = readFileSync(filePath, { encoding: 'utf8' })
Expand Down
4 changes: 2 additions & 2 deletions e2e/2.x/custom-transformers/package.json
Original file line number Diff line number Diff line change
Expand Up @@ -7,8 +7,8 @@
"test": "jest --no-cache --coverage test.js"
},
"dependencies": {
"vue": "^2.5.21",
"vue-template-compiler": "^2.5.21"
"vue": "^2.7.7",
"vue-template-compiler": "^2.7.7"
},
"devDependencies": {
"@babel/core": "^7.9.0",
Expand Down
4 changes: 2 additions & 2 deletions e2e/2.x/sass-importer/entry/package.json
Original file line number Diff line number Diff line change
Expand Up @@ -7,8 +7,8 @@
"test": "jest --no-cache --coverage test.js"
},
"dependencies": {
"vue": "^2.5.21",
"vue-template-compiler": "^2.5.21",
"vue": "^2.7.7",
"vue-template-compiler": "^2.7.7",
"vue2-sass-importer-lib": "file:../lib",
"vue2-sass-importer-sass-lib": "file:../sass-lib-v2"
},
Expand Down
2 changes: 1 addition & 1 deletion e2e/2.x/sass-importer/lib/package.json
Original file line number Diff line number Diff line change
Expand Up @@ -14,6 +14,6 @@
"vue2-sass-importer-sass-lib": "file:../sass-lib-v1"
},
"peerDependencies": {
"vue": "^2.5.21"
"vue": "^2.7.7"
}
}
4 changes: 2 additions & 2 deletions e2e/2.x/style/package.json
Original file line number Diff line number Diff line change
Expand Up @@ -7,8 +7,8 @@
"test": "node setup.js && jest --no-cache test.js"
},
"dependencies": {
"vue": "^2.5.21",
"vue-template-compiler": "^2.5.21"
"vue": "^2.7.7",
"vue-template-compiler": "^2.7.7"
},
"devDependencies": {
"@babel/core": "^7.9.0",
Expand Down
6 changes: 4 additions & 2 deletions packages/vue2-jest/lib/generate-code.js
Original file line number Diff line number Diff line change
Expand Up @@ -4,6 +4,7 @@ const splitRE = /\r?\n/g

module.exports = function generateCode(
scriptResult,
scriptSetupResult,
templateResult,
stylesResult,
customBlocksResult,
Expand All @@ -13,8 +14,9 @@ module.exports = function generateCode(
let renderFnStartLine
let renderFnEndLine

if (scriptResult) {
output += `${scriptResult.code};\n`
const finalScriptResult = scriptResult || scriptSetupResult
if (finalScriptResult) {
output += `${finalScriptResult.code};\n`
} else {
output +=
`Object.defineProperty(exports, "__esModule", {\n` +
Expand Down
10 changes: 7 additions & 3 deletions packages/vue2-jest/lib/generate-source-map.js
Original file line number Diff line number Diff line change
Expand Up @@ -4,6 +4,7 @@ const splitRE = /\r?\n/g

module.exports = function generateSourceMap(
scriptResult,
scriptSetupResult,
src,
filename,
renderFnStartLine,
Expand All @@ -20,10 +21,13 @@ module.exports = function generateSourceMap(
const srcContent = scriptFromExternalSrc ? scriptResult.externalSrc : src

map.setSourceContent(file, srcContent)
if (scriptResult) {

const finalScriptResult = scriptResult || scriptSetupResult
if (finalScriptResult) {
let inputMapConsumer =
scriptResult.map && new sourceMap.SourceMapConsumer(scriptResult.map)
scriptResult.code.split(splitRE).forEach(function(line, index) {
finalScriptResult.map &&
new sourceMap.SourceMapConsumer(finalScriptResult.map)
finalScriptResult.code.split(splitRE).forEach(function(line, index) {
let ln = index + 1
let originalLine = inputMapConsumer
? inputMapConsumer.originalPositionFor({ line: ln, column: 0 }).line
Expand Down
55 changes: 55 additions & 0 deletions packages/vue2-jest/lib/map-lines.js
Original file line number Diff line number Diff line change
@@ -0,0 +1,55 @@
const { SourceMapGenerator, SourceMapConsumer } = require('source-map')

// based on @vue/compiler-sfc mapLines
module.exports = function mapLines(oldMap, newMap) {
if (!oldMap) return newMap
if (!newMap) return oldMap

const oldMapConsumer = new SourceMapConsumer(oldMap)
const newMapConsumer = new SourceMapConsumer(newMap)
const mergedMapGenerator = new SourceMapGenerator()

newMapConsumer.eachMapping(m => {
if (m.originalLine == null) {
return
}

const origPosInOldMap = oldMapConsumer.originalPositionFor({
line: m.originalLine,
column: m.originalColumn
})

if (origPosInOldMap.source == null) {
return
}

mergedMapGenerator.addMapping({
generated: {
line: m.generatedLine,
column: m.generatedColumn
},
original: {
line: origPosInOldMap.line, // map line
// use current column, since the oldMap produced by @vue/compiler-sfc
// does not
column: m.originalColumn
},
source: origPosInOldMap.source,
name: origPosInOldMap.name
})
})

// source-map's type definition is incomplete
const generator = mergedMapGenerator
oldMapConsumer.sources.forEach(sourceFile => {
generator._sources.add(sourceFile)
const sourceContent = oldMapConsumer.sourceContentFor(sourceFile)
if (sourceContent != null) {
mergedMapGenerator.setSourceContent(sourceFile, sourceContent)
}
})

generator._sourceRoot = oldMap.sourceRoot
generator._file = oldMap.file
return generator.toJSON()
}
48 changes: 43 additions & 5 deletions packages/vue2-jest/lib/process.js
Original file line number Diff line number Diff line change
Expand Up @@ -11,8 +11,9 @@ const stripInlineSourceMap = require('./utils').stripInlineSourceMap
const getCustomTransformer = require('./utils').getCustomTransformer
const loadSrc = require('./utils').loadSrc
const babelTransformer = require('babel-jest').default
const compilerUtils = require('@vue/component-compiler-utils')
const { parse, compileTemplate, compileScript } = require('@vue/compiler-sfc')
Copy link
Contributor

@thebanjomatic thebanjomatic Jul 18, 2022

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

@vue/compiler-sfc isn't listed as a dependency of this package, so this import is unsound. There is a similar existing issue for the vue-template-compiler import as well (which should probably have been listed as an optional peer dependency).

I know there are other changes in vue 2.7 that make vue-template-compiler no longer necessary, so there might be larger refactors in the works for that.

Copy link
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Isn't @vue/compiler-sfc Vue 3 only? I'm really surprised this works at all.

Copy link
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Also looks like tests are failing - you may need to update a snapshot.

Copy link
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Oh I see, they now have a v2.7 for this module: https://www.npmjs.com/package/@vue/compiler-sfc

const generateCode = require('./generate-code')
const mapLines = require('./map-lines')

function resolveTransformer(lang = 'js', vueJestConfig) {
const transformer = getCustomTransformer(vueJestConfig['transform'], lang)
Expand Down Expand Up @@ -45,7 +46,31 @@ function processScript(scriptPart, filePath, config) {
return result
}

function processTemplate(template, filename, config) {
function processScriptSetup(descriptor, filePath, config) {
if (!descriptor.scriptSetup) {
return null
}
const vueJestConfig = getVueJestConfig(config)
const content = compileScript(descriptor, {
id: filePath,
...vueJestConfig.compilerOptions
})
const contentMap = mapLines(descriptor.scriptSetup.map, content.map)

const transformer = resolveTransformer(
descriptor.scriptSetup.lang,
vueJestConfig
)

const result = transformer.process(content.content, filePath, config)
result.map = mapLines(contentMap, result.map)

return result
}

function processTemplate(descriptor, filename, config) {
const { template, scriptSetup } = descriptor

if (!template) {
return null
}
Expand All @@ -56,14 +81,24 @@ function processTemplate(template, filename, config) {
template.content = loadSrc(template.src, filename)
}

let bindings
if (scriptSetup) {
const scriptSetupResult = compileScript(descriptor, {
id: filename,
...vueJestConfig.compilerOptions
})
bindings = scriptSetupResult.bindings
}

const userTemplateCompilerOptions = vueJestConfig.templateCompiler || {}
const result = compilerUtils.compileTemplate({
const result = compileTemplate({
source: template.content,
compiler: VueTemplateCompiler,
filename: filename,
isFunctional: template.attrs.functional,
preprocessLang: template.lang,
preprocessOptions: vueJestConfig[template.lang],
bindings,
...userTemplateCompilerOptions,
compilerOptions: {
optimize: false,
Expand Down Expand Up @@ -92,14 +127,15 @@ function processStyle(styles, filename, config) {
}

module.exports = function(src, filename, config) {
const descriptor = compilerUtils.parse({
const descriptor = parse({
source: src,
compiler: VueTemplateCompiler,
filename
})

const templateResult = processTemplate(descriptor.template, filename, config)
const templateResult = processTemplate(descriptor, filename, config)
const scriptResult = processScript(descriptor.script, filename, config)
const scriptSetupResult = processScriptSetup(descriptor, filename, config)
const stylesResult = processStyle(descriptor.styles, filename, config)
const customBlocksResult = processCustomBlocks(
descriptor.customBlocks,
Expand All @@ -120,6 +156,7 @@ module.exports = function(src, filename, config) {

const output = generateCode(
scriptResult,
scriptSetupResult,
templateResult,
stylesResult,
customBlocksResult,
Expand All @@ -128,6 +165,7 @@ module.exports = function(src, filename, config) {

const map = generateSourceMap(
scriptResult,
scriptSetupResult,
src,
filename,
output.renderFnStartLine,
Expand Down
4 changes: 2 additions & 2 deletions packages/vue2-jest/package.json
Original file line number Diff line number Diff line change
Expand Up @@ -34,8 +34,8 @@
"semantic-release": "^15.13.2",
"ts-jest": "^28.0.1",
"typescript": "^4.6.4",
"vue": "^2.4.2",
"vue-template-compiler": "^2.4.2"
"vue": "^2.7.7",
"vue-template-compiler": "^2.7.7"
},
"peerDependencies": {
"@babel/core": "7.x",
Expand Down
Loading