Rollup does not bundle declaration file - node.js

I am trying to build a library made with TypeScript. I am using the paths property in tsconfig.json.
My tsconfig.json looks like this:
{
"compilerOptions": {
"module": "es2015",
"moduleResolution": "node",
"target": "es2015",
"noImplicitAny": true,
"removeComments": true,
"preserveConstEnums": true,
"experimentalDecorators": true,
"sourceMap": true,
"lib": [
"esnext",
"dom"
],
"strict": true,
"sourceRoot": "./src",
"rootDir": "./src",
"outDir": "build",
"declaration": true,
"declarationDir": "build",
"baseUrl": "./src",
"noUnusedLocals": true,
"paths": {
"modules/*": [
"modules/*"
],
"common/*": [
"common/*"
]
}
},
"exclude": [
"node_modules",
"build"
]
}
And my rollup config looks like this:
import typescript from 'rollup-plugin-typescript2'
export default {
entry: "./src/index.ts",
output: {
file: './build/index.js',
format: 'cjs'
},
plugins: [
typescript({ typescript: require("typescript"), declaration: true, clean: true })
]
}
However, when I build using rollup -c, it creates this in my build folder:
Where the index.js is bundled just fine, but the declaration file here simply imports from the /common folder and that folder basically contains all the other folders from the src directory but only with a single declaration file per folder, furthermore, these files try to import using the paths aliases instead of being built with relative imports, so they do not work.
How do I tell rollup to build a single declaration file instead of this?

rollup-plugin-typescript keeps the folder structure for declaration files. To bundle the declaration too, you should use rollup-plugin-ts as well:
https://github.com/wessberg/rollup-plugin-ts

Related

How to use paths with ts-node?

I have this project structure:
How to configure tsconfig.json for using paths like #app/, #server/.
I try this:
{
"compilerOptions": {
"module": "CommonJS",
"target": "es5",
"lib": [
"esnext",
"dom"
],
"allowJs": true,
"skipLibCheck": true,
"esModuleInterop": true,
"allowSyntheticDefaultImports": true,
"strict": true,
"forceConsistentCasingInFileNames": true,
"noFallthroughCasesInSwitch": true,
"moduleResolution": "node",
"resolveJsonModule": true,
"isolatedModules": true,
"noEmit": false,
"baseUrl": "..",
"paths": {
"#app/*": [
"app/*"
],
"#server/*": [
"server/*"
]
}
},
"include": [
"."
]
}
Same config works with webpack and ts-loader, but when i run npx ts-node server/index.ts i got error:
npx ts-node server/index.ts
Error: Cannot find module '#server/a'
server/index.ts :
import a from '#server/a'
console.log('This is index.ts')
a()
Your config works for webpack because you run webpack from the project root. It does not work for server.ts because the path is relative to its directory. Try:
"paths": {
"#app/*": [
"../app/*"
],
"#server/*": [
"../server/*"
]
}
If you need to do it for both, you need two different tsconfig.json - one in the root and one in app or server.
Take a look at my project: https://github.com/mmomtchev/rlayers
It uses this feature a lot.

Importing a custom library into a storybook

I am writing a TypeScript library. I have gotten to the point where I would like to test said library. Because it's a very visual thing, I chose to go with storybook so I can show off the different functionalities of my library.
My package has an index.ts with the following in it:
export { Container } from "./Container";
My folder structure looks like this:
library/
dist/
src/
index.ts
Container.ts
package.json
storybook/
stories/
package.json
This is the package.json of my library:
{
"name": "#wesp/customcontainer",
"main": "dist/index.js",
"files": [
"dist"
],
}
This is the dependencies for the package.json of the storybook folder:
"dependencies": {
"#wesptest/customcontainer": "file: ../",
},
Now when I try to use the custom library in for example storybook/stories/test.stories.ts:
import {Container} from "#wesp/customcontainer";
but then the story will throw this error:
_wesp_customcontainer__WEBPACK_IMPORTED_MODULE_1__.Container is undefined
What do I have to change so I can successfully import this class?
thanks.
-- edit --
My tsconfig.json:
{
"compilerOptions": {
"target": "es2019",
"lib": ["dom", "dom.iterable", "esnext"],
"allowJs": true,
"skipLibCheck": true,
"allowSyntheticDefaultImports": true,
"strict": true,
"forceConsistentCasingInFileNames": true,
"module": "commonjs",
"moduleResolution": "node",
"resolveJsonModule": true,
"jsx": "react",
"esModuleInterop": true,
"outDir": "./dist",
"declaration": true,
},
"include": ["./src"]
}
main of your lib is dist/index.js.
Storybook file will try to import from dist dir, so first check if js file exists in that dir.

