Skip to content

Commit

Permalink
feat: support <script setup>
Browse files Browse the repository at this point in the history
  • Loading branch information
yyx990803 committed Sep 4, 2020
1 parent eec3c80 commit fb09c8b
Show file tree
Hide file tree
Showing 11 changed files with 144 additions and 74 deletions.
7 changes: 5 additions & 2 deletions example/App.vue
Original file line number Diff line number Diff line change
Expand Up @@ -3,19 +3,22 @@
<div>
{{ count }}
<span>{{ count }}</span>
<Button><span>slot</span></Button>
<Button foo="hello!"><span>slot</span></Button>
<ScriptSetup/>
</div>
</template>

<script>
import Button from './Button.vue'
import ScriptSetup from './ScriptSetup.vue'
export default {
data() {
return { count: 0 }
},
components: {
Button
Button,
ScriptSetup
}
}
</script>
Expand Down
6 changes: 5 additions & 1 deletion example/Button.vue
Original file line number Diff line number Diff line change
@@ -1,4 +1,5 @@
<template>
<p>prop foo: {{ foo }}</p>
<button @click="inc">{{ count }}</button>
<slot/>
</template>
Expand All @@ -7,7 +8,10 @@
import { ref } from 'vue'
export default {
setup() {
props: {
foo: String
},
setup(props) {
const count = ref(0)
return {
count,
Expand Down
20 changes: 20 additions & 0 deletions example/ScriptSetup.vue
Original file line number Diff line number Diff line change
@@ -0,0 +1,20 @@
<template>
<h2>{{ hello }}</h2>
<div>
{{ count }} <button @click="inc">+</button>
<Button/>
</div>
</template>

<script setup>
import { ref } from 'vue'
export { default as Button } from './Button.vue'
export const count = ref(0)
export function inc() {
count.value++
}
export const hello = 'hi from script setup'
</script>
7 changes: 6 additions & 1 deletion example/webpack.config.js
Original file line number Diff line number Diff line change
@@ -1,7 +1,8 @@
const fs = require('fs')
const path = require('path')
const webpack = require('webpack')
const hash = require('hash-sum')
const VueLoaderPlugin = require('../dist/plugin')
const VueLoaderPlugin = require('../dist/plugin').default
const MiniCssExtractPlugin = require('mini-css-extract-plugin')

module.exports = (env = {}) => {
Expand Down Expand Up @@ -86,6 +87,10 @@ module.exports = (env = {}) => {
new VueLoaderPlugin(),
new MiniCssExtractPlugin({
filename: '[name].css'
}),
new webpack.DefinePlugin({
__VUE_OPTIONS_API__: true,
__VUE_PROD_DEVTOOLS__: false
})
],
optimization: {
Expand Down
4 changes: 2 additions & 2 deletions package.json
Original file line number Diff line number Diff line change
Expand Up @@ -48,7 +48,7 @@
"@types/loader-utils": "^1.1.3",
"@types/webpack": "^4.41.0",
"@types/webpack-merge": "^4.1.5",
"@vue/compiler-sfc": "^3.0.0-rc.6",
"@vue/compiler-sfc": "^3.0.0-rc.10",
"babel-loader": "^8.0.6",
"cache-loader": "^4.1.0",
"css-loader": "^3.3.2",
Expand All @@ -65,7 +65,7 @@
"ts-jest": "^26.2.0",
"typescript": "^4.0.2",
"url-loader": "^3.0.0",
"vue": "^3.0.0-rc.6",
"vue": "^3.0.0-rc.10",
"webpack": "^4.41.2",
"webpack-cli": "^3.3.10",
"webpack-dev-server": "^3.9.0",
Expand Down
46 changes: 33 additions & 13 deletions src/index.ts
Original file line number Diff line number Diff line change
Expand Up @@ -14,11 +14,14 @@ import hash from 'hash-sum'
import loaderUtils from 'loader-utils'
import {
parse,
compileScript,
TemplateCompiler,
CompilerOptions,
SFCBlock,
SFCTemplateCompileOptions,
SFCStyleBlock
SFCScriptCompileOptions,
SFCStyleBlock,
SFCScriptBlock
} from '@vue/compiler-sfc'
import { selectBlock } from './select'
import { genHotReloadCode } from './hotReload'
Expand All @@ -30,6 +33,8 @@ import VueLoaderPlugin from './plugin'
export { VueLoaderPlugin }

export interface VueLoaderOptions {
// https://babeljs.io/docs/en/next/babel-parser#plugins
babelParserPlugins?: SFCScriptCompileOptions['babelParserPlugins']
transformAssetUrls?: SFCTemplateCompileOptions['transformAssetUrls']
compiler?: TemplateCompiler | string
compilerOptions?: CompilerOptions
Expand Down Expand Up @@ -121,6 +126,29 @@ export default function loader(
!!(descriptor.script || descriptor.template) &&
options.hotReload !== false

// script
let script: SFCScriptBlock | undefined
let scriptImport = `const script = {}`
if (descriptor.script || descriptor.scriptSetup) {
try {
script = (descriptor as any).scriptCompiled = compileScript(descriptor, {
babelParserPlugins: options.babelParserPlugins
})
} catch (e) {
loaderContext.emitError(e)
}
if (script) {
const src = script.src || resourcePath
const attrsQuery = attrsToQuery(script.attrs, 'js')
const query = `?vue&type=script${attrsQuery}${resourceQuery}`
const scriptRequest = stringifyRequest(src + query)
scriptImport =
`import script from ${scriptRequest}\n` +
// support named exports
`export * from ${scriptRequest}`
}
}

// template
let templateImport = ``
let templateRequest
Expand All @@ -129,22 +157,14 @@ export default function loader(
const idQuery = `&id=${id}`
const scopedQuery = hasScoped ? `&scoped=true` : ``
const attrsQuery = attrsToQuery(descriptor.template.attrs)
const query = `?vue&type=template${idQuery}${scopedQuery}${attrsQuery}${resourceQuery}`
const bindingsQuery = script
? `&bindings=${JSON.stringify(script.bindings)}`
: ``
const query = `?vue&type=template${idQuery}${scopedQuery}${attrsQuery}${bindingsQuery}${resourceQuery}`
templateRequest = stringifyRequest(src + query)
templateImport = `import { render } from ${templateRequest}`
}

// script
let scriptImport = `const script = {}`
if (descriptor.script) {
const src = descriptor.script.src || resourcePath
const attrsQuery = attrsToQuery(descriptor.script.attrs, 'js')
const query = `?vue&type=script${attrsQuery}${resourceQuery}`
const scriptRequest = stringifyRequest(src + query)
scriptImport =
`import script from ${scriptRequest}\n` + `export * from ${scriptRequest}` // support named exports
}

// styles
let stylesCode = ``
let hasCSSModules = false
Expand Down
2 changes: 1 addition & 1 deletion src/select.ts
Original file line number Diff line number Diff line change
Expand Up @@ -22,7 +22,7 @@ export function selectBlock(

// script
if (query.type === `script`) {
const script = descriptor.script!
const script = (descriptor as any).scriptCompiled
if (appendExtension) {
loaderContext.resourcePath += '.' + (script.lang || 'js')
}
Expand Down
3 changes: 2 additions & 1 deletion src/templateLoader.ts
Original file line number Diff line number Diff line change
Expand Up @@ -37,7 +37,8 @@ const TemplateLoader: webpack.loader.Loader = function(source, inMap) {
compiler,
compilerOptions: {
...options.compilerOptions,
scopeId
scopeId,
bindingMetadata: JSON.parse(query.bindings as string)
},
transformAssetUrls: options.transformAssetUrls || true
})
Expand Down
4 changes: 4 additions & 0 deletions test/core.spec.ts
Original file line number Diff line number Diff line change
Expand Up @@ -3,3 +3,7 @@ import { bundle } from './utils'
test('basic', async () => {
await bundle({ entry: 'basic.vue' })
})

test('script setup', async () => {
await bundle({ entry: 'ScriptSetup.vue' })
})
13 changes: 13 additions & 0 deletions test/fixtures/ScriptSetup.vue
Original file line number Diff line number Diff line change
@@ -0,0 +1,13 @@
<template>
<button @click="inc">{{ count }}</button>
</template>

<script setup>
import { ref } from 'vue'
export const count = ref(0)
export function inc() {
count.value++
}
</script>
106 changes: 53 additions & 53 deletions yarn.lock
Original file line number Diff line number Diff line change
Expand Up @@ -1419,36 +1419,36 @@
dependencies:
"@types/yargs-parser" "*"

"@vue/[email protected].6":
version "3.0.0-rc.6"
resolved "https://registry.yarnpkg.com/@vue/compiler-core/-/compiler-core-3.0.0-rc.6.tgz#d5bae6ba028068aa54706a5c9c1e8e34a296b4ce"
integrity sha512-ZECV6eMIO+cY1aMQoPMZvkS1Bjv5tfeYrcd/qE4YdsjMUtId6N9EO3xob9FUo4fL4SZt2woHmGkc8x4nKu9+NQ==
"@vue/[email protected].10":
version "3.0.0-rc.10"
resolved "https://registry.yarnpkg.com/@vue/compiler-core/-/compiler-core-3.0.0-rc.10.tgz#a76f713fb0462429ec0ec10a472fff1f539c5772"
integrity sha512-kQzHzRsM0NPAWHeqSTb2J4VsHhjRkGeLTsGzeMnW+sojgTnS3T94KacwvYgVS4qeZAKiDq0bMNZoJWrHVQ3T8g==
dependencies:
"@babel/parser" "^7.10.4"
"@babel/types" "^7.10.4"
"@vue/shared" "3.0.0-rc.6"
"@vue/shared" "3.0.0-rc.10"
estree-walker "^2.0.1"
source-map "^0.6.1"

"@vue/[email protected].6":
version "3.0.0-rc.6"
resolved "https://registry.yarnpkg.com/@vue/compiler-dom/-/compiler-dom-3.0.0-rc.6.tgz#6d7adec707834ab75b2ab89d53f484e74eec7253"
integrity sha512-ZlBvrH5FUPtMLKHib1yR0eLvVbjMarz/fWRD3MtDJiCpH5TTHo5I24HLaMhbjSB0nnwahwAbc/ni2538agmJkg==
"@vue/[email protected].10":
version "3.0.0-rc.10"
resolved "https://registry.yarnpkg.com/@vue/compiler-dom/-/compiler-dom-3.0.0-rc.10.tgz#dd1380d1ee61170de76f9eb91e0d8ac7985f0ae0"
integrity sha512-pqIUf5leZm0P9379utrRSVBMxhV8XaqJTEFFp5etCtbEa/H5ALs29EjFMtMcm9sQaVkZlKLu86mgIacbYB9Q3w==
dependencies:
"@vue/compiler-core" "3.0.0-rc.6"
"@vue/shared" "3.0.0-rc.6"
"@vue/compiler-core" "3.0.0-rc.10"
"@vue/shared" "3.0.0-rc.10"

"@vue/compiler-sfc@^3.0.0-rc.6":
version "3.0.0-rc.6"
resolved "https://registry.yarnpkg.com/@vue/compiler-sfc/-/compiler-sfc-3.0.0-rc.6.tgz#22eccc19936abeb860535b3be1f00869456507b4"
integrity sha512-ebzFDNhnQYsmZFh0t+TF/ro8LinyHebdNQEfCZ2sYLJZC0fn4NyvryxflLXwpFtPMl+5s3dWk37wQMDL8NbYHw==
"@vue/compiler-sfc@^3.0.0-rc.10":
version "3.0.0-rc.10"
resolved "https://registry.yarnpkg.com/@vue/compiler-sfc/-/compiler-sfc-3.0.0-rc.10.tgz#4351ece66cdf4d758877482f69421c43d994dbaf"
integrity sha512-VIJ+VXqeM7WoRNgD9uYSARVb6CYq+JS2NNHfeerfNc7Uk3pjYHRv1MwEicAvN6zWFm5GLC1ZYTVD+WFg3xGAkQ==
dependencies:
"@babel/parser" "^7.10.4"
"@babel/types" "^7.10.4"
"@vue/compiler-core" "3.0.0-rc.6"
"@vue/compiler-dom" "3.0.0-rc.6"
"@vue/compiler-ssr" "3.0.0-rc.6"
"@vue/shared" "3.0.0-rc.6"
"@vue/compiler-core" "3.0.0-rc.10"
"@vue/compiler-dom" "3.0.0-rc.10"
"@vue/compiler-ssr" "3.0.0-rc.10"
"@vue/shared" "3.0.0-rc.10"
consolidate "^0.15.1"
estree-walker "^2.0.1"
hash-sum "^2.0.0"
Expand All @@ -1460,42 +1460,42 @@
postcss-selector-parser "^6.0.2"
source-map "^0.6.1"

"@vue/[email protected].6":
version "3.0.0-rc.6"
resolved "https://registry.yarnpkg.com/@vue/compiler-ssr/-/compiler-ssr-3.0.0-rc.6.tgz#88635676e227cd08a2caa3110a16824727d4baab"
integrity sha512-dowz48cpbsUNyPeabH2WbBbP1R3zE/BZo6l8EEGXfmg8A0Qi3pu+m/9fZB0GJIWLpGaxDe4a7swLflo0bEa2ZA==
"@vue/[email protected].10":
version "3.0.0-rc.10"
resolved "https://registry.yarnpkg.com/@vue/compiler-ssr/-/compiler-ssr-3.0.0-rc.10.tgz#95a5f6b65b19a514c94f056994ec144b3b1b03ae"
integrity sha512-JBPil8sO5j7puB8acX2CQMRXEYB/EP8PoEur7RcF/+aqATI7C4yqWcSLC5TRJpigj6xE6ku6sx8om+j7ZHvgBw==
dependencies:
"@vue/compiler-dom" "3.0.0-rc.6"
"@vue/shared" "3.0.0-rc.6"
"@vue/compiler-dom" "3.0.0-rc.10"
"@vue/shared" "3.0.0-rc.10"

"@vue/[email protected].6":
version "3.0.0-rc.6"
resolved "https://registry.yarnpkg.com/@vue/reactivity/-/reactivity-3.0.0-rc.6.tgz#2bca7dd8b0b4219cce6d6e31fac5f30d78ac4845"
integrity sha512-FBAoswICU75OlmeWPSINvpKZnqpZ7ILBDPWBn816SbCbPj2V3W+aVyswgJXkDWWSw6XBng+WxVwdoNFyR537UQ==
"@vue/[email protected].10":
version "3.0.0-rc.10"
resolved "https://registry.yarnpkg.com/@vue/reactivity/-/reactivity-3.0.0-rc.10.tgz#34d5f51bcc5a7c36e27d7a9c1bd7a3d25ffa7c56"
integrity sha512-mkUZfOJlbqGZx2cARmhCs5r2+xLJPL7VFNagmlA3Fd66ZXBc3ZvTQdYsY4VUbYJFe5ByIzqu9TZiAkzXY+JVaA==
dependencies:
"@vue/shared" "3.0.0-rc.6"
"@vue/shared" "3.0.0-rc.10"

"@vue/[email protected].6":
version "3.0.0-rc.6"
resolved "https://registry.yarnpkg.com/@vue/runtime-core/-/runtime-core-3.0.0-rc.6.tgz#cca883b6cc941db304c84ca79f43458dd8b3a5bc"
integrity sha512-p/nA8Nl4w28uO3s0E5ZnIT9YPx8LOY35YAA0YGSfXAbeq09NQaFRv/LkJSVzNKRFvLiE5brPpQ+gb3YGKdtwjQ==
"@vue/[email protected].10":
version "3.0.0-rc.10"
resolved "https://registry.yarnpkg.com/@vue/runtime-core/-/runtime-core-3.0.0-rc.10.tgz#9055aef5113cbc328aaec29760c2151e0ed3cf40"
integrity sha512-VK/kq4gDDoqZ45CVwdbLLpikXLYLCt6YLhdgXX3fhf20gvPqrbEZv1ZNLruNnhhTpf9cLyU4tZ18DHeaUYPziw==
dependencies:
"@vue/reactivity" "3.0.0-rc.6"
"@vue/shared" "3.0.0-rc.6"
"@vue/reactivity" "3.0.0-rc.10"
"@vue/shared" "3.0.0-rc.10"

"@vue/[email protected].6":
version "3.0.0-rc.6"
resolved "https://registry.yarnpkg.com/@vue/runtime-dom/-/runtime-dom-3.0.0-rc.6.tgz#1dd18f1a92f7e7838641741c5aa1d24ce508c5a3"
integrity sha512-fRiAW3bMe6wTHQU9aK66wSwVnrXoMahsdESdngXiulXEW6swSspsarzFI0RlYyiPaN1OQbr3Dtpxxjzq1HNyZw==
"@vue/[email protected].10":
version "3.0.0-rc.10"
resolved "https://registry.yarnpkg.com/@vue/runtime-dom/-/runtime-dom-3.0.0-rc.10.tgz#50f95cb991483a4262163723320967ad17bb321f"
integrity sha512-bH4GuneHt3FQ+/21jba5orM/CO9N1cnT7J3wtrxopFJ4/4H5cvHXyG6v+ZVTu1d733Ij/6yMRA7xbtfi9a4zJw==
dependencies:
"@vue/runtime-core" "3.0.0-rc.6"
"@vue/shared" "3.0.0-rc.6"
"@vue/runtime-core" "3.0.0-rc.10"
"@vue/shared" "3.0.0-rc.10"
csstype "^2.6.8"

"@vue/[email protected].6":
version "3.0.0-rc.6"
resolved "https://registry.yarnpkg.com/@vue/shared/-/shared-3.0.0-rc.6.tgz#36f70b76df1e58afc1262d44a227276ea1156e59"
integrity sha512-DqsDUKyVQK9fDurH7woj8LGT36BPYXd9FbSkN3i2lsLl4RtA5qFNx8nR5yApLoTOUiOy/XxorD/AC3erEJ8s8g==
"@vue/[email protected].10":
version "3.0.0-rc.10"
resolved "https://registry.yarnpkg.com/@vue/shared/-/shared-3.0.0-rc.10.tgz#e7ab62abcabbfc738545902b96a3aa78f59f3286"
integrity sha512-fI6gVhhgb3cAmEkY4oeVVA2hWZ2xvkgogHdBI5PL7gSvZnOB6XZ2eQGsYjC4W+7BegvEkoMBuZsFXVa4ZQ07XQ==

"@webassemblyjs/[email protected]":
version "1.8.5"
Expand Down Expand Up @@ -8485,14 +8485,14 @@ 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.0.0-rc.6:
version "3.0.0-rc.6"
resolved "https://registry.yarnpkg.com/vue/-/vue-3.0.0-rc.6.tgz#856baa7c5701e9f960b7831f8683232eb6a687d6"
integrity sha512-A6zXzKNFbYfAwCrwzyQIB5sbIcONhVUBCQPrCk3KQrYIx5bVF6yHUK+CaMeXcioHAhuoyMGbS3VuTlblUazTpg==
vue@^3.0.0-rc.10:
version "3.0.0-rc.10"
resolved "https://registry.yarnpkg.com/vue/-/vue-3.0.0-rc.10.tgz#31298a757b4fad6ee8973d0fa27c4fde8574bd01"
integrity sha512-nRsyIQtOWLDMBb5dsPwg/WdIqznCMVWN6O6wJSzhseKC768wHlZKcJ7SPHhWPid9wi3Ykhtl9vtgvxTK/qICkw==
dependencies:
"@vue/compiler-dom" "3.0.0-rc.6"
"@vue/runtime-dom" "3.0.0-rc.6"
"@vue/shared" "3.0.0-rc.6"
"@vue/compiler-dom" "3.0.0-rc.10"
"@vue/runtime-dom" "3.0.0-rc.10"
"@vue/shared" "3.0.0-rc.10"

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

0 comments on commit fb09c8b

Please sign in to comment.