Repository: sverweij/dependency-cruiser
Pull request #942 (2024-07-01 10:22:51)

fix(extract/transpile): transpile script setup with vue 2

## Description

Currently the vue2 template compiler only extracts content from the `script` section of single file components. [Script setup SFCs are supported since version 2.17](https://github.com/vuejs/vue/blob/main/CHANGELOG.md#270-2022-07-01). This MR updates the implementation analogous to the vue 3 `@vue/compiler-sfc` to extract content from `<setup script>` components in case they exist

## Motivation and Context

Without this change Vue 2 components using `<script setup>` appear empty to dependency cruiser leading to missing imports.

## How Has This Been Tested?

- [x] Manually testing the fix in a local project
- [x] green ci

## Types of changes

- [x] Bug fix (non-breaking change which fixes an issue)
- [ ] Documentation only change
- [ ] Refactor (non-breaking change which fixes an issue without changing functionality)
- [ ] New feature (non-breaking change which adds functionality)
- [ ] Breaking change (fix or feature that would cause existing functionality to change)

## Checklist

<!--- Go over all the following points, and put an `x` in all the boxes that apply. -->
<!--- If you're unsure about any of these, don't hesitate to ask. We're here to help! -->

- [x] :book: My change doesn't require a documentation update
- [x] :balance_scale:
  - The contribution will be subject to [The MIT license](https://github.com/sverweij/dependency-cruiser/blob/main/LICENSE), and I'm OK with that.
  - The contribution is my own original work.
  - I am ok with the stuff in [**CONTRIBUTING.md**](https://github.com/sverweij/dependency-cruiser/blob/main/.github/CONTRIBUTING.md).


codeclimate[bot]: Code Climate has analyzed commit 6c43fa4b and detected **0 issues** on this pull request.

View more on [Code Climate](https://codeclimate.com/github/sverweij/dependency-cruiser/pull/942).

sverweij: Hi @ferdynator thanks for this fix! I totally missed this was possible in vue2.

Code modification is clear & great to see additional unit tests to prevent regression

=> LGTM

Patch:
diff --git a/src/extract/transpile/vue-template-wrap.cjs b/src/extract/transpile/vue-template-wrap.cjs
index e8b502e9..9fd12073 100644
--- a/src/extract/transpile/vue-template-wrap.cjs
+++ b/src/extract/transpile/vue-template-wrap.cjs
@@ -53,7 +53,15 @@ function vue3Transpile(pSource) {
 }
 
 function vue2Transpile(pSource) {
-  return vueTemplateCompiler.parseComponent(pSource)?.script?.content ?? "";
+  const lParsedComponent = vueTemplateCompiler.parseComponent(pSource);
+  const lScriptContent = lParsedComponent?.script?.content ?? "";
+  const lScriptSetupContent = lParsedComponent?.scriptSetup?.content ?? "";
+
+  if (lScriptContent && lScriptSetupContent) {
+    return lScriptContent + EOL + lScriptSetupContent;
+  }
+
+  return lScriptContent || lScriptSetupContent;
 }
 
 module.exports = {


Test patch:
diff --git a/test/extract/transpile/vue-template-wrap.spec.mjs b/test/extract/transpile/vue-template-wrap.spec.mjs
index 83781193..5aaa7daa 100644
--- a/test/extract/transpile/vue-template-wrap.spec.mjs
+++ b/test/extract/transpile/vue-template-wrap.spec.mjs
@@ -43,4 +43,42 @@ describe("[I] vue transpiler", () => {
       normalizeNewline(""),
     );
   });
+
+  it("extracts the script setup content from a vue SFC", () => {
+    equal(
+      normalizeNewline(
+        wrap.transpile(
+          readFileSync(
+            join(__dirname, "__mocks__/vue-script-setup.vue"),
+            "utf8",
+          ),
+        ),
+      ),
+      normalizeNewline(
+        readFileSync(
+          join(__dirname, "__fixtures__/vue-script-setup.js"),
+          "utf8",
+        ),
+      ),
+    );
+  });
+
+  it("extracts the script setup content and script content from a vue SFC", () => {
+    equal(
+      normalizeNewline(
+        wrap.transpile(
+          readFileSync(
+            join(__dirname, "__mocks__/vue-script-setup-and-script.vue"),
+            "utf8",
+          ),
+        ),
+      ),
+      normalizeNewline(
+        readFileSync(
+          join(__dirname, "__fixtures__/vue-script-setup-and-script.js"),
+          "utf8",
+        ),
+      ),
+    );
+  });
 });