Search code examples
typescriptvuejs3node-modulesvite

Typescript using d.ts files from node_modules


I created a node module with vite and used it on my project.

The folder structure looks like this:

root
|-my-module
||-lib
|||-index.d.ts // contains all definitions for components
|||-dict.enum.d.ts // contains a dictionary
||-src
|||-components
||||-MyComponent.vue
|||-dict.enum.ts
|||-main.ts
|||-App.vue
|-project

Now I am installing this module using npm install ../my-module which works fine besides typescript does not find the definition files. I need to add my own types.d.ts to my project folder in order to have no compiler errors.

How can I use the generated definition files?

this is what my tsconfig looks like:

  "compilerOptions": {
    "target": "ES2020",
    "useDefineForClassFields": true,
    "module": "ESNext",
    "lib": ["ES2020", "DOM", "DOM.Iterable"],
    "skipLibCheck": true,

    /* Bundler mode */
    "moduleResolution": "bundler",
    "allowImportingTsExtensions": true,
    "resolveJsonModule": true,
    "isolatedModules": true,
    "noEmit": true,
    "jsx": "preserve",

    /* Linting */
    "strict": true,
    "noUnusedLocals": true,
    "noUnusedParameters": true,
    "noFallthroughCasesInSwitch": true,

    /* Typing */
    "typeRoots": [
      "node_modules/@types",
      "node_modules/my-module"
    ]
  },
  "include": ["src/**/*.ts", "src/**/*.d.ts", "src/**/*.tsx", "src/**/*.vue"],
  "references": [{ "path": "./tsconfig.node.json" }]
}

EDIT 1

This is my package.json

{
    [...]
    "type": "module",
    "scripts": {
        "serve": "vite",
        "build": "vue-tsc --declaration && vite build",
        "preview": "vite preview"
    },
    "main": "./lib/my-module.umd.cjs",
    "module": "./lib/my-module.js",
    "exports": {
        ".": {
            "import": "./lib/my-module.js",
            "require": "./lib/my-module.umd.cjs"
        },
        "./style.css": "./lib/style.css"
    },
    "types": "./lib/index.d.ts",
    "dependencies": {
        "vite-plugin-dts": "^3.5.2",
        "vue": "^3.3.4"
    },
    "devDependencies": {
        "@vitejs/plugin-vue": "^4.2.3",
        "typescript": "^5.1.6",
        "vite": "^4.4.5",
        "vite-plugin-svg-icons": "^2.0.1",
        "vue-tsc": "^1.8.8"
    }
}

By now I realized that the problem more occurred because of what the vite-plugin-dts creates. This is my Vite config:

import { defineConfig } from "vite";
import path, { resolve } from "path";
import { createSvgIconsPlugin } from "vite-plugin-svg-icons";
import vue from "@vitejs/plugin-vue";
import dts from "vite-plugin-dts";

export default defineConfig({
    plugins: [
        vue(),
        dts({
            rollupTypes: true 
        }),
    ],
    build: {
        outDir: './lib',
        lib: {
            entry: resolve(__dirname, "src/main.ts"),
            name: "MyModule",
            fileName: "my-module",
        },
        rollupOptions: {
            external: ["vue"],
            output: {
                globals: {
                    vue: "Vue",
                },
            },
        },
    },
});

When I run the build script I get an index.d.ts with the content export * from '/main.ts' but I don't know why


Solution

  • Ok, so if at some point someone finds this thread and needs some guidance here is how I solved my problems:

    First: Remove any declarations from the project you want to import your library into. You won't need them. I tried pointing towards my node module inside my tsconfig, which did not work.

    Second: Create a index.ts inside of ./module/src which you will use to export your components. I used my main.ts which could also work but I would not be able to test my modules properly without having an actual app. In your index.ts you will import/export your components. I tried to export it by export { default as Smth } from "anywhere.ts" which did not work. It worked for me like this:

    import Smth from "./anywhere";
    
    export { Smth }
    

    With this my types got generated as I would like it to. I also used this vite.config.ts:

    
    // https://vitejs.dev/config/
    export default defineConfig({
        plugins: [
            vue(),
            dts({
                rollupTypes: true,
            }),
        ],
        build: {
            outDir: './dist',
            lib: {
                // src/indext.ts is where we have exported the component(s)
                entry: resolve(__dirname, "src/index.ts"),
                name: "MyModule",
                // the name of the output files when the build is run
                fileName: "my-mdule",
                formats: ['es'],
            },
            rollupOptions: {
                // make sure to externalize deps that shouldn't be bundled
                // into your library
                external: ["vue"],
                output: {
                    // Provide global variables to use in the UMD build
                    // for externalized deps
                    globals: {
                        vue: "Vue",
                    },
                },
            },
        },
    });
    

    If you now have everything in our build folder you were looking for and typing are still not available in your project you properly have some issues with your modules package.json.

    Your package.json should look something like this:

    
        "main": "./dist/my-module.umd.cjs",
        "module": "./dist/my-module.js",
        "exports": {
            ".": {
                "types": "./dist/index.d.ts",
                "import": "./dist/my-module.js",
                "require": "./dist/my-module.umd.cjs"
            },
            "./dist/style.css": {
              "import": "./dist/style.css",
              "require": "./dist/style.css"
            }
        },
    

    The property "types moved from root to exports and this made me search for hours.

    Hope this will help in the future!