Skip to content

Commit f7571a6

Browse files
committed
refactor: adjust custom elements mode behavior
see vuejs/core#4261
1 parent 6aa00ae commit f7571a6

File tree

2 files changed

+52
-54
lines changed

2 files changed

+52
-54
lines changed

Diff for: README.md

+51-50
Original file line numberDiff line numberDiff line change
@@ -7,26 +7,27 @@
77
## v16 Only Options
88

99
- `refSugar: boolean`: enable experimental ref sugar.
10-
- `customElement: boolean | RegExp`: enable custom elements mode.
10+
11+
- `customElement: boolean | RegExp`: enable custom elements mode. An SFC loaded in custom elements mode inlines its `<style>` tags as strings under the component's `styles` option. When used with `defineCustomElement` from Vue core, the styles will be injected into the custom element's shadow root.
1112
- Default is `/\.ce\.vue$/`
12-
- Setting to `true` will load all `.vue` files as native Custom Elements.
13+
- Setting to `true` will process all `.vue` files in custom element mode.
1314

1415
## What is Vue Loader?
1516

1617
`vue-loader` is a loader for [webpack](https://webpack.js.org/) that allows you to author Vue components in a format called [Single-File Components (SFCs)](./docs/spec.md):
1718

18-
``` vue
19+
```vue
1920
<template>
2021
<div class="example">{{ msg }}</div>
2122
</template>
2223
2324
<script>
2425
export default {
25-
data () {
26+
data() {
2627
return {
27-
msg: 'Hello world!'
28+
msg: 'Hello world!',
2829
}
29-
}
30+
},
3031
}
3132
</script>
3233
@@ -53,72 +54,72 @@ In a nutshell, the combination of webpack and `vue-loader` gives you a modern, f
5354
5455
`vue-loader` is not a simple source transform loader. It handles each language blocks inside an SFC with its own dedicated loader chain (you can think of each block as a "virtual module"), and finally assembles the blocks together into the final module. Here's a brief overview of how the whole thing works:
5556

56-
1. `vue-loader` parses the SFC source code into an *SFC Descriptor* using `@vue/compiler-sfc`. It then generates an import for each language block so the actual returned module code looks like this:
57+
1. `vue-loader` parses the SFC source code into an _SFC Descriptor_ using `@vue/compiler-sfc`. It then generates an import for each language block so the actual returned module code looks like this:
5758

58-
``` js
59-
// code returned from the main loader for 'source.vue'
59+
```js
60+
// code returned from the main loader for 'source.vue'
6061

61-
// import the <template> block
62-
import render from 'source.vue?vue&type=template'
63-
// import the <script> block
64-
import script from 'source.vue?vue&type=script'
65-
export * from 'source.vue?vue&type=script'
66-
// import <style> blocks
67-
import 'source.vue?vue&type=style&index=1'
62+
// import the <template> block
63+
import render from 'source.vue?vue&type=template'
64+
// import the <script> block
65+
import script from 'source.vue?vue&type=script'
66+
export * from 'source.vue?vue&type=script'
67+
// import <style> blocks
68+
import 'source.vue?vue&type=style&index=1'
6869

69-
script.render = render
70-
export default script
71-
```
70+
script.render = render
71+
export default script
72+
```
7273

73-
Notice how the code is importing `source.vue` itself, but with different request queries for each block.
74+
Notice how the code is importing `source.vue` itself, but with different request queries for each block.
7475

7576
2. We want the content in `script` block to be treated like `.js` files (and if it's `<script lang="ts">`, we want to to be treated like `.ts` files). Same for other language blocks. So we want webpack to apply any configured module rules that matches `.js` also to requests that look like `source.vue?vue&type=script`. This is what `VueLoaderPlugin` (`src/plugins.ts`) does: for each module rule in the webpack config, it creates a modified clone that targets corresponding Vue language block requests.
7677

77-
Suppose we have configured `babel-loader` for all `*.js` files. That rule will be cloned and applied to Vue SFC `<script>` blocks as well. Internally to webpack, a request like
78+
Suppose we have configured `babel-loader` for all `*.js` files. That rule will be cloned and applied to Vue SFC `<script>` blocks as well. Internally to webpack, a request like
7879

79-
``` js
80-
import script from 'source.vue?vue&type=script'
81-
```
80+
```js
81+
import script from 'source.vue?vue&type=script'
82+
```
8283

83-
Will expand to:
84+
Will expand to:
8485

85-
``` js
86-
import script from 'babel-loader!vue-loader!source.vue?vue&type=script'
87-
```
86+
```js
87+
import script from 'babel-loader!vue-loader!source.vue?vue&type=script'
88+
```
8889

89-
Notice the `vue-loader` is also matched because `vue-loader` are applied to `.vue` files.
90+
Notice the `vue-loader` is also matched because `vue-loader` are applied to `.vue` files.
9091

91-
Similarly, if you have configured `style-loader` + `css-loader` + `sass-loader` for `*.scss` files:
92+
Similarly, if you have configured `style-loader` + `css-loader` + `sass-loader` for `*.scss` files:
9293

93-
``` html
94-
<style scoped lang="scss">
95-
```
94+
```html
95+
<style scoped lang="scss">
96+
```
9697
97-
Will be returned by `vue-loader` as:
98+
Will be returned by `vue-loader` as:
9899
99-
``` js
100-
import 'source.vue?vue&type=style&index=1&scoped&lang=scss'
101-
```
100+
```js
101+
import 'source.vue?vue&type=style&index=1&scoped&lang=scss'
102+
```
102103
103-
And webpack will expand it to:
104+
And webpack will expand it to:
104105
105-
``` js
106-
import 'style-loader!css-loader!sass-loader!vue-loader!source.vue?vue&type=style&index=1&scoped&lang=scss'
107-
```
106+
```js
107+
import 'style-loader!css-loader!sass-loader!vue-loader!source.vue?vue&type=style&index=1&scoped&lang=scss'
108+
```
108109
109110
3. When processing the expanded requests, the main `vue-loader` will get invoked again. This time though, the loader notices that the request has queries and is targeting a specific block only. So it selects (`src/select.ts`) the inner content of the target block and passes it on to the loaders matched after it.
110111
111112
4. For the `<script>` block, this is pretty much it. For `<template>` and `<style>` blocks though, a few extra tasks need to be performed:
112113
113-
- We need to compile the template using the Vue template compiler;
114-
- We need to post-process the CSS in `<style scoped>` blocks, **after** `css-loader` but **before** `style-loader`.
114+
- We need to compile the template using the Vue template compiler;
115+
- We need to post-process the CSS in `<style scoped>` blocks, **after** `css-loader` but **before** `style-loader`.
115116
116-
Technically, these are additional loaders (`src/templateLoader.ts` and `src/stylePostLoader.ts`) that need to be injected into the expanded loader chain. It would be very complicated if the end users have to configure this themselves, so `VueLoaderPlugin` also injects a global [Pitching Loader](https://webpack.js.org/api/loaders/#pitching-loader) (`src/pitcher.ts`) that intercepts Vue `<template>` and `<style>` requests and injects the necessary loaders. The final requests look like the following:
117+
Technically, these are additional loaders (`src/templateLoader.ts` and `src/stylePostLoader.ts`) that need to be injected into the expanded loader chain. It would be very complicated if the end users have to configure this themselves, so `VueLoaderPlugin` also injects a global [Pitching Loader](https://webpack.js.org/api/loaders/#pitching-loader) (`src/pitcher.ts`) that intercepts Vue `<template>` and `<style>` requests and injects the necessary loaders. The final requests look like the following:
117118
118-
``` js
119-
// <template lang="pug">
120-
import 'vue-loader/template-loader!pug-loader!source.vue?vue&type=template'
119+
```js
120+
// <template lang="pug">
121+
import 'vue-loader/template-loader!pug-loader!source.vue?vue&type=template'
121122
122-
// <style scoped lang="scss">
123-
import 'style-loader!vue-loader/style-post-loader!css-loader!sass-loader!vue-loader!source.vue?vue&type=style&index=1&scoped&lang=scss'
124-
```
123+
// <style scoped lang="scss">
124+
import 'style-loader!vue-loader/style-post-loader!css-loader!sass-loader!vue-loader!source.vue?vue&type=style&index=1&scoped&lang=scss'
125+
```

Diff for: src/index.ts

+1-4
Original file line numberDiff line numberDiff line change
@@ -285,10 +285,7 @@ export default function loader(
285285
}
286286

287287
// finalize
288-
code += asCustomElement
289-
? `\n\nimport { defineCustomElement as __ce } from 'vue';` +
290-
`export default __ce(script)`
291-
: `\n\nexport default script`
288+
code += `\n\nexport default script`
292289
return code
293290
}
294291

0 commit comments

Comments
 (0)