@rsbuild/plugin-vue2 1.0.1-beta.9 → 1.0.2

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
package/LICENSE CHANGED
@@ -1,6 +1,6 @@
1
1
  MIT License
2
2
 
3
- Copyright (c) 2023-present Bytedance, Inc. and its affiliates.
3
+ Copyright (c) 2024 Rspack Contrib
4
4
 
5
5
  Permission is hereby granted, free of charge, to any person obtaining a copy
6
6
  of this software and associated documentation files (the "Software"), to deal
package/README.md CHANGED
@@ -1,19 +1,125 @@
1
- <p align="center">
2
- <a href="https://rsbuild.dev" target="blank"><img src="https://github.com/web-infra-dev/rsbuild/assets/7237365/84abc13e-b620-468f-a90b-dbf28e7e9427" alt="Rsbuild Logo" /></a>
1
+ # @rsbuild/plugin-vue2
2
+
3
+ Provides support for Vue 2 SFC (Single File Components). The plugin internally integrates [vue-loader](https://vue-loader.vuejs.org/) v15.
4
+
5
+ > @rsbuild/plugin-vue2 only supports Vue >= 2.7.0.
6
+
7
+ <p>
8
+ <a href="https://npmjs.com/package/@rsbuild/plugin-vue2">
9
+ <img src="https://img.shields.io/npm/v/@rsbuild/plugin-vue2?style=flat-square&colorA=564341&colorB=EDED91" alt="npm version" />
10
+ </a>
11
+ <img src="https://img.shields.io/badge/License-MIT-blue.svg?style=flat-square&colorA=564341&colorB=EDED91" alt="license" />
3
12
  </p>
4
13
 
5
- # Rsbuild
14
+ ## Usage
15
+
16
+ Install:
17
+
18
+ ```bash
19
+ npm add @rsbuild/plugin-vue2 -D
20
+ ```
21
+
22
+ Add plugin to your `rsbuild.config.ts`:
23
+
24
+ ```ts
25
+ // rsbuild.config.ts
26
+ import { pluginVue2 } from "@rsbuild/plugin-vue2";
27
+
28
+ export default {
29
+ plugins: [pluginVue2()],
30
+ };
31
+ ```
32
+
33
+ After registering the plugin, you can import `*.vue` files in your code.
34
+
35
+ ## Options
36
+
37
+ If you need to customize the compilation behavior of Vue, you can use the following configs.
38
+
39
+ ### vueLoaderOptions
40
+
41
+ Options passed to `vue-loader`, please refer to the [vue-loader documentation](https://vue-loader.vuejs.org/) for detailed usage.
42
+
43
+ - **Type:** `VueLoaderOptions`
44
+ - **Default:**
45
+
46
+ ```js
47
+ const defaultOptions = {
48
+ compilerOptions: {
49
+ whitespace: "condense",
50
+ },
51
+ experimentalInlineMatchResource: true,
52
+ };
53
+ ```
54
+
55
+ - **Example:**
56
+
57
+ ```ts
58
+ pluginVue2({
59
+ vueLoaderOptions: {
60
+ hotReload: false,
61
+ },
62
+ });
63
+ ```
64
+
65
+ > The Vue 2 plugin is using the `vue-loader` v15. Please be aware that there may be configuration differences between v15 and the latest version.
66
+
67
+ ### splitChunks
68
+
69
+ When [chunkSplit.strategy](/config/performance/chunk-split) set to `split-by-experience`, Rsbuild will automatically split `vue` and `router` related packages into separate chunks by default:
70
+
71
+ - `lib-vue.js`: includes vue, vue-loader.
72
+ - `lib-router.js`: includes vue-router.
73
+
74
+ This option is used to control this behavior and determine whether the `vue` and `router` related packages need to be split into separate chunks.
75
+
76
+ - **Type:**
77
+
78
+ ```ts
79
+ type SplitVueChunkOptions = {
80
+ vue?: boolean;
81
+ router?: boolean;
82
+ };
83
+ ```
84
+
85
+ - **Default:**
86
+
87
+ ```ts
88
+ const defaultOptions = {
89
+ vue: true,
90
+ router: true,
91
+ };
92
+ ```
93
+
94
+ - **Example:**
95
+
96
+ ```ts
97
+ pluginVue({
98
+ splitChunks: {
99
+ vue: false,
100
+ router: false,
101
+ },
102
+ });
103
+ ```
104
+
105
+ ## FAQ
6
106
 
7
- The Rspack-based build tool. It's fast, out-of-the-box and extensible.
107
+ ### /deep/ selector causes compilation error
8
108
 
9
- ## Documentation
109
+ `/deep/` is a deprecated usage as of Vue v2.7. Since it is not a valid CSS syntax, CSS compilation tools like Lightning CSS will fail to compile it.
10
110
 
11
- https://rsbuild.dev/
111
+ You can use `:deep()` instead. See [Vue - Deep Selectors](https://vuejs.org/api/sfc-css-features.html#deep-selectors) for more details.
12
112
 
13
- ## Contributing
113
+ ```html
114
+ <style scoped>
115
+ .a :deep(.b) {
116
+ /* ... */
117
+ }
118
+ </style>
119
+ ```
14
120
 
15
- Please read the [Contributing Guide](https://github.com/web-infra-dev/rsbuild/blob/main/CONTRIBUTING.md).
121
+ > You can also refer to [Vue - RFC 0023](https://github.com/vuejs/rfcs/blob/master/active-rfcs/0023-scoped-styles-changes.md) for more details.
16
122
 
17
123
  ## License
18
124
 
19
- Rsbuild is [MIT licensed](https://github.com/web-infra-dev/rsbuild/blob/main/LICENSE).
125
+ [MIT](./LICENSE).
package/dist/index.cjs CHANGED
@@ -1,188 +1,180 @@
1
1
  "use strict";
2
- var __create = Object.create;
3
- var __defProp = Object.defineProperty;
4
- var __getOwnPropDesc = Object.getOwnPropertyDescriptor;
5
- var __getOwnPropNames = Object.getOwnPropertyNames;
6
- var __getProtoOf = Object.getPrototypeOf;
7
- var __hasOwnProp = Object.prototype.hasOwnProperty;
8
- var __defNormalProp = (obj, key, value) => key in obj ? __defProp(obj, key, { enumerable: true, configurable: true, writable: true, value }) : obj[key] = value;
9
- var __export = (target, all) => {
10
- for (var name in all)
11
- __defProp(target, name, { get: all[name], enumerable: true });
12
- };
13
- var __copyProps = (to, from, except, desc) => {
14
- if (from && typeof from === "object" || typeof from === "function") {
15
- for (let key of __getOwnPropNames(from))
16
- if (!__hasOwnProp.call(to, key) && key !== except)
17
- __defProp(to, key, { get: () => from[key], enumerable: !(desc = __getOwnPropDesc(from, key)) || desc.enumerable });
18
- }
19
- return to;
20
- };
21
- var __toESM = (mod, isNodeMode, target) => (target = mod != null ? __create(__getProtoOf(mod)) : {}, __copyProps(
22
- // If the importer is in node compatibility mode or this is not an ESM
23
- // file that has been converted to a CommonJS file using a Babel-
24
- // compatible transform (i.e. "__esModule" has not been set), then set
25
- // "default" to the CommonJS "module.exports" for node compatibility.
26
- isNodeMode || !mod || !mod.__esModule ? __defProp(target, "default", { value: mod, enumerable: true }) : target,
27
- mod
28
- ));
29
- var __toCommonJS = (mod) => __copyProps(__defProp({}, "__esModule", { value: true }), mod);
30
- var __publicField = (obj, key, value) => {
31
- __defNormalProp(obj, typeof key !== "symbol" ? key + "" : key, value);
32
- return value;
33
- };
34
-
35
- // src/index.ts
36
- var src_exports = {};
37
- __export(src_exports, {
38
- PLUGIN_VUE2_NAME: () => PLUGIN_VUE2_NAME,
39
- pluginVue2: () => pluginVue2
2
+ // The require scope
3
+ var __webpack_require__ = {};
4
+ /************************************************************************/ // webpack/runtime/define_property_getters
5
+ (()=>{
6
+ __webpack_require__.d = function(exports1, definition) {
7
+ for(var key in definition)if (__webpack_require__.o(definition, key) && !__webpack_require__.o(exports1, key)) Object.defineProperty(exports1, key, {
8
+ enumerable: true,
9
+ get: definition[key]
10
+ });
11
+ };
12
+ })();
13
+ // webpack/runtime/has_own_property
14
+ (()=>{
15
+ __webpack_require__.o = function(obj, prop) {
16
+ return Object.prototype.hasOwnProperty.call(obj, prop);
17
+ };
18
+ })();
19
+ // webpack/runtime/make_namespace_object
20
+ (()=>{
21
+ // define __esModule on exports
22
+ __webpack_require__.r = function(exports1) {
23
+ if ('undefined' != typeof Symbol && Symbol.toStringTag) Object.defineProperty(exports1, Symbol.toStringTag, {
24
+ value: 'Module'
25
+ });
26
+ Object.defineProperty(exports1, '__esModule', {
27
+ value: true
28
+ });
29
+ };
30
+ })();
31
+ /************************************************************************/ var __webpack_exports__ = {};
32
+ // ESM COMPAT FLAG
33
+ __webpack_require__.r(__webpack_exports__);
34
+ // EXPORTS
35
+ __webpack_require__.d(__webpack_exports__, {
36
+ PLUGIN_VUE2_NAME: ()=>/* binding */ PLUGIN_VUE2_NAME,
37
+ pluginVue2: ()=>/* binding */ pluginVue2
40
38
  });
41
- module.exports = __toCommonJS(src_exports);
42
- var import_vue_loader = require("vue-loader");
43
-
44
- // src/VueLoader15PitchFixPlugin.ts
45
- var VueLoader15PitchFixPlugin = class {
46
- constructor() {
47
- __publicField(this, "name", "VueLoader15PitchFixPlugin");
48
- }
49
- apply(compiler) {
50
- const { NormalModule } = compiler.webpack;
51
- compiler.hooks.compilation.tap(this.name, (compilation) => {
52
- const isExpCssOn = compilation.compiler.options?.experiments?.css;
53
- if (!isExpCssOn)
54
- return;
55
- NormalModule.getCompilationHooks(compilation).loader.tap(
56
- this.name,
57
- (loaderContext) => {
58
- if (
59
- // the related issue only happens for <style>
60
- /[?&]type=style/.test(loaderContext.resourceQuery) && // the fix should be applied before `pitch` phase completed.
61
- // once `pitch` phase completed, vue-loader will remove its pitcher loader.
62
- /[\\/]vue-loader[\\/]lib[\\/]loaders[\\/]pitcher/.test(
63
- loaderContext.loaders?.[0]?.path || ""
64
- )
65
- ) {
66
- const seen = /* @__PURE__ */ new Set();
67
- const loaders = [];
68
- for (const loader of loaderContext.loaders || []) {
69
- const identifier = typeof loader === "string" ? loader : loader.path + loader.query;
70
- if (!seen.has(identifier)) {
71
- seen.add(identifier);
72
- loaders.push(loader);
73
- }
74
- }
75
- loaderContext.loaders = loaders;
76
- }
77
- }
78
- );
39
+ const external_node_module_namespaceObject = require("node:module");
40
+ const external_vue_loader_namespaceObject = require("vue-loader");
41
+ function _define_property(obj, key, value) {
42
+ if (key in obj) Object.defineProperty(obj, key, {
43
+ value: value,
44
+ enumerable: true,
45
+ configurable: true,
46
+ writable: true
79
47
  });
80
- }
81
- };
82
-
83
- // src/splitChunks.ts
84
- var isPlainObject = (obj) => obj !== null && typeof obj === "object" && Object.prototype.toString.call(obj) === "[object Object]";
85
- var applySplitChunksRule = (api, options = {
86
- vue: true,
87
- router: true
88
- }) => {
89
- api.modifyBundlerChain((chain, { environment }) => {
90
- const { config } = environment;
91
- if (config.performance.chunkSplit.strategy !== "split-by-experience") {
92
- return;
93
- }
94
- const currentConfig = chain.optimization.splitChunks.values();
95
- if (!isPlainObject(currentConfig)) {
96
- return;
97
- }
98
- const extraGroups = {};
99
- if (options.router) {
100
- extraGroups.vue = {
101
- name: "lib-vue",
102
- test: /node_modules[\\/](?:vue|vue-loader)[\\/]/,
103
- priority: 0
104
- };
105
- }
106
- if (options.router) {
107
- extraGroups.router = {
108
- name: "lib-router",
109
- test: /node_modules[\\/]vue-router[\\/]/,
110
- priority: 0
111
- };
48
+ else obj[key] = value;
49
+ return obj;
50
+ }
51
+ /**
52
+ * this plugin is a quick fix for issue https://github.com/web-infra-dev/rsbuild/issues/2093
53
+ */ class VueLoader15PitchFixPlugin {
54
+ apply(compiler) {
55
+ const { NormalModule } = compiler.webpack;
56
+ compiler.hooks.compilation.tap(this.name, (compilation)=>{
57
+ var _compilation_compiler_options_experiments, _compilation_compiler_options;
58
+ const isExpCssOn = null === (_compilation_compiler_options = compilation.compiler.options) || void 0 === _compilation_compiler_options ? void 0 : null === (_compilation_compiler_options_experiments = _compilation_compiler_options.experiments) || void 0 === _compilation_compiler_options_experiments ? void 0 : _compilation_compiler_options_experiments.css;
59
+ // the related issue only happens when experiments.css is on
60
+ if (!isExpCssOn) return;
61
+ NormalModule.getCompilationHooks(compilation).loader.tap(this.name, (loaderContext)=>{
62
+ var _loaderContext_loaders_, _loaderContext_loaders;
63
+ if (/[?&]type=style/.test(loaderContext.resourceQuery) && // the fix should be applied before `pitch` phase completed.
64
+ // once `pitch` phase completed, vue-loader will remove its pitcher loader.
65
+ /[\\/]vue-loader[\\/]lib[\\/]loaders[\\/]pitcher/.test((null === (_loaderContext_loaders = loaderContext.loaders) || void 0 === _loaderContext_loaders ? void 0 : null === (_loaderContext_loaders_ = _loaderContext_loaders[0]) || void 0 === _loaderContext_loaders_ ? void 0 : _loaderContext_loaders_.path) || '')) {
66
+ const seen = new Set();
67
+ const loaders = [];
68
+ // deduplicate loaders
69
+ for (const loader of loaderContext.loaders || []){
70
+ const identifier = 'string' == typeof loader ? loader : loader.path + loader.query;
71
+ if (!seen.has(identifier)) {
72
+ seen.add(identifier);
73
+ loaders.push(loader);
74
+ }
75
+ }
76
+ loaderContext.loaders = loaders;
77
+ }
78
+ });
79
+ });
112
80
  }
113
- if (!Object.keys(extraGroups).length) {
114
- return;
81
+ constructor(){
82
+ _define_property(this, "name", 'VueLoader15PitchFixPlugin');
115
83
  }
116
- chain.optimization.splitChunks({
117
- ...currentConfig,
118
- cacheGroups: {
119
- ...currentConfig.cacheGroups,
120
- ...extraGroups
121
- }
84
+ }
85
+ const isPlainObject = (obj)=>null !== obj && 'object' == typeof obj && '[object Object]' === Object.prototype.toString.call(obj);
86
+ const applySplitChunksRule = (api, options = {
87
+ vue: true,
88
+ router: true
89
+ })=>{
90
+ api.modifyBundlerChain((chain, { environment })=>{
91
+ const { config } = environment;
92
+ if ('split-by-experience' !== config.performance.chunkSplit.strategy) return;
93
+ const currentConfig = chain.optimization.splitChunks.values();
94
+ if (!isPlainObject(currentConfig)) return;
95
+ const extraGroups = {};
96
+ if (options.router) extraGroups.vue = {
97
+ name: 'lib-vue',
98
+ test: /node_modules[\\/](?:vue|vue-loader)[\\/]/,
99
+ priority: 0
100
+ };
101
+ if (options.router) extraGroups.router = {
102
+ name: 'lib-router',
103
+ test: /node_modules[\\/]vue-router[\\/]/,
104
+ priority: 0
105
+ };
106
+ if (!Object.keys(extraGroups).length) return;
107
+ chain.optimization.splitChunks({
108
+ ...currentConfig,
109
+ cacheGroups: {
110
+ ...currentConfig.cacheGroups,
111
+ ...extraGroups
112
+ }
113
+ });
122
114
  });
123
- });
124
115
  };
125
-
126
- // src/index.ts
127
- var PLUGIN_VUE2_NAME = "rsbuild:vue2";
116
+ const src_require = (0, external_node_module_namespaceObject.createRequire)(/*#__PURE__*/ function() {
117
+ return 'undefined' == typeof document ? new (module.require('url'.replace('', ''))).URL('file:' + __filename).href : document.currentScript && document.currentScript.src || new URL('main.js', document.baseURI).href;
118
+ }());
119
+ const PLUGIN_VUE2_NAME = 'rsbuild:vue2';
128
120
  function pluginVue2(options = {}) {
129
- return {
130
- name: PLUGIN_VUE2_NAME,
131
- setup(api) {
132
- const VUE_REGEXP = /\.vue$/;
133
- const CSS_MODULES_REGEX = /\.modules?\.\w+$/i;
134
- api.modifyEnvironmentConfig((config) => {
135
- if (config.output.cssModules.auto === true) {
136
- config.output.cssModules.auto = (path, query) => {
137
- if (VUE_REGEXP.test(path)) {
138
- return query.includes("type=style") && query.includes("module=true");
139
- }
140
- return CSS_MODULES_REGEX.test(path);
141
- };
121
+ return {
122
+ name: PLUGIN_VUE2_NAME,
123
+ setup (api) {
124
+ const VUE_REGEXP = /\.vue$/;
125
+ const CSS_MODULES_REGEX = /\.modules?\.\w+$/i;
126
+ api.modifyEnvironmentConfig((config, { mergeEnvironmentConfig })=>{
127
+ // Support `<style module>` in Vue SFC
128
+ if (true === config.output.cssModules.auto) config.output.cssModules.auto = (path, query)=>{
129
+ if (VUE_REGEXP.test(path)) return query.includes('type=style') && query.includes('module=true');
130
+ return CSS_MODULES_REGEX.test(path);
131
+ };
132
+ const extraConfig = {
133
+ source: {
134
+ // should transpile all scripts from Vue SFC
135
+ include: [
136
+ /\.vue/
137
+ ]
138
+ }
139
+ };
140
+ return mergeEnvironmentConfig(config, extraConfig);
141
+ });
142
+ api.modifyBundlerChain((chain, { CHAIN_ID })=>{
143
+ chain.resolve.extensions.add('.vue');
144
+ // https://github.com/web-infra-dev/rsbuild/issues/1132
145
+ if (!chain.resolve.alias.get('vue$')) chain.resolve.alias.set('vue$', 'vue/dist/vue.runtime.esm.js');
146
+ const userLoaderOptions = options.vueLoaderOptions ?? {};
147
+ const compilerOptions = {
148
+ // https://github.com/vuejs/vue-cli/pull/3853
149
+ whitespace: 'condense',
150
+ ...userLoaderOptions.compilerOptions
151
+ };
152
+ const vueLoaderOptions = {
153
+ experimentalInlineMatchResource: true,
154
+ ...userLoaderOptions,
155
+ compilerOptions
156
+ };
157
+ const rule = chain.module.rule(CHAIN_ID.RULE.VUE);
158
+ rule.test(VUE_REGEXP).use(CHAIN_ID.USE.VUE).loader(src_require.resolve('vue-loader')).options(vueLoaderOptions);
159
+ if (chain.module.rules.has(CHAIN_ID.RULE.JS)) applyResolveConfig(rule, chain.module.rule(CHAIN_ID.RULE.JS));
160
+ // Support for lang="postcss" and lang="pcss" in SFC
161
+ chain.module.rule(CHAIN_ID.RULE.CSS).test(/\.(?:css|postcss|pcss)$/);
162
+ chain.plugin(CHAIN_ID.PLUGIN.VUE_LOADER_PLUGIN).use(external_vue_loader_namespaceObject.VueLoaderPlugin);
163
+ // we could remove this once a new vue-loader@15 is released with https://github.com/vuejs/vue-loader/pull/2071 shipped
164
+ chain.plugin('vue-loader-15-pitch-fix').use(VueLoader15PitchFixPlugin);
165
+ });
166
+ applySplitChunksRule(api, options.splitChunks);
142
167
  }
143
- return config;
144
- });
145
- api.modifyBundlerChain((chain, { CHAIN_ID }) => {
146
- chain.resolve.extensions.add(".vue");
147
- if (!chain.resolve.alias.get("vue$")) {
148
- chain.resolve.alias.set("vue$", "vue/dist/vue.runtime.esm.js");
149
- }
150
- const userLoaderOptions = options.vueLoaderOptions ?? {};
151
- const compilerOptions = {
152
- // https://github.com/vuejs/vue-cli/pull/3853
153
- whitespace: "condense",
154
- ...userLoaderOptions.compilerOptions
155
- };
156
- const vueLoaderOptions = {
157
- experimentalInlineMatchResource: true,
158
- ...userLoaderOptions,
159
- compilerOptions
160
- };
161
- const rule = chain.module.rule(CHAIN_ID.RULE.VUE);
162
- rule.test(VUE_REGEXP).use(CHAIN_ID.USE.VUE).loader(require.resolve("vue-loader")).options(vueLoaderOptions);
163
- if (chain.module.rules.has(CHAIN_ID.RULE.JS)) {
164
- applyResolveConfig(rule, chain.module.rule(CHAIN_ID.RULE.JS));
165
- }
166
- chain.module.rule(CHAIN_ID.RULE.CSS).test(/\.(?:css|postcss|pcss)$/);
167
- chain.plugin(CHAIN_ID.PLUGIN.VUE_LOADER_PLUGIN).use(import_vue_loader.VueLoaderPlugin);
168
- chain.plugin("vue-loader-15-pitch-fix").use(VueLoader15PitchFixPlugin);
169
- });
170
- applySplitChunksRule(api, options.splitChunks);
171
- }
172
- };
168
+ };
173
169
  }
174
170
  function applyResolveConfig(vueRule, jsRule) {
175
- const fullySpecified = jsRule.resolve.get("fullySpecified");
176
- const aliases = jsRule.resolve.alias.entries();
177
- if (aliases) {
178
- vueRule.resolve.alias.merge(aliases);
179
- }
180
- if (fullySpecified !== void 0) {
181
- vueRule.resolve.fullySpecified(fullySpecified);
182
- }
171
+ const fullySpecified = jsRule.resolve.get('fullySpecified');
172
+ const aliases = jsRule.resolve.alias.entries();
173
+ if (aliases) vueRule.resolve.alias.merge(aliases);
174
+ if (void 0 !== fullySpecified) vueRule.resolve.fullySpecified(fullySpecified);
183
175
  }
184
- // Annotate the CommonJS export names for ESM import in node:
185
- 0 && (module.exports = {
186
- PLUGIN_VUE2_NAME,
187
- pluginVue2
176
+ var __webpack_export_target__ = exports;
177
+ for(var i in __webpack_exports__)__webpack_export_target__[i] = __webpack_exports__[i];
178
+ if (__webpack_exports__.__esModule) Object.defineProperty(__webpack_export_target__, '__esModule', {
179
+ value: true
188
180
  });
package/dist/index.js CHANGED
@@ -1,168 +1,136 @@
1
- import { createRequire } from 'module';
2
- var require = createRequire(import.meta['url']);
3
-
4
- var __defProp = Object.defineProperty;
5
- var __defNormalProp = (obj, key, value) => key in obj ? __defProp(obj, key, { enumerable: true, configurable: true, writable: true, value }) : obj[key] = value;
6
- var __require = /* @__PURE__ */ ((x) => typeof require !== "undefined" ? require : typeof Proxy !== "undefined" ? new Proxy(x, {
7
- get: (a, b) => (typeof require !== "undefined" ? require : a)[b]
8
- }) : x)(function(x) {
9
- if (typeof require !== "undefined")
10
- return require.apply(this, arguments);
11
- throw Error('Dynamic require of "' + x + '" is not supported');
12
- });
13
- var __publicField = (obj, key, value) => {
14
- __defNormalProp(obj, typeof key !== "symbol" ? key + "" : key, value);
15
- return value;
16
- };
17
-
18
- // ../../node_modules/.pnpm/@modern-js+module-tools@2.56.2_typescript@5.5.2/node_modules/@modern-js/module-tools/shims/esm.js
19
- import { fileURLToPath } from "url";
20
- import path from "path";
21
-
22
- // src/index.ts
23
- import { VueLoaderPlugin } from "vue-loader";
24
-
25
- // src/VueLoader15PitchFixPlugin.ts
26
- var VueLoader15PitchFixPlugin = class {
27
- constructor() {
28
- __publicField(this, "name", "VueLoader15PitchFixPlugin");
29
- }
30
- apply(compiler) {
31
- const { NormalModule } = compiler.webpack;
32
- compiler.hooks.compilation.tap(this.name, (compilation) => {
33
- const isExpCssOn = compilation.compiler.options?.experiments?.css;
34
- if (!isExpCssOn)
35
- return;
36
- NormalModule.getCompilationHooks(compilation).loader.tap(
37
- this.name,
38
- (loaderContext) => {
39
- if (
40
- // the related issue only happens for <style>
41
- /[?&]type=style/.test(loaderContext.resourceQuery) && // the fix should be applied before `pitch` phase completed.
42
- // once `pitch` phase completed, vue-loader will remove its pitcher loader.
43
- /[\\/]vue-loader[\\/]lib[\\/]loaders[\\/]pitcher/.test(
44
- loaderContext.loaders?.[0]?.path || ""
45
- )
46
- ) {
47
- const seen = /* @__PURE__ */ new Set();
48
- const loaders = [];
49
- for (const loader of loaderContext.loaders || []) {
50
- const identifier = typeof loader === "string" ? loader : loader.path + loader.query;
51
- if (!seen.has(identifier)) {
52
- seen.add(identifier);
53
- loaders.push(loader);
54
- }
55
- }
56
- loaderContext.loaders = loaders;
57
- }
58
- }
59
- );
1
+ import * as __WEBPACK_EXTERNAL_MODULE_node_module__ from "node:module";
2
+ import * as __WEBPACK_EXTERNAL_MODULE_vue_loader__ from "vue-loader";
3
+ function _define_property(obj, key, value) {
4
+ if (key in obj) Object.defineProperty(obj, key, {
5
+ value: value,
6
+ enumerable: true,
7
+ configurable: true,
8
+ writable: true
60
9
  });
61
- }
62
- };
63
-
64
- // src/splitChunks.ts
65
- var isPlainObject = (obj) => obj !== null && typeof obj === "object" && Object.prototype.toString.call(obj) === "[object Object]";
66
- var applySplitChunksRule = (api, options = {
67
- vue: true,
68
- router: true
69
- }) => {
70
- api.modifyBundlerChain((chain, { environment }) => {
71
- const { config } = environment;
72
- if (config.performance.chunkSplit.strategy !== "split-by-experience") {
73
- return;
74
- }
75
- const currentConfig = chain.optimization.splitChunks.values();
76
- if (!isPlainObject(currentConfig)) {
77
- return;
78
- }
79
- const extraGroups = {};
80
- if (options.router) {
81
- extraGroups.vue = {
82
- name: "lib-vue",
83
- test: /node_modules[\\/](?:vue|vue-loader)[\\/]/,
84
- priority: 0
85
- };
86
- }
87
- if (options.router) {
88
- extraGroups.router = {
89
- name: "lib-router",
90
- test: /node_modules[\\/]vue-router[\\/]/,
91
- priority: 0
92
- };
10
+ else obj[key] = value;
11
+ return obj;
12
+ }
13
+ /**
14
+ * this plugin is a quick fix for issue https://github.com/web-infra-dev/rsbuild/issues/2093
15
+ */ class VueLoader15PitchFixPlugin {
16
+ apply(compiler) {
17
+ const { NormalModule } = compiler.webpack;
18
+ compiler.hooks.compilation.tap(this.name, (compilation)=>{
19
+ var _compilation_compiler_options_experiments, _compilation_compiler_options;
20
+ const isExpCssOn = null === (_compilation_compiler_options = compilation.compiler.options) || void 0 === _compilation_compiler_options ? void 0 : null === (_compilation_compiler_options_experiments = _compilation_compiler_options.experiments) || void 0 === _compilation_compiler_options_experiments ? void 0 : _compilation_compiler_options_experiments.css;
21
+ // the related issue only happens when experiments.css is on
22
+ if (!isExpCssOn) return;
23
+ NormalModule.getCompilationHooks(compilation).loader.tap(this.name, (loaderContext)=>{
24
+ var _loaderContext_loaders_, _loaderContext_loaders;
25
+ if (/[?&]type=style/.test(loaderContext.resourceQuery) && // the fix should be applied before `pitch` phase completed.
26
+ // once `pitch` phase completed, vue-loader will remove its pitcher loader.
27
+ /[\\/]vue-loader[\\/]lib[\\/]loaders[\\/]pitcher/.test((null === (_loaderContext_loaders = loaderContext.loaders) || void 0 === _loaderContext_loaders ? void 0 : null === (_loaderContext_loaders_ = _loaderContext_loaders[0]) || void 0 === _loaderContext_loaders_ ? void 0 : _loaderContext_loaders_.path) || '')) {
28
+ const seen = new Set();
29
+ const loaders = [];
30
+ // deduplicate loaders
31
+ for (const loader of loaderContext.loaders || []){
32
+ const identifier = 'string' == typeof loader ? loader : loader.path + loader.query;
33
+ if (!seen.has(identifier)) {
34
+ seen.add(identifier);
35
+ loaders.push(loader);
36
+ }
37
+ }
38
+ loaderContext.loaders = loaders;
39
+ }
40
+ });
41
+ });
93
42
  }
94
- if (!Object.keys(extraGroups).length) {
95
- return;
43
+ constructor(){
44
+ _define_property(this, "name", 'VueLoader15PitchFixPlugin');
96
45
  }
97
- chain.optimization.splitChunks({
98
- ...currentConfig,
99
- cacheGroups: {
100
- ...currentConfig.cacheGroups,
101
- ...extraGroups
102
- }
46
+ }
47
+ const isPlainObject = (obj)=>null !== obj && 'object' == typeof obj && '[object Object]' === Object.prototype.toString.call(obj);
48
+ const applySplitChunksRule = (api, options = {
49
+ vue: true,
50
+ router: true
51
+ })=>{
52
+ api.modifyBundlerChain((chain, { environment })=>{
53
+ const { config } = environment;
54
+ if ('split-by-experience' !== config.performance.chunkSplit.strategy) return;
55
+ const currentConfig = chain.optimization.splitChunks.values();
56
+ if (!isPlainObject(currentConfig)) return;
57
+ const extraGroups = {};
58
+ if (options.router) extraGroups.vue = {
59
+ name: 'lib-vue',
60
+ test: /node_modules[\\/](?:vue|vue-loader)[\\/]/,
61
+ priority: 0
62
+ };
63
+ if (options.router) extraGroups.router = {
64
+ name: 'lib-router',
65
+ test: /node_modules[\\/]vue-router[\\/]/,
66
+ priority: 0
67
+ };
68
+ if (!Object.keys(extraGroups).length) return;
69
+ chain.optimization.splitChunks({
70
+ ...currentConfig,
71
+ cacheGroups: {
72
+ ...currentConfig.cacheGroups,
73
+ ...extraGroups
74
+ }
75
+ });
103
76
  });
104
- });
105
77
  };
106
-
107
- // src/index.ts
108
- var PLUGIN_VUE2_NAME = "rsbuild:vue2";
78
+ const src_require = (0, __WEBPACK_EXTERNAL_MODULE_node_module__.createRequire)(import.meta.url);
79
+ const PLUGIN_VUE2_NAME = 'rsbuild:vue2';
109
80
  function pluginVue2(options = {}) {
110
- return {
111
- name: PLUGIN_VUE2_NAME,
112
- setup(api) {
113
- const VUE_REGEXP = /\.vue$/;
114
- const CSS_MODULES_REGEX = /\.modules?\.\w+$/i;
115
- api.modifyEnvironmentConfig((config) => {
116
- if (config.output.cssModules.auto === true) {
117
- config.output.cssModules.auto = (path2, query) => {
118
- if (VUE_REGEXP.test(path2)) {
119
- return query.includes("type=style") && query.includes("module=true");
120
- }
121
- return CSS_MODULES_REGEX.test(path2);
122
- };
81
+ return {
82
+ name: PLUGIN_VUE2_NAME,
83
+ setup (api) {
84
+ const VUE_REGEXP = /\.vue$/;
85
+ const CSS_MODULES_REGEX = /\.modules?\.\w+$/i;
86
+ api.modifyEnvironmentConfig((config, { mergeEnvironmentConfig })=>{
87
+ // Support `<style module>` in Vue SFC
88
+ if (true === config.output.cssModules.auto) config.output.cssModules.auto = (path, query)=>{
89
+ if (VUE_REGEXP.test(path)) return query.includes('type=style') && query.includes('module=true');
90
+ return CSS_MODULES_REGEX.test(path);
91
+ };
92
+ const extraConfig = {
93
+ source: {
94
+ // should transpile all scripts from Vue SFC
95
+ include: [
96
+ /\.vue/
97
+ ]
98
+ }
99
+ };
100
+ return mergeEnvironmentConfig(config, extraConfig);
101
+ });
102
+ api.modifyBundlerChain((chain, { CHAIN_ID })=>{
103
+ chain.resolve.extensions.add('.vue');
104
+ // https://github.com/web-infra-dev/rsbuild/issues/1132
105
+ if (!chain.resolve.alias.get('vue$')) chain.resolve.alias.set('vue$', 'vue/dist/vue.runtime.esm.js');
106
+ const userLoaderOptions = options.vueLoaderOptions ?? {};
107
+ const compilerOptions = {
108
+ // https://github.com/vuejs/vue-cli/pull/3853
109
+ whitespace: 'condense',
110
+ ...userLoaderOptions.compilerOptions
111
+ };
112
+ const vueLoaderOptions = {
113
+ experimentalInlineMatchResource: true,
114
+ ...userLoaderOptions,
115
+ compilerOptions
116
+ };
117
+ const rule = chain.module.rule(CHAIN_ID.RULE.VUE);
118
+ rule.test(VUE_REGEXP).use(CHAIN_ID.USE.VUE).loader(src_require.resolve('vue-loader')).options(vueLoaderOptions);
119
+ if (chain.module.rules.has(CHAIN_ID.RULE.JS)) applyResolveConfig(rule, chain.module.rule(CHAIN_ID.RULE.JS));
120
+ // Support for lang="postcss" and lang="pcss" in SFC
121
+ chain.module.rule(CHAIN_ID.RULE.CSS).test(/\.(?:css|postcss|pcss)$/);
122
+ chain.plugin(CHAIN_ID.PLUGIN.VUE_LOADER_PLUGIN).use(__WEBPACK_EXTERNAL_MODULE_vue_loader__.VueLoaderPlugin);
123
+ // we could remove this once a new vue-loader@15 is released with https://github.com/vuejs/vue-loader/pull/2071 shipped
124
+ chain.plugin('vue-loader-15-pitch-fix').use(VueLoader15PitchFixPlugin);
125
+ });
126
+ applySplitChunksRule(api, options.splitChunks);
123
127
  }
124
- return config;
125
- });
126
- api.modifyBundlerChain((chain, { CHAIN_ID }) => {
127
- chain.resolve.extensions.add(".vue");
128
- if (!chain.resolve.alias.get("vue$")) {
129
- chain.resolve.alias.set("vue$", "vue/dist/vue.runtime.esm.js");
130
- }
131
- const userLoaderOptions = options.vueLoaderOptions ?? {};
132
- const compilerOptions = {
133
- // https://github.com/vuejs/vue-cli/pull/3853
134
- whitespace: "condense",
135
- ...userLoaderOptions.compilerOptions
136
- };
137
- const vueLoaderOptions = {
138
- experimentalInlineMatchResource: true,
139
- ...userLoaderOptions,
140
- compilerOptions
141
- };
142
- const rule = chain.module.rule(CHAIN_ID.RULE.VUE);
143
- rule.test(VUE_REGEXP).use(CHAIN_ID.USE.VUE).loader(__require.resolve("vue-loader")).options(vueLoaderOptions);
144
- if (chain.module.rules.has(CHAIN_ID.RULE.JS)) {
145
- applyResolveConfig(rule, chain.module.rule(CHAIN_ID.RULE.JS));
146
- }
147
- chain.module.rule(CHAIN_ID.RULE.CSS).test(/\.(?:css|postcss|pcss)$/);
148
- chain.plugin(CHAIN_ID.PLUGIN.VUE_LOADER_PLUGIN).use(VueLoaderPlugin);
149
- chain.plugin("vue-loader-15-pitch-fix").use(VueLoader15PitchFixPlugin);
150
- });
151
- applySplitChunksRule(api, options.splitChunks);
152
- }
153
- };
128
+ };
154
129
  }
155
130
  function applyResolveConfig(vueRule, jsRule) {
156
- const fullySpecified = jsRule.resolve.get("fullySpecified");
157
- const aliases = jsRule.resolve.alias.entries();
158
- if (aliases) {
159
- vueRule.resolve.alias.merge(aliases);
160
- }
161
- if (fullySpecified !== void 0) {
162
- vueRule.resolve.fullySpecified(fullySpecified);
163
- }
131
+ const fullySpecified = jsRule.resolve.get('fullySpecified');
132
+ const aliases = jsRule.resolve.alias.entries();
133
+ if (aliases) vueRule.resolve.alias.merge(aliases);
134
+ if (void 0 !== fullySpecified) vueRule.resolve.fullySpecified(fullySpecified);
164
135
  }
165
- export {
166
- PLUGIN_VUE2_NAME,
167
- pluginVue2
168
- };
136
+ export { PLUGIN_VUE2_NAME, pluginVue2 };
@@ -1,3 +1,3 @@
1
1
  import type { RsbuildPluginAPI } from '@rsbuild/core';
2
- import type { SplitVueChunkOptions } from '.';
2
+ import type { SplitVueChunkOptions } from './index.js';
3
3
  export declare const applySplitChunksRule: (api: RsbuildPluginAPI, options?: SplitVueChunkOptions) => void;
package/package.json CHANGED
@@ -1,48 +1,69 @@
1
1
  {
2
2
  "name": "@rsbuild/plugin-vue2",
3
- "version": "1.0.1-beta.9",
4
- "description": "Vue 2 plugin of Rsbuild",
5
- "homepage": "https://rsbuild.dev",
6
- "repository": {
7
- "type": "git",
8
- "url": "https://github.com/web-infra-dev/rsbuild",
9
- "directory": "packages/plugin-vue2"
10
- },
3
+ "version": "1.0.2",
4
+ "repository": "https://github.com/rspack-contrib/rsbuild-plugin-vue2",
11
5
  "license": "MIT",
12
6
  "type": "module",
13
7
  "exports": {
14
8
  ".": {
15
- "types": "./dist-types/index.d.ts",
9
+ "types": "./dist/index.d.ts",
16
10
  "import": "./dist/index.js",
17
11
  "require": "./dist/index.cjs"
18
12
  }
19
13
  },
20
- "main": "./dist/index.cjs",
21
- "types": "./dist-types/index.d.ts",
14
+ "main": "./dist/index.js",
15
+ "module": "./dist/index.mjs",
16
+ "types": "./dist/index.d.ts",
22
17
  "files": [
23
- "dist",
24
- "dist-types"
18
+ "dist"
25
19
  ],
20
+ "scripts": {
21
+ "build": "rslib build",
22
+ "dev": "rslib build --watch",
23
+ "lint": "biome check .",
24
+ "lint:write": "biome check . --write",
25
+ "prepare": "simple-git-hooks && npm run build",
26
+ "test": "playwright test",
27
+ "bump": "npx bumpp"
28
+ },
29
+ "simple-git-hooks": {
30
+ "pre-commit": "npx nano-staged"
31
+ },
32
+ "nano-staged": {
33
+ "*.{js,jsx,ts,tsx,mjs,cjs}": [
34
+ "biome check --write --no-errors-on-unmatched"
35
+ ]
36
+ },
26
37
  "dependencies": {
27
38
  "vue-loader": "^15.11.1",
28
- "webpack": "^5.93.0"
39
+ "webpack": "^5.96.1"
29
40
  },
30
41
  "devDependencies": {
31
- "typescript": "^5.5.2",
32
- "webpack": "^5.93.0",
33
- "@rsbuild/core": "1.0.1-beta.9",
34
- "@scripts/test-helper": "1.0.1-beta.9"
42
+ "@biomejs/biome": "^1.9.4",
43
+ "@playwright/test": "^1.48.2",
44
+ "@rsbuild/core": "^1.1.0",
45
+ "@rsbuild/plugin-less": "1.1.0",
46
+ "@rslib/core": "^0.0.18",
47
+ "@types/node": "^20.17.6",
48
+ "nano-staged": "^0.8.0",
49
+ "playwright": "^1.48.2",
50
+ "simple-git-hooks": "^2.11.1",
51
+ "tsup": "^8.3.5",
52
+ "typescript": "^5.6.3",
53
+ "vue": "^2.7.16"
35
54
  },
36
55
  "peerDependencies": {
37
- "@rsbuild/core": "^1.0.1-beta.9"
56
+ "@rsbuild/core": "1.x"
38
57
  },
58
+ "peerDependenciesMeta": {
59
+ "@rsbuild/core": {
60
+ "optional": true
61
+ }
62
+ },
63
+ "packageManager": "pnpm@9.12.3",
39
64
  "publishConfig": {
40
65
  "access": "public",
41
- "provenance": true,
42
- "registry": "https://registry.npmjs.org/"
43
- },
44
- "scripts": {
45
- "build": "modern build",
46
- "dev": "modern build --watch"
66
+ "registry": "https://registry.npmjs.org/",
67
+ "provenance": true
47
68
  }
48
- }
69
+ }
@@ -1 +0,0 @@
1
- {"//":"This file is for making TypeScript work with moduleResolution node16+.","version":"1.0.0"}
File without changes