Skip to content

Commit

Permalink
feat: support optional @vue/compiler-sfc peer dep
Browse files Browse the repository at this point in the history
  • Loading branch information
yyx990803 committed Sep 21, 2021
1 parent 1a26253 commit 21725a4
Show file tree
Hide file tree
Showing 9 changed files with 145 additions and 61 deletions.
8 changes: 1 addition & 7 deletions package.json
Original file line number Diff line number Diff line change
Expand Up @@ -37,14 +37,8 @@
"loader-utils": "^2.0.0"
},
"peerDependencies": {
"@vue/compiler-sfc": "^3.2.12",
"webpack": "^4.1.0 || ^5.0.0-0"
},
"peerDependenciesMeta": {
"@vue/compiler-sfc": {
"optional": true
}
},
"devDependencies": {
"@babel/core": "^7.7.7",
"@babel/preset-env": "^7.11.5",
Expand Down Expand Up @@ -86,7 +80,7 @@
"ts-loader-v9": "npm:ts-loader@^9.2.4",
"typescript": "^4.4.3",
"url-loader": "^4.1.0",
"vue": "^3.2.12",
"vue": "^3.2.13",
"webpack": "^4.41.2",
"webpack-cli": "^3.3.10",
"webpack-dev-server": "^3.9.0",
Expand Down
25 changes: 25 additions & 0 deletions src/compiler.ts
Original file line number Diff line number Diff line change
@@ -0,0 +1,25 @@
// extend the descriptor so we can store the scopeId on it
declare module '@vue/compiler-sfc' {
interface SFCDescriptor {
id: string
}
}

import * as _compiler from '@vue/compiler-sfc'

export let compiler: typeof _compiler

try {
// Vue 3.2.13+ ships the SFC compiler directly under the `vue` package
// making it no longer necessary to have @vue/compiler-sfc separately installed.
compiler = require('vue/compiler-sfc')
} catch (e) {
try {
compiler = require('@vue/compiler-sfc')
} catch (e) {
throw new Error(
`@vitejs/plugin-vue requires vue (>=3.2.13) or @vue/compiler-sfc ` +
`to be present in the dependency tree.`
)
}
}
4 changes: 2 additions & 2 deletions src/descriptorCache.ts
Original file line number Diff line number Diff line change
@@ -1,6 +1,6 @@
import * as fs from 'fs'
import { SFCDescriptor } from '@vue/compiler-sfc'
import { parse } from '@vue/compiler-sfc'
import { compiler } from './compiler'

const cache = new Map<string, SFCDescriptor>()

Expand All @@ -20,7 +20,7 @@ export function getDescriptor(filename: string): SFCDescriptor {
// loaders being run in separate threads. The only way to deal with this is to
// read from disk directly...
const source = fs.readFileSync(filename, 'utf-8')
const { descriptor } = parse(source, {
const { descriptor } = compiler.parse(source, {
filename,
sourceMap: true,
})
Expand Down
9 changes: 7 additions & 2 deletions src/formatError.ts
Original file line number Diff line number Diff line change
@@ -1,4 +1,5 @@
import { generateCodeFrame, CompilerError } from '@vue/compiler-sfc'
import { CompilerError } from '@vue/compiler-sfc'
import { compiler } from './compiler'
import chalk = require('chalk')

export function formatError(
Expand All @@ -12,7 +13,11 @@ export function formatError(
}
const locString = `:${loc.start.line}:${loc.start.column}`
const filePath = chalk.gray(`at ${file}${locString}`)
const codeframe = generateCodeFrame(source, loc.start.offset, loc.end.offset)
const codeframe = compiler.generateCodeFrame(
source,
loc.start.offset,
loc.end.offset
)
err.message = `\n${chalk.red(
`VueCompilerError: ${err.message}`
)}\n${filePath}\n${chalk.yellow(codeframe)}\n`
Expand Down
13 changes: 2 additions & 11 deletions src/index.ts
Original file line number Diff line number Diff line change
@@ -1,21 +1,12 @@
try {
require.resolve('@vue/compiler-sfc')
} catch (e) {
throw new Error(
'vue-loader requires @vue/compiler-sfc to be present in the dependency ' +
'tree.'
)
}

import webpack = require('webpack')
import * as path from 'path'
import * as qs from 'querystring'
import * as loaderUtils from 'loader-utils'

import hash = require('hash-sum')

import { compiler } from './compiler'
import {
parse,
TemplateCompiler,
CompilerOptions,
SFCBlock,
Expand Down Expand Up @@ -102,7 +93,7 @@ export default function loader(
mode === 'production' || process.env.NODE_ENV === 'production'

const filename = resourcePath.replace(/\?.*$/, '')
const { descriptor, errors } = parse(source, {
const { descriptor, errors } = compiler.parse(source, {
filename,
sourceMap,
})
Expand Down
14 changes: 7 additions & 7 deletions src/resolveScript.ts
Original file line number Diff line number Diff line change
@@ -1,12 +1,12 @@
import webpack = require('webpack')
import {
compileScript,
SFCDescriptor,
SFCScriptBlock,
TemplateCompiler,
} from '@vue/compiler-sfc'
import { VueLoaderOptions } from 'src'
import { resolveTemplateTSOptions } from './util'
import { compiler } from './compiler'

const clientCache = new WeakMap<SFCDescriptor, SFCScriptBlock | null>()
const serverCache = new WeakMap<SFCDescriptor, SFCScriptBlock | null>()
Expand Down Expand Up @@ -46,24 +46,24 @@ export function resolveScript(

let resolved: SFCScriptBlock | null = null

let compiler: TemplateCompiler | undefined
let templateCompiler: TemplateCompiler | undefined
if (typeof options.compiler === 'string') {
compiler = require(options.compiler)
templateCompiler = require(options.compiler)
} else {
compiler = options.compiler
templateCompiler = options.compiler
}

if (compileScript) {
if (compiler.compileScript) {
try {
resolved = compileScript(descriptor, {
resolved = compiler.compileScript(descriptor, {
id: scopeId,
isProd,
inlineTemplate: enableInline,
refSugar: options.refSugar,
babelParserPlugins: options.babelParserPlugins,
templateOptions: {
ssr: isServer,
compiler,
compiler: templateCompiler,
compilerOptions: {
...options.compilerOptions,
...resolveTemplateTSOptions(descriptor, options.compilerOptions),
Expand Down
4 changes: 2 additions & 2 deletions src/stylePostLoader.ts
Original file line number Diff line number Diff line change
@@ -1,13 +1,13 @@
import * as qs from 'querystring'
import { compileStyle } from '@vue/compiler-sfc'
import { compiler } from './compiler'
import webpack = require('webpack')

// This is a post loader that handles scoped CSS transforms.
// Injected right before css-loader by the global pitcher (../pitch.js)
// for any <style scoped> selection requests initiated from within vue files.
const StylePostLoader: webpack.loader.Loader = function (source, inMap) {
const query = qs.parse(this.resourceQuery.slice(1))
const { code, map, errors } = compileStyle({
const { code, map, errors } = compiler.compileStyle({
source: source as string,
filename: this.resourcePath,
id: `data-v-${query.id}`,
Expand Down
13 changes: 7 additions & 6 deletions src/templateLoader.ts
Original file line number Diff line number Diff line change
Expand Up @@ -3,10 +3,11 @@ import * as qs from 'querystring'
import * as loaderUtils from 'loader-utils'
import { VueLoaderOptions } from './'
import { formatError } from './formatError'
import { compileTemplate, TemplateCompiler } from '@vue/compiler-sfc'
import { TemplateCompiler } from '@vue/compiler-sfc'
import { getDescriptor } from './descriptorCache'
import { resolveScript } from './resolveScript'
import { resolveTemplateTSOptions } from './util'
import { compiler } from './compiler'

// Loader that compiles raw template into JavaScript functions.
// This is injected by the global pitcher (../pitch) for template
Expand Down Expand Up @@ -40,14 +41,14 @@ const TemplateLoader: webpack.loader.Loader = function (source, inMap) {
loaderContext
)

let compiler: TemplateCompiler | undefined
let templateCompiler: TemplateCompiler | undefined
if (typeof options.compiler === 'string') {
compiler = require(options.compiler)
templateCompiler = require(options.compiler)
} else {
compiler = options.compiler
templateCompiler = options.compiler
}

const compiled = compileTemplate({
const compiled = compiler.compileTemplate({
source,
filename: loaderContext.resourcePath,
inMap,
Expand All @@ -57,7 +58,7 @@ const TemplateLoader: webpack.loader.Loader = function (source, inMap) {
isProd,
ssr: isServer,
ssrCssVars: descriptor.cssVars,
compiler,
compiler: templateCompiler,
compilerOptions: {
...options.compilerOptions,
scopeId: query.scoped ? `data-v-${scopeId}` : undefined,
Expand Down
116 changes: 92 additions & 24 deletions yarn.lock
Original file line number Diff line number Diff line change
Expand Up @@ -1410,6 +1410,16 @@
estree-walker "^2.0.2"
source-map "^0.6.1"

"@vue/compiler-core@3.2.13":
version "3.2.13"
resolved "https://registry.yarnpkg.com/@vue/compiler-core/-/compiler-core-3.2.13.tgz#901268088b98a53c43be0f02bfa0e3a389ad6bf4"
integrity sha512-H8MUuKVCfAT6C0vth/+1LAriKnM+RTFo/5MoFycwRPwworTvkpWq/EuGoIXdLBblo8Y2/bNsOmIBEEoOtrb/bQ==
dependencies:
"@babel/parser" "^7.15.0"
"@vue/shared" "3.2.13"
estree-walker "^2.0.2"
source-map "^0.6.1"

"@vue/compiler-dom@3.2.12":
version "3.2.12"
resolved "https://registry.yarnpkg.com/@vue/compiler-dom/-/compiler-dom-3.2.12.tgz#d6ba00114e73adb8b18940c3ff18797cc2b0514f"
Expand All @@ -1418,6 +1428,30 @@
"@vue/compiler-core" "3.2.12"
"@vue/shared" "3.2.12"

"@vue/compiler-dom@3.2.13":
version "3.2.13"
resolved "https://registry.yarnpkg.com/@vue/compiler-dom/-/compiler-dom-3.2.13.tgz#028982494fb9d97807d5275b42355732686f8ed7"
integrity sha512-5+2dYgQyNzM97EEgbdAusUpLjulcKkvLM26jOGpd14+qwEcW/KCnns5DGjlZD/tsdEwToOoTDCm+mjx7cO/G1Q==
dependencies:
"@vue/compiler-core" "3.2.13"
"@vue/shared" "3.2.13"

"@vue/compiler-sfc@3.2.13":
version "3.2.13"
resolved "https://registry.yarnpkg.com/@vue/compiler-sfc/-/compiler-sfc-3.2.13.tgz#a38475048aad9c96cf04dfe635129b417e0f9295"
integrity sha512-3j970d969aOILykcTstdihP33xH1Onm0wsvcl+rGv9AGxivB9xicRxBw93HCIA4dAPivr42WjHEoci9q2/85uw==
dependencies:
"@babel/parser" "^7.15.0"
"@vue/compiler-core" "3.2.13"
"@vue/compiler-dom" "3.2.13"
"@vue/compiler-ssr" "3.2.13"
"@vue/ref-transform" "3.2.13"
"@vue/shared" "3.2.13"
estree-walker "^2.0.2"
magic-string "^0.25.7"
postcss "^8.1.10"
source-map "^0.6.1"

"@vue/compiler-sfc@^3.2.12":
version "3.2.12"
resolved "https://registry.yarnpkg.com/@vue/compiler-sfc/-/compiler-sfc-3.2.12.tgz#39555550d96051508753ba934f7260dc5ee5211e"
Expand Down Expand Up @@ -1450,12 +1484,20 @@
"@vue/compiler-dom" "3.2.12"
"@vue/shared" "3.2.12"

"@vue/reactivity@3.2.12":
version "3.2.12"
resolved "https://registry.yarnpkg.com/@vue/reactivity/-/reactivity-3.2.12.tgz#b482a737cbdc891f9b1ec3100f3c1804b56d080b"
integrity sha512-Lr5CTQjFm5mT/6DGnVNhptmba/Qg1DbD6eNWWmiHLMlpPt4q2ww9A2orEjVw0qNcdTJ04JLPEVAz5jhTZTCfIg==
"@vue/compiler-ssr@3.2.13":
version "3.2.13"
resolved "https://registry.yarnpkg.com/@vue/compiler-ssr/-/compiler-ssr-3.2.13.tgz#98434672e0b488c2affa4b0570731d6be5cda187"
integrity sha512-ZbO6uDhUWTdKBRguYNEZXj2FU3nh1cudoHBiidbxj9q5J0tVT+j1PSVFAXPq6SquUBdJpa4HvGkQ5kQzv6upXg==
dependencies:
"@vue/shared" "3.2.12"
"@vue/compiler-dom" "3.2.13"
"@vue/shared" "3.2.13"

"@vue/reactivity@3.2.13":
version "3.2.13"
resolved "https://registry.yarnpkg.com/@vue/reactivity/-/reactivity-3.2.13.tgz#d269b09aaafef06a91bf3eb98defd41a2c3daf54"
integrity sha512-j3ByCiRgrr4uEZpXJM8XowrbYKeNHMHlbmMZE/2QpVzVPIfrQWS2fpLmbchJeMrnwIrzEl+dub3hgwkV4KRn4w==
dependencies:
"@vue/shared" "3.2.13"

"@vue/ref-transform@3.2.12":
version "3.2.12"
Expand All @@ -1468,28 +1510,52 @@
estree-walker "^2.0.2"
magic-string "^0.25.7"

"@vue/runtime-core@3.2.12":
version "3.2.12"
resolved "https://registry.yarnpkg.com/@vue/runtime-core/-/runtime-core-3.2.12.tgz#422662fd5b85f787222d2aea840264ba97e84a13"
integrity sha512-LO+ztgcmsomavYUaSq7BTteh8pmnUmvUnXUFVYdlcg3VCdYRS0ImlclpYsNHqjAk2gU+H09dr2PP0kL961xUfQ==
"@vue/ref-transform@3.2.13":
version "3.2.13"
resolved "https://registry.yarnpkg.com/@vue/ref-transform/-/ref-transform-3.2.13.tgz#6adfce50d388cc03683d9d2ba58f3a3bde5166f4"
integrity sha512-q6GXHZFzXjpx1K3UFRF8fa+xSmD9xV/FjhGzTNnfrryBr8tBUNYgP2f0s5K5N+21Ay7+MlQ1XXMUp8McGvsryQ==
dependencies:
"@vue/reactivity" "3.2.12"
"@vue/shared" "3.2.12"
"@babel/parser" "^7.15.0"
"@vue/compiler-core" "3.2.13"
"@vue/shared" "3.2.13"
estree-walker "^2.0.2"
magic-string "^0.25.7"

"@vue/runtime-dom@3.2.12":
version "3.2.12"
resolved "https://registry.yarnpkg.com/@vue/runtime-dom/-/runtime-dom-3.2.12.tgz#d9fe865dca36f9ca33ba327afdeb89ae2aa03f4c"
integrity sha512-+NSDqivgihvoPYbKFDmzFu1tW7SOzwc7r0b7T8vsJtooVPGxwtfAFZ6wyLtteOXXrCpyTR3kpyTCIp31uY7aJg==
"@vue/runtime-core@3.2.13":
version "3.2.13"
resolved "https://registry.yarnpkg.com/@vue/runtime-core/-/runtime-core-3.2.13.tgz#8b62f92642e56af71d0d35a9f0065daf6f9eb3fb"
integrity sha512-VQedL9Wa7yWMPVDrIkxzLCm6cWCDBoXcXc+jrsOJkqpWhEeA7+zGOsDsHzhLH8aaJD6vdnUR5Cy0EKvoJDqEWQ==
dependencies:
"@vue/runtime-core" "3.2.12"
"@vue/shared" "3.2.12"
"@vue/reactivity" "3.2.13"
"@vue/shared" "3.2.13"

"@vue/runtime-dom@3.2.13":
version "3.2.13"
resolved "https://registry.yarnpkg.com/@vue/runtime-dom/-/runtime-dom-3.2.13.tgz#238f517a75765719f8373409cee853775c636f92"
integrity sha512-DVG+ItkrnCOEa9HSrmGBTLwv/gBVYCO8wkm/yv+d5ChoTnyIILxP0oCiZEPJsgWZfUSRPNi5rXozwo7F99MiwQ==
dependencies:
"@vue/runtime-core" "3.2.13"
"@vue/shared" "3.2.13"
csstype "^2.6.8"

"@vue/server-renderer@3.2.13":
version "3.2.13"
resolved "https://registry.yarnpkg.com/@vue/server-renderer/-/server-renderer-3.2.13.tgz#b10a564be67eec6721f90b36c3c817c19e6064b4"
integrity sha512-KI+JFV+vRb95+Jb6IwRRm4Vhvj8wrJTNs+OlATfqwwIRpBGAyxn/4knDJYzlnUf/mrKAkrbw751mHhi+pEwILQ==
dependencies:
"@vue/compiler-ssr" "3.2.13"
"@vue/shared" "3.2.13"

"@vue/shared@3.2.12":
version "3.2.12"
resolved "https://registry.yarnpkg.com/@vue/shared/-/shared-3.2.12.tgz#304064a4b56fc6c7b9169d80e9ee62ecb4bf0a1c"
integrity sha512-5CkaifUCJwcTuru7FDwKFacPJuEoGUTw0LKSa5bw40B23s0TS+MGlYR1285nbV/ju3QUGlA6d6PD+GJkWy7uFg==

"@vue/shared@3.2.13":
version "3.2.13"
resolved "https://registry.yarnpkg.com/@vue/shared/-/shared-3.2.13.tgz#c830ef966d7af12598e0ea862a55695ea589cd47"
integrity sha512-F/gs3kHQ8Xeo24F6EImOvBiIoYQsBjF9qoLzvk+LHxYN6ZhIDEL1NWrBFYzdFQ7NphjEYd4EvPZ+Qee+WX8P6w==

"@webassemblyjs/ast@1.11.1":
version "1.11.1"
resolved "https://registry.yarnpkg.com/@webassemblyjs/ast/-/ast-1.11.1.tgz#2bfd767eae1a6996f432ff7e8d7fc75679c0b6a7"
Expand Down Expand Up @@ -9668,14 +9734,16 @@ void-elements@^2.0.1:
resolved "https://registry.yarnpkg.com/void-elements/-/void-elements-2.0.1.tgz#c066afb582bb1cb4128d60ea92392e94d5e9dbec"
integrity sha1-wGavtYK7HLQSjWDqkjkulNXp2+w=

vue@^3.2.12:
version "3.2.12"
resolved "https://registry.yarnpkg.com/vue/-/vue-3.2.12.tgz#b44f55506fb6a7c4b65635e609deb5f9368aa2ce"
integrity sha512-VV14HtubmB56uuQaSvLkJZgoocPiN8CJI3zZA9y8h7q/Z5hcknDIFkbq5d8ku0ukZ6AJPQqMsZWcq0qryF0jgg==
vue@^3.2.13:
version "3.2.13"
resolved "https://registry.yarnpkg.com/vue/-/vue-3.2.13.tgz#9d1a94fc62dc29ae21a3dd0d8ee24198e421671e"
integrity sha512-raTGvLXXTdMxrhQKY1r1YFXZMmjbjTe7QHBW9EU4CgCBhq8DbgyLqgILcSUZmeFyazk5WY7a7xu0VYmHElf4lA==
dependencies:
"@vue/compiler-dom" "3.2.12"
"@vue/runtime-dom" "3.2.12"
"@vue/shared" "3.2.12"
"@vue/compiler-dom" "3.2.13"
"@vue/compiler-sfc" "3.2.13"
"@vue/runtime-dom" "3.2.13"
"@vue/server-renderer" "3.2.13"
"@vue/shared" "3.2.13"

w3c-hr-time@^1.0.2:
version "1.0.2"
Expand Down

1 comment on commit 21725a4

@mbrodala
Copy link

Choose a reason for hiding this comment

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

Same as my comment in 11e3cb8: why is there no official release on Github for this?

image

Please sign in to comment.