Reputation: 10926
I have a models
directory (my-models
) in my project that contains a few important typescript classes for my app.
I've been using it from within the app with no problems and, now I want to make it an npm package so I can import it in another project.
This is what I tried to do:
my-models
directory (the one that contains all my
models and classes)my-models
directory (the one that contains all my models and classes)my-models
in another "client" project's root directoryThe problem I have is that no matter what I do, I can't find a way to share all my Typescript classes and use them in another project. I run into trouble compiling my library and then when I make it compile, I cannot import classes in my client project. I get this error:
`File '.../services/my-models/index.d.ts' is not a module.ts(2306)
This is the package.json of my-models
:
{
"name": "my-models",
"version": "0.9.0",
"description": "API Client and models",
"main": "dist/main.js",
"types": "index.d.ts",
"scripts": {
"test": "echo \"Error: no test specified\" && exit 1"
},
"dependencies": {
"axios": "^0.19.0",
"@types/axios": "^0.14.0"
},
"devDependencies": {
"typescript": "^3.9.5"
}
}
And this is an import in my client project where I try to import one of my models:
import { Student } from 'my-models'
But wait, I kind of made it work doing this:
import { Student } from 'my-models/dist/main'
Why? I'm saying in my-models
's package.json that dist/main.js is the main file, why can't I just import * from "my-models"?
BTW, this is my-models/dist directory:
So not sure if I'm doing something wrong or how to do it correctly. Appreciate any help
Upvotes: 4
Views: 2032
Reputation: 29214
Thanks to Adrian's answer I was able to create a library the angular way. Looking into it more you only really require the ng-packagr
package for
development. It requires no typescript configuration or setup and one extra
ng-package.json
file with a line for the schema
I have a repo with more info in the README but here are the steps to create a base package:
npm init
npm install -D ng-packagr
"build": "ng-packagr -p ng-package.json"
ng-package.json
:
{
"$schema": "./node_modules/ng-packagr/ng-package.schema.json"
}
src/public_api.ts
:
export function add(a: number, b: number): number {
return a + b
}
npm build
That's it. The 'dist' directory contains your package.
It can be published with npm publish dist
. If you go
into it you can run npm link
and then use it from
other projects on your computer with npm link <package-name>
with whatever package name you have in the package.json.
I was able to link to it in a new vuetify project after using npm link my-package
with this:
import { add } from 'my-packager'
console.log(`3 + 19 = ${add(3, 19)}`)
With a new node package I was able to use it in index.mjs
with this:
import { add } from 'my-packager'
console.log(`7 + 2 = ${add(7,2)}`)
And with index.js
like this:
import('my-packager').then(({ add }) => {
console.log(`7 + 2 = ${add(52,-10)
}`))
This produces es2022 modules, if you want older versions I suppose you could
use an older version of ng-packagr
. If you want to include static assets
you will have to look at the schema for ng-package.json.
Upvotes: 0
Reputation: 21638
I use the Angular CLI to build NPM libraries even if they are not Angular projects. You can just delete the Angular dependencies from the package.json file and you have a world class TypeScript project setup for you with a great test pipeline.
npm install --global @angular/cli
ng new my-lib --create-application=false
cd my-lib
ng generate library my-lib
After you generate the library you can go into the projects/my-lib/src directory open the package.json file and get rid of the Angular dependencies. Now you have a blank TypeScript project.
ng build my-lib
will build it
ng test my-lib
will run the unit test
cd into the dist/my-lib folder and you can npm publish
straight to npm.
Why hand roll a TypeScript build when you can leverage off the work of the Angular team?
Upvotes: 4