Cannot overwrite out dir using declaration

I'm using Typescript and in tsconfig.json I'm getting this error:
Cannot write file 'c:/michael/Documents/razor/lib/client.d.ts' because it would overwrite input file.
this is my tsconfig.json content:
{
"compilerOptions": {
"target": "es6",
"module": "commonjs",
"moduleResolution": "Node",
"sourceMap": true,
"outDir": "./lib",
"removeComments": true,
"strict": true,
"esModuleInterop": true,
"skipLibCheck": true,
"experimentalDecorators": true,
"emitDecoratorMetadata": true,
"resolveJsonModule": true,
"declaration": true
},
"exclude": [
"node_modules",
"test"
]
}
as you can see I have enabled declaration: true to export also the d.ts files.
This is my project folders structure:
/lib
/node_modules
/src
/test
.gitignore
.npmignore
razor-1.0.0.tgz
package.json
packages-lock.json
readme.md
tsconfig.json
If I try to run tsc -p I cannot compile, so each time I must delete the folder lib manually which contains the compiled project.
How can I fix this?
TypeScript is picking up files from lib directory when compiling. Hence, that error. Try adding lib to the exclude array.

Preserve directory structure of a package for importing

I'm trying to create a package with directory structure as follow:
src/
folder1/
index.ts
...
folder2/
index.ts
...
folder3/
index.ts
...
.
.
.
And I would like to import it as import { Class1 } from '#package/folder1', import { Class2 } from '#package/folder2', etc.
At this moment, I'm able to import my classes like import { Class1 } from '#package/lib/folder1'. Is it possible to achieve my expected behavior?
tsconfig.json:
{
"compilerOptions": {
"module": "commonjs",
"declaration": true,
"removeComments": true,
"emitDecoratorMetadata": true,
"experimentalDecorators": true,
"target": "es2017",
"sourceMap": true,
"outDir": "./lib",
"rootDir": "./src",
"rootDirs": ["./src/folder1"],
"lib": [
"es2017",
"esnext.asynciterable"
],
"typeRoots": [
"./node_modules/#types"
],
"allowSyntheticDefaultImports": true,
"forceConsistentCasingInFileNames": true,
"moduleResolution": "node",
"pretty": true,
"noEmit": false,
"esModuleInterop": true
},
"include": ["src"],
"exclude": ["node_modules", "lib"]
}
It seems this feature is not out-of-the-box in the version of Typescript I'm using (3.7.4). The package module-alias could be a workaround but it looks like Typescript 3.8 will allow adding aliases to the exports.
Typescript 3.8 announcement link
Related SO question

Node Error: Cannot find module - typescript api for custom module where I export mongoose schemas and interfaces

I have a typescript module #tlabs/models where I'm simply exporting in index.ts:
export * from '../models......'
where in each file I have something like:
export const Project = typedModel('projects', ProjectSchema);
and my only dependency is ts-mongoose imported in each file simply as:
import { createSchema, Type, typedModel, ExtractProps } from 'ts-mongoose';
ts-mongoose being a dependency that itself required mongoose + mongoose types.
In my typescript node project I have ts-mongoose, mongoose and #tlabs/models as dependencies and #types/mongoose as dev dependency.
Running tsc is fine, the files get compiled and there's no error being thrown out but then trying to run the actual files throws out:
Error: Cannot find module '#tlabs/models'
I have reinstalled all modules several times and checked package.json as well as the actual files on the disk + through vscode and they're right there.
What am I missing out?
My tsconfig is:
{
"include": ["src/**/*"],
"exclude": ["node_modules", "./node_modules", "./node_modules/*"],
"compilerOptions": {
"module": "commonjs",
"esModuleInterop": true,
"target": "es6",
"allowJs": true,
"moduleResolution": "node",
"sourceMap": true,
"outDir": "dist",
"noImplicitAny": false,
"alwaysStrict": true,
"strictNullChecks": true,
"types": [],
"lib": [],
"experimentalDecorators": true
}
}
My final TS config for my exported models:
{
"compilerOptions": {
"target": "es5",
"module": "commonjs",
"declaration": true,
"declarationMap": true,
"sourceMap": true,
"outDir": "lib",
"strict": true,
"esModuleInterop": true
},
"include": ["src"]
}
and relevant package.json configuration:
{
"main": "lib/index.js",
"types": "lib",
"scripts": {
"tsc": "tsc",
"build": "tsc -p ."
},
"files": [
"lib"
],
}

Resources