From b4a4a393ccfa61e998fbd0ee6df93a886cf61a52 Mon Sep 17 00:00:00 2001 From: Evan You Date: Wed, 26 Apr 2023 10:49:54 +0800 Subject: [PATCH 01/40] chore: changelog --- CHANGELOG.md | 23 +++++++++++++++++++++++ 1 file changed, 23 insertions(+) diff --git a/CHANGELOG.md b/CHANGELOG.md index f00faee9f..ff0cbe416 100644 --- a/CHANGELOG.md +++ b/CHANGELOG.md @@ -1,3 +1,26 @@ +# [17.1.0](https://github.com/vuejs/vue-loader/compare/v17.1.0-beta.0...v17.1.0) (2023-04-26) + + +### Bug Fixes + +* do not throw when `Rule.layer` ([#2000](https://github.com/vuejs/vue-loader/issues/2000)) ([ef589df](https://github.com/vuejs/vue-loader/commit/ef589df2956506a5a7bbc050c476501d32dd8469)) + + + +# [17.1.0-beta.0](https://github.com/vuejs/vue-loader/compare/v17.0.1...v17.1.0-beta.0) (2023-04-19) + + +### Bug Fixes + +* reference project compiler, fixes [#2031](https://github.com/vuejs/vue-loader/issues/2031) ([#2038](https://github.com/vuejs/vue-loader/issues/2038)) ([cc6fa9e](https://github.com/vuejs/vue-loader/commit/cc6fa9ebf85972a08fc8bbc359b0093b15790745)) + + +### Features + +* support 3.3 imported types hmr ([bbd98fc](https://github.com/vuejs/vue-loader/commit/bbd98fc8bdc17fcbffb456a5ffe772bc184f22e4)) + + + # [17.1.0-beta.0](https://github.com/vuejs/vue-loader/compare/v17.0.1...v17.1.0-beta.0) (2023-04-19) From 9fb570c4637ed758e57041e4734a8ceefd71a3c9 Mon Sep 17 00:00:00 2001 From: Evan You Date: Thu, 11 May 2023 11:25:25 +0100 Subject: [PATCH 02/40] chore: bump vue --- package.json | 2 +- yarn.lock | 138 +++++++++++++++++++++++++-------------------------- 2 files changed, 70 insertions(+), 70 deletions(-) diff --git a/package.json b/package.json index fa13136b7..076de066e 100644 --- a/package.json +++ b/package.json @@ -88,7 +88,7 @@ "ts-loader-v9": "npm:ts-loader@^9.2.4", "typescript": "^4.4.3", "url-loader": "^4.1.0", - "vue": "^3.3.0-alpha.12", + "vue": "^3.3.0", "vue-i18n": "^9.1.7", "webpack": "^5.79.0", "webpack-cli": "^3.3.12", diff --git a/yarn.lock b/yarn.lock index 34c979246..dbf3ba5ac 100644 --- a/yarn.lock +++ b/yarn.lock @@ -1502,100 +1502,100 @@ dependencies: "@types/yargs-parser" "*" -"@vue/compiler-core@3.3.0-alpha.12": - version "3.3.0-alpha.12" - resolved "https://registry.yarnpkg.com/@vue/compiler-core/-/compiler-core-3.3.0-alpha.12.tgz#baa00b99ab54c0bcf9d0b06b3efbce39434f6016" - integrity sha512-jAcjlvNR5e+rZ8nzJ8S3t6vpINctQhnLEjqeubvPRPgIRxnzAl6NzWgOCfqz81WO8tRoyYXyN5YF5lEyj+Ku2Q== +"@vue/compiler-core@3.3.1": + version "3.3.1" + resolved "https://registry.yarnpkg.com/@vue/compiler-core/-/compiler-core-3.3.1.tgz#4e60a13a4dc65dd1f70e19d30f3746d4f9367af2" + integrity sha512-5le1qYSBgLWg2jdLrbydlhnPJkkzMw46UrRUvTnOKlfg6pThtm9ohhqBhNPHbr0RcM1MCbK5WZe/3Ghz0SZjpQ== dependencies: "@babel/parser" "^7.21.3" - "@vue/shared" "3.3.0-alpha.12" + "@vue/shared" "3.3.1" estree-walker "^2.0.2" source-map-js "^1.0.2" -"@vue/compiler-dom@3.3.0-alpha.12": - version "3.3.0-alpha.12" - resolved "https://registry.yarnpkg.com/@vue/compiler-dom/-/compiler-dom-3.3.0-alpha.12.tgz#aa4c7ac31b17f7b2b7d6873c1e047433bf6546f6" - integrity sha512-jti83D32xoyAIkvPwf3V1c/r4K498OZpJxEJCUYizsr9WAN1vI1Mm85JKTFF/phH7CDu7wqxALx/uti6SsnEtA== +"@vue/compiler-dom@3.3.1": + version "3.3.1" + resolved "https://registry.yarnpkg.com/@vue/compiler-dom/-/compiler-dom-3.3.1.tgz#2d94431071377ace74c770aafb6ab2d62205b336" + integrity sha512-VmgIsoLivCft3+oNc5KM7b9wd0nZxP/g2qilMwi1hJyGA624KWnNKHn4hzBQs4FpzydUVpNy+TWVT8KiRCh3MQ== dependencies: - "@vue/compiler-core" "3.3.0-alpha.12" - "@vue/shared" "3.3.0-alpha.12" + "@vue/compiler-core" "3.3.1" + "@vue/shared" "3.3.1" -"@vue/compiler-sfc@3.3.0-alpha.12": - version "3.3.0-alpha.12" - resolved "https://registry.yarnpkg.com/@vue/compiler-sfc/-/compiler-sfc-3.3.0-alpha.12.tgz#c2bb246c47e76e0c94b75baf73ca9be347d5035c" - integrity sha512-JevlKXtRuvwl5iTgCyCxOVD9Bge9Ck4pnOY03V1Vikx+Smtf/QIqJI/XMK2aFxgoPXUBj3/ueqy9kz6yW2CgNQ== +"@vue/compiler-sfc@3.3.1": + version "3.3.1" + resolved "https://registry.yarnpkg.com/@vue/compiler-sfc/-/compiler-sfc-3.3.1.tgz#16a614fe9c85f35ca0e4333793441edb126323fc" + integrity sha512-G+FPwBbXSLaA4+Ry5/bdD9Oda+sRslQcE9o6JSZaougRiT4OjVL0vtkbQHPrGRTULZV28OcrAjRfSZOSB0OTXQ== dependencies: "@babel/parser" "^7.20.15" - "@vue/compiler-core" "3.3.0-alpha.12" - "@vue/compiler-dom" "3.3.0-alpha.12" - "@vue/compiler-ssr" "3.3.0-alpha.12" - "@vue/reactivity-transform" "3.3.0-alpha.12" - "@vue/shared" "3.3.0-alpha.12" + "@vue/compiler-core" "3.3.1" + "@vue/compiler-dom" "3.3.1" + "@vue/compiler-ssr" "3.3.1" + "@vue/reactivity-transform" "3.3.1" + "@vue/shared" "3.3.1" estree-walker "^2.0.2" magic-string "^0.30.0" postcss "^8.1.10" source-map-js "^1.0.2" -"@vue/compiler-ssr@3.3.0-alpha.12": - version "3.3.0-alpha.12" - resolved "https://registry.yarnpkg.com/@vue/compiler-ssr/-/compiler-ssr-3.3.0-alpha.12.tgz#4dc3ef9c21708576cd473f7170f74ccc0a915263" - integrity sha512-PlitVo8v+rzQ9SxTqY+88N0kOEWbgsRj5oGrgxcACEJxt5oLvKm6eIJuFtwm4im/QtUk3SqMLTKRqTZ+CVywbg== +"@vue/compiler-ssr@3.3.1": + version "3.3.1" + resolved "https://registry.yarnpkg.com/@vue/compiler-ssr/-/compiler-ssr-3.3.1.tgz#4572a5ff79fefd1ba68cb57f024763f5d004f7b3" + integrity sha512-QOQWGNCWuSeyKx4KvWSJlnIMGg+/2oCHgkFUYo7aJ+9Uaaz45yRgKQ+FNigy50NYBQIhpXn2e4OSR8GXh4knrQ== dependencies: - "@vue/compiler-dom" "3.3.0-alpha.12" - "@vue/shared" "3.3.0-alpha.12" + "@vue/compiler-dom" "3.3.1" + "@vue/shared" "3.3.1" "@vue/devtools-api@^6.0.0-beta.7": version "6.0.0-beta.17" resolved "https://registry.yarnpkg.com/@vue/devtools-api/-/devtools-api-6.0.0-beta.17.tgz#d4b9eb02c670d39a4532f4bb3c8517abce3fcb82" integrity sha512-hwGY4Xxc2nl34OyNH7l2VO8/ja3R78B8bcbaBQnZljSju5Z0Bm9HTt+/fQao+TUrs3gfNrrQrY3euWqiaG8chw== -"@vue/reactivity-transform@3.3.0-alpha.12": - version "3.3.0-alpha.12" - resolved "https://registry.yarnpkg.com/@vue/reactivity-transform/-/reactivity-transform-3.3.0-alpha.12.tgz#3c05edcf7c12a37201bf7c0bae5ba2a0a69b372c" - integrity sha512-t+vK8WOK8NXLpl6YBOpGh3sTx54j6G2NQsWjFFEv4BEMYtrPYTZswFRfT6eth8eY4X5jI5np/vHGUMCaUnf3BA== +"@vue/reactivity-transform@3.3.1": + version "3.3.1" + resolved "https://registry.yarnpkg.com/@vue/reactivity-transform/-/reactivity-transform-3.3.1.tgz#35000e3bd4d481b228e5f0b97eb652ec9e6894dc" + integrity sha512-MkOrJauAGH4MNdxGW/PmrDegMyOGX0wGIdKUZJRBXOTpotDONg7/TPJe2QeGeBCow/5v9iOqZOWCfvmOWIaDMg== dependencies: "@babel/parser" "^7.20.15" - "@vue/compiler-core" "3.3.0-alpha.12" - "@vue/shared" "3.3.0-alpha.12" + "@vue/compiler-core" "3.3.1" + "@vue/shared" "3.3.1" estree-walker "^2.0.2" magic-string "^0.30.0" -"@vue/reactivity@3.3.0-alpha.12": - version "3.3.0-alpha.12" - resolved "https://registry.yarnpkg.com/@vue/reactivity/-/reactivity-3.3.0-alpha.12.tgz#d074c5b30bf8dba406042e28f2682ff08b67b3fc" - integrity sha512-/MpZzF0A/ocPocOFPE5Rs80mSUFRdj8xUZdmKcgq+HABmDs+XCW50lSgBxejLVYmm7S09lnVfs/Mvp/jzV9Oiw== +"@vue/reactivity@3.3.1": + version "3.3.1" + resolved "https://registry.yarnpkg.com/@vue/reactivity/-/reactivity-3.3.1.tgz#b134186493113f9f8c3fb6d65a047e19825a46e1" + integrity sha512-zCfmazOtyUdC1NS/EPiSYJ4RqojqmTAviJyBbyVvY8zAv5NhK44Yfw0E1tt+m5vz0ZO1ptI9jDKBr3MWIEkpgw== dependencies: - "@vue/shared" "3.3.0-alpha.12" + "@vue/shared" "3.3.1" -"@vue/runtime-core@3.3.0-alpha.12": - version "3.3.0-alpha.12" - resolved "https://registry.yarnpkg.com/@vue/runtime-core/-/runtime-core-3.3.0-alpha.12.tgz#d0cb5c8279ca41e22b28f5ced738c3cd52dedb43" - integrity sha512-LQMIo9ZqG21l1B8JOGjlBP+z/ePGRl+Zu6NItgBl+FbPJHB7LEG5XSb+gmApamQKXRSynzoGeRY584dQ8PglIA== +"@vue/runtime-core@3.3.1": + version "3.3.1" + resolved "https://registry.yarnpkg.com/@vue/runtime-core/-/runtime-core-3.3.1.tgz#ed244dcb48d4e1e2079bf7d698a218e5b8ef5f62" + integrity sha512-Ljb37LYafhQqKIasc0r32Cva8gIh6VeSMjlwO6V03tCjHd18gmjP0F4UD+8/a59sGTysAgA8Rb9lIC2DVxRz2Q== dependencies: - "@vue/reactivity" "3.3.0-alpha.12" - "@vue/shared" "3.3.0-alpha.12" + "@vue/reactivity" "3.3.1" + "@vue/shared" "3.3.1" -"@vue/runtime-dom@3.3.0-alpha.12": - version "3.3.0-alpha.12" - resolved "https://registry.yarnpkg.com/@vue/runtime-dom/-/runtime-dom-3.3.0-alpha.12.tgz#7871c21e916bafdf3202e29c3fcecfdeba3bc4f9" - integrity sha512-4Q3HcFc3Y6eX36s9WN5zL519k0fsuSmLKuNhLPABgThxcirnlGMr3AN9Ru0D40UoKBN3AEwNuMLp89tl+xMwvA== +"@vue/runtime-dom@3.3.1": + version "3.3.1" + resolved "https://registry.yarnpkg.com/@vue/runtime-dom/-/runtime-dom-3.3.1.tgz#c07aef5b72385a2f22fdc82a203db6eba7f39fb4" + integrity sha512-NBjYbQPtMklb7lsJsM2Juv5Ygry6mvZP7PdH1GZqrzfLkvlplQT3qCtQMd/sib6yiy8t9m/Y4hVU7X9nzb9Oeg== dependencies: - "@vue/runtime-core" "3.3.0-alpha.12" - "@vue/shared" "3.3.0-alpha.12" + "@vue/runtime-core" "3.3.1" + "@vue/shared" "3.3.1" csstype "^3.1.1" -"@vue/server-renderer@3.3.0-alpha.12": - version "3.3.0-alpha.12" - resolved "https://registry.yarnpkg.com/@vue/server-renderer/-/server-renderer-3.3.0-alpha.12.tgz#b0cba2dbbf004b511be17af2dda483b4ec4b712c" - integrity sha512-jE9lDdXTQtedzHcyaccgWMYvEbiBcwF/r77zp95HmoYbprxw4QhcVZ+x49AtlDY5ndtJ0JRL4bDiKERz+uvxyg== +"@vue/server-renderer@3.3.1": + version "3.3.1" + resolved "https://registry.yarnpkg.com/@vue/server-renderer/-/server-renderer-3.3.1.tgz#c750a775ca4abd8213748a540cce7344af00dac4" + integrity sha512-sod8ggOwbkQXw3lBjfzrbdxRS9lw/lNHoMaXghHawNYowf+4WoaLWD5ouz6fPZadUqNKAsqK95p8DYb1vcVfPA== dependencies: - "@vue/compiler-ssr" "3.3.0-alpha.12" - "@vue/shared" "3.3.0-alpha.12" + "@vue/compiler-ssr" "3.3.1" + "@vue/shared" "3.3.1" -"@vue/shared@3.3.0-alpha.12": - version "3.3.0-alpha.12" - resolved "https://registry.yarnpkg.com/@vue/shared/-/shared-3.3.0-alpha.12.tgz#4af4819fa5da6c88fb0c45e54dc2e480d9ed60c8" - integrity sha512-5Kw7f53F+Vxl8F61fsrTg056mhhHchDmSK8fRdHlfuEuNz2EICi8ehaD+0A3PMo+Zd/S9OBhkOyG4oI6g+O9PA== +"@vue/shared@3.3.1": + version "3.3.1" + resolved "https://registry.yarnpkg.com/@vue/shared/-/shared-3.3.1.tgz#875a1c1847ec0646fc3dbe5581cb46b49ca3c469" + integrity sha512-ybDBtQ+479HL/bkeIOIAwgpeAEACzztkvulJLbK3JMFuTOv4qDivmV3AIsR8RHYJ+RD9tQxcHWBsX4GqEcYrfw== "@webassemblyjs/ast@1.11.1": version "1.11.1" @@ -9838,16 +9838,16 @@ vue-i18n@^9.1.7: "@intlify/vue-devtools" "9.1.7" "@vue/devtools-api" "^6.0.0-beta.7" -vue@^3.3.0-alpha.12: - version "3.3.0-alpha.12" - resolved "https://registry.yarnpkg.com/vue/-/vue-3.3.0-alpha.12.tgz#8a9ee1d4fe315f7f80521fc76bd4de1b470b838a" - integrity sha512-+NPimtt2nJ37/m49+9Ie/0gndIZ3PGXTfC0ITBZPKxsq1yphnM4bgD66OCdO98ci5W2lC9FfBRcEaCA5HFxekA== - dependencies: - "@vue/compiler-dom" "3.3.0-alpha.12" - "@vue/compiler-sfc" "3.3.0-alpha.12" - "@vue/runtime-dom" "3.3.0-alpha.12" - "@vue/server-renderer" "3.3.0-alpha.12" - "@vue/shared" "3.3.0-alpha.12" +vue@^3.3.0: + version "3.3.1" + resolved "https://registry.yarnpkg.com/vue/-/vue-3.3.1.tgz#267372cecd953900412bb00108bb56a591f57d33" + integrity sha512-3Rwy4I5idbPVSDZu6I+fFh6tdDSZbauImCTqLxE7y0LpHtiDvPeY01OI7RkFPbva1nk4hoO0sv/NzosH2h60sg== + dependencies: + "@vue/compiler-dom" "3.3.1" + "@vue/compiler-sfc" "3.3.1" + "@vue/runtime-dom" "3.3.1" + "@vue/server-renderer" "3.3.1" + "@vue/shared" "3.3.1" w3c-hr-time@^1.0.2: version "1.0.2" From 6269698f9fda37f0e3849db3e8b8e67ad1862f57 Mon Sep 17 00:00:00 2001 From: Evan You Date: Thu, 11 May 2023 11:25:37 +0100 Subject: [PATCH 03/40] fix: support propsDestructure and defineModel options --- src/index.ts | 14 ++++++++++++++ src/resolveScript.ts | 2 ++ 2 files changed, 16 insertions(+) diff --git a/src/index.ts b/src/index.ts index ec6f7dc59..dabc5c000 100644 --- a/src/index.ts +++ b/src/index.ts @@ -30,7 +30,21 @@ export interface VueLoaderOptions { transformAssetUrls?: SFCTemplateCompileOptions['transformAssetUrls'] compiler?: TemplateCompiler | string compilerOptions?: CompilerOptions + /** + * TODO remove in 3.4 + * @deprecated + */ reactivityTransform?: boolean + + /** + * @experimental + */ + propsDestructure?: boolean + /** + * @experimental + */ + defineModel?: boolean + customElement?: boolean | RegExp hotReload?: boolean diff --git a/src/resolveScript.ts b/src/resolveScript.ts index 760683bba..ee954ee07 100644 --- a/src/resolveScript.ts +++ b/src/resolveScript.ts @@ -62,6 +62,8 @@ export function resolveScript( isProd, inlineTemplate: enableInline, reactivityTransform: options.reactivityTransform, + propsDestructure: options.propsDestructure, + defineModel: options.defineModel, babelParserPlugins: options.babelParserPlugins, templateOptions: { ssr: isServer, From fdee426f9985756f9fd28b7cf726f84945fd0f0b Mon Sep 17 00:00:00 2001 From: Evan You Date: Thu, 11 May 2023 11:27:22 +0100 Subject: [PATCH 04/40] v17.1.1 --- package.json | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/package.json b/package.json index 076de066e..2f5134289 100644 --- a/package.json +++ b/package.json @@ -1,6 +1,6 @@ { "name": "vue-loader", - "version": "17.1.0", + "version": "17.1.1", "license": "MIT", "author": "Evan You", "repository": "vuejs/vue-loader", From b96af78e80afcbee3420f64d2483f8e1d7a6fad0 Mon Sep 17 00:00:00 2001 From: Evan You Date: Thu, 11 May 2023 11:27:51 +0100 Subject: [PATCH 05/40] chore: changelog --- CHANGELOG.md | 18 ++++++++++++++++++ 1 file changed, 18 insertions(+) diff --git a/CHANGELOG.md b/CHANGELOG.md index ff0cbe416..4f4f4e633 100644 --- a/CHANGELOG.md +++ b/CHANGELOG.md @@ -1,3 +1,21 @@ +## [17.1.1](https://github.com/vuejs/vue-loader/compare/v17.1.0...v17.1.1) (2023-05-11) + + +### Bug Fixes + +* support propsDestructure and defineModel options ([6269698](https://github.com/vuejs/vue-loader/commit/6269698f9fda37f0e3849db3e8b8e67ad1862f57)) + + + +# [17.1.0](https://github.com/vuejs/vue-loader/compare/v17.1.0-beta.0...v17.1.0) (2023-04-26) + + +### Bug Fixes + +* do not throw when `Rule.layer` ([#2000](https://github.com/vuejs/vue-loader/issues/2000)) ([ef589df](https://github.com/vuejs/vue-loader/commit/ef589df2956506a5a7bbc050c476501d32dd8469)) + + + # [17.1.0](https://github.com/vuejs/vue-loader/compare/v17.1.0-beta.0...v17.1.0) (2023-04-26) From a81dc0f573d216eefa13b0275f3fc147bf3e2ef3 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Michael=20Vo=C5=99=C3=AD=C5=A1ek?= Date: Sun, 28 May 2023 10:01:11 +0200 Subject: [PATCH 06/40] fix: keep build stable when run in a different path (#2040) By making the `exportHelperPath` a relative path so that the generated code is consistent. --- src/index.ts | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/src/index.ts b/src/index.ts index dabc5c000..aa4dfc9df 100644 --- a/src/index.ts +++ b/src/index.ts @@ -58,7 +58,7 @@ export interface VueLoaderOptions { let errorEmitted = false const { parse } = compiler -const exportHelperPath = JSON.stringify(require.resolve('./exportHelper')) +const exportHelperPath = require.resolve('./exportHelper') export default function loader( this: LoaderContext, @@ -296,7 +296,7 @@ export default function loader( if (!propsToAttach.length) { code += `\n\nconst __exports__ = script;` } else { - code += `\n\nimport exportComponent from ${exportHelperPath}` + code += `\n\nimport exportComponent from ${stringifyRequest(exportHelperPath)}` code += `\nconst __exports__ = /*#__PURE__*/exportComponent(script, [${propsToAttach .map(([key, val]) => `['${key}',${val}]`) .join(',')}])` From 40b93b9c2722e85a000de62e3eb8bc02facafd10 Mon Sep 17 00:00:00 2001 From: Haoqun Jiang Date: Sun, 28 May 2023 22:39:22 +0800 Subject: [PATCH 07/40] fix: properly close the watcher after tests --- src/pluginWebpack4.ts | 9 +++++++++ 1 file changed, 9 insertions(+) diff --git a/src/pluginWebpack4.ts b/src/pluginWebpack4.ts index fb0669870..335a6a0a9 100644 --- a/src/pluginWebpack4.ts +++ b/src/pluginWebpack4.ts @@ -171,6 +171,15 @@ class VueLoaderPlugin { watcher.close() } }) + + // In some cases, e.g. in this project's tests, + // even though needsHMR() returns true, webpack is not watching, thus no watchClose hook is called. + // So we need to close the watcher when webpack is done. + compiler.hooks.done.tap(id, () => { + if (watcher) { + watcher.close() + } + }) } } } From 4b726337691947b4a74f6293c3ace9385088b887 Mon Sep 17 00:00:00 2001 From: Haoqun Jiang Date: Mon, 29 May 2023 12:01:25 +0800 Subject: [PATCH 08/40] 17.1.2 --- package.json | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/package.json b/package.json index 2f5134289..bf2d9a177 100644 --- a/package.json +++ b/package.json @@ -1,6 +1,6 @@ { "name": "vue-loader", - "version": "17.1.1", + "version": "17.1.2", "license": "MIT", "author": "Evan You", "repository": "vuejs/vue-loader", From 6ad8056a3650b11fb2f51f89ffc5867046429603 Mon Sep 17 00:00:00 2001 From: Haoqun Jiang Date: Mon, 29 May 2023 12:09:00 +0800 Subject: [PATCH 09/40] chore: 17.1.2 changelog --- CHANGELOG.md | 10 ++++++++++ 1 file changed, 10 insertions(+) diff --git a/CHANGELOG.md b/CHANGELOG.md index 4f4f4e633..e9f7a7bb8 100644 --- a/CHANGELOG.md +++ b/CHANGELOG.md @@ -1,3 +1,13 @@ +## [17.1.2](https://github.com/vuejs/vue-loader/compare/v17.1.1...v17.1.2) (2023-05-29) + + +### Bug Fixes + +* keep build stable when run in a different path ([#2040](https://github.com/vuejs/vue-loader/issues/2040)) ([a81dc0f](https://github.com/vuejs/vue-loader/commit/a81dc0f573d216eefa13b0275f3fc147bf3e2ef3)) +* properly close the watcher after tests ([40b93b9](https://github.com/vuejs/vue-loader/commit/40b93b9c2722e85a000de62e3eb8bc02facafd10)) + + + ## [17.1.1](https://github.com/vuejs/vue-loader/compare/v17.1.0...v17.1.1) (2023-05-11) From 3149f6d69c2f456bdcfa23acc0da93473a93a764 Mon Sep 17 00:00:00 2001 From: Hana Date: Thu, 1 Jun 2023 16:50:21 +0800 Subject: [PATCH 10/40] feat: support experimental inline match resource (#2046) --- .github/workflows/ci.yml | 12 ++++++ README.md | 4 ++ jest.config.js | 10 ++++- package.json | 2 + src/index.ts | 85 +++++++++++++++++++++++++++++++++++----- src/pitcher.ts | 66 ++++++++++++++++++++++++++++--- src/plugin.ts | 23 +++++++---- src/pluginWebpack5.ts | 57 ++++++++++++++++++++++----- src/util.ts | 34 ++++++++++++++++ test/advanced.spec.ts | 21 +++++++--- test/edgeCases.spec.ts | 19 ++++----- test/style.spec.ts | 11 ++++-- test/template.spec.ts | 4 +- test/utils.ts | 46 +++++++++++++++++----- tsconfig.json | 10 +---- 15 files changed, 335 insertions(+), 69 deletions(-) diff --git a/.github/workflows/ci.yml b/.github/workflows/ci.yml index 80fba103b..368015cff 100644 --- a/.github/workflows/ci.yml +++ b/.github/workflows/ci.yml @@ -30,3 +30,15 @@ jobs: cache: 'yarn' - run: yarn install - run: yarn test + + test-webpack5-inline-match-resource: + runs-on: ubuntu-latest + steps: + - uses: actions/checkout@v2 + - name: Set node version to 16 + uses: actions/setup-node@v2 + with: + node-version: 16 + cache: 'yarn' + - run: yarn install + - run: yarn test:match-resource diff --git a/README.md b/README.md index aff9518b6..b3f34888c 100644 --- a/README.md +++ b/README.md @@ -4,6 +4,10 @@ - [Documentation](https://vue-loader.vuejs.org) +## v17.1+ Only Options + +- `experimentalInlineMatchResource: boolean`: enable [Inline matchResource](https://webpack.js.org/api/loaders/#inline-matchresource) for rule matching for vue-loader. + ## v16+ Only Options - `reactivityTransform: boolean`: enable [Vue Reactivity Transform](https://github.com/vuejs/rfcs/discussions/369) (SFCs only). diff --git a/jest.config.js b/jest.config.js index 4f710abb7..fc6d1b325 100644 --- a/jest.config.js +++ b/jest.config.js @@ -1,4 +1,12 @@ -console.log(`running tests with webpack ${process.env.WEBPACK4 ? '4' : '5'}...`) +const isWebpack4 = process.env.WEBPACK4 + +console.log( + `running tests with webpack ${isWebpack4 ? '4' : '5'}${ + !isWebpack4 && process.env.INLINE_MATCH_RESOURCE + ? ' with inline match resource enabled' + : '' + }...` +) module.exports = { preset: 'ts-jest', diff --git a/package.json b/package.json index bf2d9a177..7fd8ca6cd 100644 --- a/package.json +++ b/package.json @@ -14,6 +14,8 @@ "build": "tsc", "pretest": "tsc", "test": "jest", + "pretest:match-resource": "tsc", + "test:match-resource": "INLINE_MATCH_RESOURCE=true jest", "pretest:webpack4": "tsc", "test:webpack4": "WEBPACK4=true jest", "dev-example": "node example/devServer.js --config example/webpack.config.js --inline --hot", diff --git a/src/index.ts b/src/index.ts index aa4dfc9df..21be9e5c4 100644 --- a/src/index.ts +++ b/src/index.ts @@ -20,7 +20,12 @@ import { formatError } from './formatError' import VueLoaderPlugin from './plugin' import { canInlineTemplate } from './resolveScript' import { setDescriptor } from './descriptorCache' -import { getOptions, stringifyRequest as _stringifyRequest } from './util' +import { + getOptions, + stringifyRequest as _stringifyRequest, + genMatchResource, + testWebpack5, +} from './util' export { VueLoaderPlugin } @@ -51,6 +56,7 @@ export interface VueLoaderOptions { exposeFilename?: boolean appendExtension?: boolean enableTsInTemplate?: boolean + experimentalInlineMatchResource?: boolean isServerBuild?: boolean } @@ -90,18 +96,23 @@ export default function loader( rootContext, resourcePath, resourceQuery: _resourceQuery = '', + _compiler, } = loaderContext + const isWebpack5 = testWebpack5(_compiler) const rawQuery = _resourceQuery.slice(1) const incomingQuery = qs.parse(rawQuery) const resourceQuery = rawQuery ? `&${rawQuery}` : '' const options = (getOptions(loaderContext) || {}) as VueLoaderOptions + const enableInlineMatchResource = + isWebpack5 && Boolean(options.experimentalInlineMatchResource) const isServer = options.isServerBuild ?? target === 'node' const isProduction = mode === 'production' || process.env.NODE_ENV === 'production' const filename = resourcePath.replace(/\?.*$/, '') + const { descriptor, errors } = parse(source, { filename, sourceMap, @@ -167,10 +178,23 @@ export default function loader( if (script || scriptSetup) { const lang = script?.lang || scriptSetup?.lang isTS = !!(lang && /tsx?/.test(lang)) + const externalQuery = Boolean(script && !scriptSetup && script.src) + ? `&external` + : `` const src = (script && !scriptSetup && script.src) || resourcePath const attrsQuery = attrsToQuery((scriptSetup || script)!.attrs, 'js') - const query = `?vue&type=script${attrsQuery}${resourceQuery}` - const scriptRequest = stringifyRequest(src + query) + const query = `?vue&type=script${attrsQuery}${resourceQuery}${externalQuery}` + + let scriptRequest: string + + if (enableInlineMatchResource) { + scriptRequest = stringifyRequest( + genMatchResource(this, src, query, lang || 'js') + ) + } else { + scriptRequest = stringifyRequest(src + query) + } + scriptImport = `import script from ${scriptRequest}\n` + // support named exports @@ -184,13 +208,27 @@ export default function loader( const useInlineTemplate = canInlineTemplate(descriptor, isProduction) if (descriptor.template && !useInlineTemplate) { const src = descriptor.template.src || resourcePath + const externalQuery = Boolean(descriptor.template.src) ? `&external` : `` const idQuery = `&id=${id}` const scopedQuery = hasScoped ? `&scoped=true` : `` const attrsQuery = attrsToQuery(descriptor.template.attrs) const tsQuery = options.enableTsInTemplate !== false && isTS ? `&ts=true` : `` - const query = `?vue&type=template${idQuery}${scopedQuery}${tsQuery}${attrsQuery}${resourceQuery}` - templateRequest = stringifyRequest(src + query) + const query = `?vue&type=template${idQuery}${scopedQuery}${tsQuery}${attrsQuery}${resourceQuery}${externalQuery}` + + if (enableInlineMatchResource) { + templateRequest = stringifyRequest( + genMatchResource( + this, + src, + query, + options.enableTsInTemplate !== false && isTS ? 'ts' : 'js' + ) + ) + } else { + templateRequest = stringifyRequest(src + query) + } + templateImport = `import { ${renderFnName} } from ${templateRequest}` propsToAttach.push([renderFnName, renderFnName]) } @@ -205,12 +243,23 @@ export default function loader( .forEach((style, i) => { const src = style.src || resourcePath const attrsQuery = attrsToQuery(style.attrs, 'css') + const lang = String(style.attrs.lang || 'css') // make sure to only pass id when necessary so that we don't inject // duplicate tags when multiple components import the same css file const idQuery = !style.src || style.scoped ? `&id=${id}` : `` const inlineQuery = asCustomElement ? `&inline` : `` - const query = `?vue&type=style&index=${i}${idQuery}${inlineQuery}${attrsQuery}${resourceQuery}` - const styleRequest = stringifyRequest(src + query) + const externalQuery = Boolean(style.src) ? `&external` : `` + const query = `?vue&type=style&index=${i}${idQuery}${inlineQuery}${attrsQuery}${resourceQuery}${externalQuery}` + + let styleRequest + if (enableInlineMatchResource) { + styleRequest = stringifyRequest( + genMatchResource(this, src, query, lang) + ) + } else { + styleRequest = stringifyRequest(src + query) + } + if (style.module) { if (asCustomElement) { loaderContext.emitError( @@ -283,9 +332,27 @@ export default function loader( const issuerQuery = block.attrs.src ? `&issuerPath=${qs.escape(resourcePath)}` : '' - const query = `?vue&type=custom&index=${i}${blockTypeQuery}${issuerQuery}${attrsQuery}${resourceQuery}` + + const externalQuery = Boolean(block.attrs.src) ? `&external` : `` + const query = `?vue&type=custom&index=${i}${blockTypeQuery}${issuerQuery}${attrsQuery}${resourceQuery}${externalQuery}` + + let customRequest + + if (enableInlineMatchResource) { + customRequest = stringifyRequest( + genMatchResource( + this, + src as string, + query, + block.attrs.lang as string + ) + ) + } else { + customRequest = stringifyRequest(src + query) + } + return ( - `import block${i} from ${stringifyRequest(src + query)}\n` + + `import block${i} from ${customRequest}\n` + `if (typeof block${i} === 'function') block${i}(script)` ) }) diff --git a/src/pitcher.ts b/src/pitcher.ts index e90acc9a5..f12f5405a 100644 --- a/src/pitcher.ts +++ b/src/pitcher.ts @@ -1,6 +1,6 @@ import type { LoaderDefinitionFunction, LoaderContext } from 'webpack' import * as qs from 'querystring' -import { stringifyRequest } from './util' +import { getOptions, stringifyRequest, testWebpack5 } from './util' import { VueLoaderOptions } from '.' const selfPath = require.resolve('./index') @@ -58,7 +58,40 @@ export const pitch = function () { }) // Inject style-post-loader before css-loader for scoped CSS and trimming + const isWebpack5 = testWebpack5(context._compiler) + const options = (getOptions(context) || {}) as VueLoaderOptions if (query.type === `style`) { + if (isWebpack5 && context._compiler?.options.experiments.css) { + // If user enables `experiments.css`, then we are trying to emit css code directly. + // Although we can target requests like `xxx.vue?type=style` to match `type: "css"`, + // it will make the plugin a mess. + if (!options.experimentalInlineMatchResource) { + context.emitError( + new Error( + '`experimentalInlineMatchResource` should be enabled if `experiments.css` enabled currently' + ) + ) + return '' + } + + if (query.inline || query.module) { + context.emitError( + new Error( + '`inline` or `module` is currently not supported with `experiments.css` enabled' + ) + ) + return '' + } + + const loaderString = [stylePostLoaderPath, ...loaders] + .map((loader) => { + return typeof loader === 'string' ? loader : loader.request + }) + .join('!') + return `@import "${context.resourcePath}${ + query.lang ? `.${query.lang}` : '' + }${context.resourceQuery}!=!-!${loaderString}!${context.resource}";` + } const cssLoaderIndex = loaders.findIndex(isCSSLoader) if (cssLoaderIndex > -1) { // if inlined, ignore any loaders after css-loader and replace w/ inline @@ -71,7 +104,8 @@ export const pitch = function () { return genProxyModule( [...afterLoaders, stylePostLoaderPath, ...beforeLoaders], context, - !!query.module || query.inline != null + !!query.module || query.inline != null, + (query.lang as string) || 'css' ) } } @@ -84,15 +118,21 @@ export const pitch = function () { // Rewrite request. Technically this should only be done when we have deduped // loaders. But somehow this is required for block source maps to work. - return genProxyModule(loaders, context, query.type !== 'template') + return genProxyModule( + loaders, + context, + query.type !== 'template', + query.ts ? 'ts' : (query.lang as string) + ) } function genProxyModule( loaders: (Loader | string)[], context: LoaderContext, - exportDefault = true + exportDefault = true, + lang = 'js' ) { - const request = genRequest(loaders, context) + const request = genRequest(loaders, lang, context) // return a proxy module which simply re-exports everything from the // actual request. Note for template blocks the compiled module has no // default export. @@ -104,12 +144,28 @@ function genProxyModule( function genRequest( loaders: (Loader | string)[], + lang: string, context: LoaderContext ) { + const isWebpack5 = testWebpack5(context._compiler) + const options = (getOptions(context) || {}) as VueLoaderOptions + const enableInlineMatchResource = + isWebpack5 && options.experimentalInlineMatchResource + const loaderStrings = loaders.map((loader) => { return typeof loader === 'string' ? loader : loader.request }) const resource = context.resourcePath + context.resourceQuery + + if (enableInlineMatchResource) { + return stringifyRequest( + context, + `${context.resourcePath}${lang ? `.${lang}` : ''}${ + context.resourceQuery + }!=!-!${[...loaderStrings, resource].join('!')}` + ) + } + return stringifyRequest( context, '-!' + [...loaderStrings, resource].join('!') diff --git a/src/plugin.ts b/src/plugin.ts index a7b4a42d4..72caaadce 100644 --- a/src/plugin.ts +++ b/src/plugin.ts @@ -1,19 +1,26 @@ -import webpack from 'webpack' import type { Compiler } from 'webpack' +import { testWebpack5 } from './util' declare class VueLoaderPlugin { static NS: string apply(compiler: Compiler): void } -let Plugin: typeof VueLoaderPlugin +const NS = 'vue-loader' -if (webpack.version && webpack.version[0] > '4') { - // webpack5 and upper - Plugin = require('./pluginWebpack5').default -} else { - // webpack4 and lower - Plugin = require('./pluginWebpack4').default +class Plugin { + static NS = NS + apply(compiler: Compiler) { + let Ctor: typeof VueLoaderPlugin + if (testWebpack5(compiler)) { + // webpack5 and upper + Ctor = require('./pluginWebpack5').default + } else { + // webpack4 and lower + Ctor = require('./pluginWebpack4').default + } + new Ctor().apply(compiler) + } } export default Plugin diff --git a/src/pluginWebpack5.ts b/src/pluginWebpack5.ts index 75152851b..649cd54c7 100644 --- a/src/pluginWebpack5.ts +++ b/src/pluginWebpack5.ts @@ -1,6 +1,6 @@ import * as qs from 'querystring' import type { VueLoaderOptions } from './' -import type { RuleSetRule, Compiler } from 'webpack' +import type { RuleSetRule, Compiler, RuleSetUse } from 'webpack' import { needHMR } from './util' import { clientCache, typeDepToSFCMap } from './resolveScript' import { compiler as vueCompiler } from './compiler' @@ -146,7 +146,7 @@ class VueLoaderPlugin { ) } - // get the normlized "use" for vue files + // get the normalized "use" for vue files const vueUse = vueRules .filter((rule) => rule.type === 'use') .map((rule) => rule.value) @@ -170,6 +170,8 @@ class VueLoaderPlugin { const vueLoaderUse = vueUse[vueLoaderUseIndex] const vueLoaderOptions = (vueLoaderUse.options = vueLoaderUse.options || {}) as VueLoaderOptions + const enableInlineMatchResource = + vueLoaderOptions.experimentalInlineMatchResource // for each user rule (except the vue rule), create a cloned rule // that targets the corresponding language blocks in *.vue files. @@ -221,16 +223,53 @@ class VueLoaderPlugin { const parsed = qs.parse(query.slice(1)) return parsed.vue != null }, + options: vueLoaderOptions, } // replace original rules - compiler.options.module!.rules = [ - pitcher, - ...jsRulesForRenderFn, - templateCompilerRule, - ...clonedRules, - ...rules, - ] + if (enableInlineMatchResource) { + // Match rules using `vue-loader` + const vueLoaderRules = rules.filter((rule) => { + const matchOnce = (use?: RuleSetUse) => { + let loaderString = '' + + if (!use) { + return loaderString + } + + if (typeof use === 'string') { + loaderString = use + } else if (Array.isArray(use)) { + loaderString = matchOnce(use[0]) + } else if (typeof use === 'object' && use.loader) { + loaderString = use.loader + } + return loaderString + } + + const loader = rule.loader || matchOnce(rule.use) + return ( + loader === require('../package.json').name || + loader.startsWith(require.resolve('./index')) + ) + }) + + compiler.options.module!.rules = [ + pitcher, + ...rules.filter((rule) => !vueLoaderRules.includes(rule)), + templateCompilerRule, + ...clonedRules, + ...vueLoaderRules, + ] + } else { + compiler.options.module!.rules = [ + pitcher, + ...jsRulesForRenderFn, + templateCompilerRule, + ...clonedRules, + ...rules, + ] + } // 3.3 HMR support for imported types if ( diff --git a/src/util.ts b/src/util.ts index 1a2718fac..998f14011 100644 --- a/src/util.ts +++ b/src/util.ts @@ -1,4 +1,5 @@ import type { Compiler, LoaderContext } from 'webpack' +import qs from 'querystring' import type { SFCDescriptor, CompilerOptions } from 'vue/compiler-sfc' import type { VueLoaderOptions } from '.' import * as path from 'path' @@ -163,3 +164,36 @@ export function stringifyRequest( .join('!') ) } + +export function genMatchResource( + context: LoaderContext, + resourcePath: string, + resourceQuery?: string, + lang?: string +) { + resourceQuery = resourceQuery || '' + + const loaders: string[] = [] + const parsedQuery = qs.parse(resourceQuery.slice(1)) + + // process non-external resources + if ('vue' in parsedQuery && !('external' in parsedQuery)) { + const currentRequest = context.loaders + .slice(context.loaderIndex) + .map((obj) => obj.request) + loaders.push(...currentRequest) + } + const loaderString = loaders.join('!') + + return `${resourcePath}${lang ? `.${lang}` : ''}${resourceQuery}!=!${ + loaderString ? `${loaderString}!` : '' + }${resourcePath}${resourceQuery}` +} + +export const testWebpack5 = (compiler?: Compiler) => { + if (!compiler) { + return false + } + const webpackVersion = compiler?.webpack?.version + return Boolean(webpackVersion && Number(webpackVersion.split('.')[0]) > 4) +} diff --git a/test/advanced.spec.ts b/test/advanced.spec.ts index 9fee7e833..eec28bc95 100644 --- a/test/advanced.spec.ts +++ b/test/advanced.spec.ts @@ -1,6 +1,12 @@ import { SourceMapConsumer } from 'source-map' import { fs as mfs } from 'memfs' -import { bundle, mockBundleAndRun, normalizeNewline, genId } from './utils' +import { + bundle, + mockBundleAndRun, + normalizeNewline, + genId, + DEFAULT_VUE_USE, +} from './utils' const MiniCssExtractPlugin = require('mini-css-extract-plugin') @@ -10,7 +16,7 @@ test('support chaining with other loaders', async () => { modify: (config) => { config!.module!.rules[0] = { test: /\.vue$/, - use: ['vue-loader', require.resolve('./mock-loaders/js')], + use: [DEFAULT_VUE_USE, require.resolve('./mock-loaders/js')], } }, }) @@ -24,7 +30,7 @@ test.skip('inherit queries on files', async () => { modify: (config) => { config!.module!.rules[0] = { test: /\.vue$/, - use: ['vue-loader', require.resolve('./mock-loaders/query')], + use: [DEFAULT_VUE_USE, require.resolve('./mock-loaders/query')], } }, }) @@ -92,7 +98,7 @@ test('extract CSS', async () => { config.module.rules = [ { test: /\.vue$/, - use: 'vue-loader', + use: [DEFAULT_VUE_USE], }, { test: /\.css$/, @@ -126,7 +132,7 @@ test('extract CSS with code spliting', async () => { config.module.rules = [ { test: /\.vue$/, - use: 'vue-loader', + use: [DEFAULT_VUE_USE], }, { test: /\.css$/, @@ -153,7 +159,10 @@ test('support rules with oneOf', async () => { entry, modify: (config: any) => { config!.module!.rules = [ - { test: /\.vue$/, loader: 'vue-loader' }, + { + test: /\.vue$/, + use: [DEFAULT_VUE_USE], + }, { test: /\.css$/, use: 'style-loader', diff --git a/test/edgeCases.spec.ts b/test/edgeCases.spec.ts index d5394b3d1..a0c5aadfc 100644 --- a/test/edgeCases.spec.ts +++ b/test/edgeCases.spec.ts @@ -1,6 +1,12 @@ import * as path from 'path' import webpack from 'webpack' -import { mfs, bundle, mockBundleAndRun, normalizeNewline } from './utils' +import { + mfs, + bundle, + mockBundleAndRun, + normalizeNewline, + DEFAULT_VUE_USE, +} from './utils' // @ts-ignore function assertComponent({ @@ -37,7 +43,7 @@ test('vue rule with include', async () => { config.module.rules[i] = { test: /\.vue$/, include: /fixtures/, - loader: 'vue-loader', + use: [DEFAULT_VUE_USE], } }, }) @@ -52,7 +58,7 @@ test('test-less oneOf rules', async () => { config!.module!.rules = [ { test: /\.vue$/, - loader: 'vue-loader', + use: [DEFAULT_VUE_USE], }, { oneOf: [ @@ -79,12 +85,7 @@ test('normalize multiple use + options', async () => { ) config!.module!.rules[i] = { test: /\.vue$/, - use: [ - { - loader: 'vue-loader', - options: {}, - }, - ], + use: [DEFAULT_VUE_USE], } }, }) diff --git a/test/style.spec.ts b/test/style.spec.ts index 94a04eb0e..4bb998dbe 100644 --- a/test/style.spec.ts +++ b/test/style.spec.ts @@ -1,4 +1,9 @@ -import { mockBundleAndRun, genId, normalizeNewline } from './utils' +import { + mockBundleAndRun, + genId, + normalizeNewline, + DEFAULT_VUE_USE, +} from './utils' test('scoped style', async () => { const { window, instance, componentModule } = await mockBundleAndRun({ @@ -109,7 +114,7 @@ test('CSS Modules', async () => { config!.module!.rules = [ { test: /\.vue$/, - loader: 'vue-loader', + use: [DEFAULT_VUE_USE], }, { test: /\.css$/, @@ -178,7 +183,7 @@ test('CSS Modules Extend', async () => { config!.module!.rules = [ { test: /\.vue$/, - loader: 'vue-loader', + use: [DEFAULT_VUE_USE], }, { test: /\.css$/, diff --git a/test/template.spec.ts b/test/template.spec.ts index 52eda51cb..e46758a54 100644 --- a/test/template.spec.ts +++ b/test/template.spec.ts @@ -1,5 +1,5 @@ import * as path from 'path' -import { mockBundleAndRun, normalizeNewline } from './utils' +import { DEFAULT_VUE_USE, mockBundleAndRun, normalizeNewline } from './utils' test('apply babel transformations to expressions in template', async () => { const { instance } = await mockBundleAndRun({ @@ -111,7 +111,7 @@ test('should allow process custom file', async () => { rules: [ { test: /\.svg$/, - loader: 'vue-loader', + use: [DEFAULT_VUE_USE], }, ], }, diff --git a/test/utils.ts b/test/utils.ts index 628d24da8..0214fd4c9 100644 --- a/test/utils.ts +++ b/test/utils.ts @@ -9,6 +9,13 @@ import { JSDOM, VirtualConsole } from 'jsdom' import { VueLoaderPlugin } from '..' import type { VueLoaderOptions } from '..' +export const DEFAULT_VUE_USE = { + loader: 'vue-loader', + options: { + experimentalInlineMatchResource: Boolean(process.env.INLINE_MATCH_RESOURCE), + }, +} + const baseConfig: webpack.Configuration = { mode: 'development', devtool: false, @@ -29,11 +36,7 @@ const baseConfig: webpack.Configuration = { rules: [ { test: /\.vue$/, - loader: 'vue-loader', - }, - { - test: /\.css$/, - use: ['style-loader', 'css-loader'], + use: [DEFAULT_VUE_USE], }, { test: /\.ts$/, @@ -73,16 +76,41 @@ export function bundle( }> { let config: BundleOptions = merge({}, baseConfig, options) + if (!options.experiments?.css) { + config.module?.rules?.push({ + test: /\.css$/, + use: ['style-loader', 'css-loader'], + }) + } + if (config.vue && config.module) { - const vueOptions = options.vue + const vueOptions = { + // Test experimental inline match resource by default + experimentalInlineMatchResource: Boolean( + process.env.INLINE_MATCH_RESOURCE + ), + ...options.vue, + } + delete config.vue const vueIndex = config.module.rules!.findIndex( (r: any) => r.test instanceof RegExp && r.test.test('.vue') ) const vueRule = config.module.rules![vueIndex] - config.module.rules![vueIndex] = Object.assign({}, vueRule, { - options: vueOptions, - }) + + // Detect `Rule.use` or `Rule.loader` and `Rule.options` combination + if (vueRule && typeof vueRule === 'object' && Array.isArray(vueRule.use)) { + // Vue usually locates at the first loader + if (typeof vueRule.use?.[0] === 'object') { + vueRule.use[0] = Object.assign({}, vueRule.use[0], { + options: vueOptions, + }) + } + } else { + config.module.rules![vueIndex] = Object.assign({}, vueRule, { + options: vueOptions, + }) + } } if (typeof config.entry === 'string' && /\.vue/.test(config.entry)) { diff --git a/tsconfig.json b/tsconfig.json index 15b7fee10..aead67b91 100644 --- a/tsconfig.json +++ b/tsconfig.json @@ -14,13 +14,7 @@ "noImplicitAny": true, "removeComments": false, "skipLibCheck": true, - "lib": [ - "es6", - "es7", - "DOM" - ] + "lib": ["es6", "es7", "DOM"] }, - "include": [ - "src" - ] + "include": ["src"] } From 659d51ffd3a0da2d07d8ef0b8986ec434b8792a7 Mon Sep 17 00:00:00 2001 From: Haoqun Jiang Date: Mon, 29 May 2023 12:13:51 +0800 Subject: [PATCH 11/40] chore: remove duplicate entries in CHANGELOG.md --- CHANGELOG.md | 23 ----------------------- 1 file changed, 23 deletions(-) diff --git a/CHANGELOG.md b/CHANGELOG.md index e9f7a7bb8..81fc0c72f 100644 --- a/CHANGELOG.md +++ b/CHANGELOG.md @@ -26,29 +26,6 @@ -# [17.1.0](https://github.com/vuejs/vue-loader/compare/v17.1.0-beta.0...v17.1.0) (2023-04-26) - - -### Bug Fixes - -* do not throw when `Rule.layer` ([#2000](https://github.com/vuejs/vue-loader/issues/2000)) ([ef589df](https://github.com/vuejs/vue-loader/commit/ef589df2956506a5a7bbc050c476501d32dd8469)) - - - -# [17.1.0-beta.0](https://github.com/vuejs/vue-loader/compare/v17.0.1...v17.1.0-beta.0) (2023-04-19) - - -### Bug Fixes - -* reference project compiler, fixes [#2031](https://github.com/vuejs/vue-loader/issues/2031) ([#2038](https://github.com/vuejs/vue-loader/issues/2038)) ([cc6fa9e](https://github.com/vuejs/vue-loader/commit/cc6fa9ebf85972a08fc8bbc359b0093b15790745)) - - -### Features - -* support 3.3 imported types hmr ([bbd98fc](https://github.com/vuejs/vue-loader/commit/bbd98fc8bdc17fcbffb456a5ffe772bc184f22e4)) - - - # [17.1.0-beta.0](https://github.com/vuejs/vue-loader/compare/v17.0.1...v17.1.0-beta.0) (2023-04-19) From 27026acad3aa947d7d2a3d07fd8cb9f01b98ad32 Mon Sep 17 00:00:00 2001 From: Haoqun Jiang Date: Thu, 1 Jun 2023 16:53:43 +0800 Subject: [PATCH 12/40] 17.2.1 --- package.json | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/package.json b/package.json index 7fd8ca6cd..45c9cc97b 100644 --- a/package.json +++ b/package.json @@ -1,6 +1,6 @@ { "name": "vue-loader", - "version": "17.1.2", + "version": "17.2.1", "license": "MIT", "author": "Evan You", "repository": "vuejs/vue-loader", From 4a6c1037d16c67d0399fe76b623c6acd6f9459f5 Mon Sep 17 00:00:00 2001 From: Haoqun Jiang Date: Thu, 1 Jun 2023 16:58:24 +0800 Subject: [PATCH 13/40] chore: v17.2.1 changelog [skip ci] --- CHANGELOG.md | 11 +++++++++++ 1 file changed, 11 insertions(+) diff --git a/CHANGELOG.md b/CHANGELOG.md index 81fc0c72f..be886b7b4 100644 --- a/CHANGELOG.md +++ b/CHANGELOG.md @@ -1,3 +1,14 @@ +## [17.2.1](https://github.com/vuejs/vue-loader/compare/v17.1.2...v17.2.1) (2023-06-01) + + +### Features + +* A new `experimentalInlineMatchResource` option (webpack 5 only), which leverages webpack 5's inline match resource feature and works well with the [`experiments.css`](https://webpack.js.org/configuration/experiments/#experimentscss) feature ([#2046](https://github.com/vuejs/vue-loader/issues/2046)) ([3149f6d](https://github.com/vuejs/vue-loader/commit/3149f6d69c2f456bdcfa23acc0da93473a93a764)) + + +Note: v17.2.0 was released by accident, it has the same content as v17.1.2, therefore not included in the changelog. + + ## [17.1.2](https://github.com/vuejs/vue-loader/compare/v17.1.1...v17.1.2) (2023-05-29) From 6968b38a661b5bfd5df8004f45249718dd906941 Mon Sep 17 00:00:00 2001 From: Hana Date: Fri, 2 Jun 2023 14:03:09 +0800 Subject: [PATCH 14/40] chore: update readme (#2047) --- README.md | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/README.md b/README.md index b3f34888c..aae03ae3d 100644 --- a/README.md +++ b/README.md @@ -4,7 +4,7 @@ - [Documentation](https://vue-loader.vuejs.org) -## v17.1+ Only Options +## v17.2.1+ Only Options - `experimentalInlineMatchResource: boolean`: enable [Inline matchResource](https://webpack.js.org/api/loaders/#inline-matchresource) for rule matching for vue-loader. From f3f45df925bcd80307232e7410ead355f87953d3 Mon Sep 17 00:00:00 2001 From: Hana Date: Fri, 2 Jun 2023 14:16:32 +0800 Subject: [PATCH 15/40] fix: windows path for `experiments.css` (#2049) --- src/pitcher.ts | 10 +++++++--- 1 file changed, 7 insertions(+), 3 deletions(-) diff --git a/src/pitcher.ts b/src/pitcher.ts index f12f5405a..426dd1c7d 100644 --- a/src/pitcher.ts +++ b/src/pitcher.ts @@ -88,9 +88,13 @@ export const pitch = function () { return typeof loader === 'string' ? loader : loader.request }) .join('!') - return `@import "${context.resourcePath}${ - query.lang ? `.${query.lang}` : '' - }${context.resourceQuery}!=!-!${loaderString}!${context.resource}";` + const styleRequest = stringifyRequest( + context, + `${context.resourcePath}${query.lang ? `.${query.lang}` : ''}${ + context.resourceQuery + }!=!-!${loaderString}!${context.resource}` + ) + return `@import ${styleRequest};` } const cssLoaderIndex = loaders.findIndex(isCSSLoader) if (cssLoaderIndex > -1) { From 790ef9dcee58d9eeca4e482294210ec29d9524f1 Mon Sep 17 00:00:00 2001 From: Haoqun Jiang Date: Fri, 2 Jun 2023 14:21:04 +0800 Subject: [PATCH 16/40] 17.2.2 --- package.json | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/package.json b/package.json index 45c9cc97b..0899b137e 100644 --- a/package.json +++ b/package.json @@ -1,6 +1,6 @@ { "name": "vue-loader", - "version": "17.2.1", + "version": "17.2.2", "license": "MIT", "author": "Evan You", "repository": "vuejs/vue-loader", From 8357e071c45e77de0889a9feedf2079a327f69d4 Mon Sep 17 00:00:00 2001 From: Haoqun Jiang Date: Fri, 2 Jun 2023 14:21:35 +0800 Subject: [PATCH 17/40] chore: v17.2.2 changelog --- CHANGELOG.md | 9 +++++++++ 1 file changed, 9 insertions(+) diff --git a/CHANGELOG.md b/CHANGELOG.md index be886b7b4..84ce6ea2d 100644 --- a/CHANGELOG.md +++ b/CHANGELOG.md @@ -1,3 +1,12 @@ +## [17.2.2](https://github.com/vuejs/vue-loader/compare/v17.2.1...v17.2.2) (2023-06-02) + + +### Bug Fixes + +* windows path for `experiments.css` ([#2049](https://github.com/vuejs/vue-loader/issues/2049)) ([f3f45df](https://github.com/vuejs/vue-loader/commit/f3f45df925bcd80307232e7410ead355f87953d3)) + + + ## [17.2.1](https://github.com/vuejs/vue-loader/compare/v17.1.2...v17.2.1) (2023-06-01) From 98782e794fadca83b600b047b55aa6f0c230cc25 Mon Sep 17 00:00:00 2001 From: Jinjiang Date: Sat, 7 Oct 2023 14:57:44 +0800 Subject: [PATCH 18/40] feat: skip normal css files without scoped flag in stylePostLoader (#2053) --- src/stylePostLoader.ts | 12 ++++++++++++ test/core.spec.ts | 4 ++-- test/template.spec.ts | 4 ++-- 3 files changed, 16 insertions(+), 4 deletions(-) diff --git a/src/stylePostLoader.ts b/src/stylePostLoader.ts index 544924ea6..59c664d5b 100644 --- a/src/stylePostLoader.ts +++ b/src/stylePostLoader.ts @@ -9,6 +9,18 @@ const { compileStyle } = compiler // for any diff --git a/test/style.spec.ts b/test/style.spec.ts index 4bb998dbe..72fb3cbd3 100644 --- a/test/style.spec.ts +++ b/test/style.spec.ts @@ -198,4 +198,22 @@ test('CSS Modules Extend', async () => { expect(style).toContain(`.${instance.$style.red} {\n color: #FF0000;\n}`) }) -test.todo('experimental