.npmignore not ignoring index.ts file when publishing - node.js

I'm creating an Angular2 component library I'm publishing to npm. I'm using index.ts as my barrel file throughout the source code. I've included *.ts in my .npmignore file, however, index.ts is getting included in the code published to npm. When I install the component in my consuming Angular2 project, index.ts is included in the code installed in node_modules folder. Having index.ts throughout the npm installed library is preventing the primary application from building because index.ts is not in the root folder. Surprisingly, all my other .ts files are being excluded in the npm install.
Here's my .npmignore file:
node_modules
npm-debug.log
Thumbs.db
.DS_Store
.idea
.vscode
*.ts
**/*.ts
**/index.ts
!*.d.ts
.gitignore
.npmignore
license-banner.txt
tsconfig.json
tsconfig.publish.json
Everthing is getting ignored except index.ts.
I have to manually go in and delete every index.ts file then everything works as expected.
What am I missing that's causing index.ts to be included?
I'm using npm version 3.9.6.
Thanks for your help.

After much research and trial and error, I discovered I needed to add an output directory for compiling my TS code into JS and typescript type information (.d.ts) files. Once the generated code was in a separate folder (in this case /lib), my implementation changed to import from my lib folder. All of my .ts files remained in the src folder.
My projects that have installed the library are now compiling as expected. Bottom line is to make sure your generated code (JS and .d.ts files) are in a separate folder from your source code. Seems obvious now.

Related

Missing /src and /dist in node_module (with workspaces)

I forked a package and made some changes and need to install it locally. Here's my branch.
I ran:
yarn add 'saber2#https://github.com/ilmoi/saber-common#head=ilmoi_support_v0'
which successfully installs the package, but it's missing both /src and /dist and so it unusable.
Having searched for similar issues I unsuccessfully tried:
building and commiting /dist dir (made sure not in .gitignore)
adding a "files" line to package.json (both top level and inside the workspace)
adding a "prepare" line
adding a blank .npmignore
None of those works. Here's how the package looks in node modules:
I suspect the problem is to do with workspaces. For some reason none of them compile / show. Please advise on what I'm missing.

Module installed from npm can't find it's local files

I published a small package to npm which consists of several files.
The index.js of the package just imports and re exports the public classes and APIs/
When I install the package from NPM I get the following error when I try to use the custom package:
Error: Cannot find module './openapi'
Require stack:
- .../node_modules/.../dist/index.js
I checked dist folder in the module dir in node_modules and the files are there.
I assume there is an issue with the relative path inside the node_modules
One option to fix this is to bundle everything into a single file, but I would prefer to keep multiple files.
What options are there to fix this ?
.gitignore files are ignored. There were after all some ignored local files that needed a to be pushed.

How to NPM publish so that consumers can imports from different top-level directories

I am publishing a library to NPM. The library was written in Typescript, and the result of the Typescript compilation is put in a lib/ folder. The main file is an index.ts that exports my public API:
export * from './functions';
export * from './models';
In package.json, I specify:
{"main": "lib/index.js", "types": "lib/index.d.ts", "files": ["lib/**/*"]}
Once my package is published and installed elsewhere, its folder structure is:
lib/
index.js
index.d.ts
functions/
index.ts
my-function.ts
models/
index.ts
my-model.ts
the consumer imports everything from the package root:
import {someFunction, SomeModel} from 'a-library';
This works, but I like the idea of segregating paths. One path for functions, and another for models. Currently if I remove the top-level index, the imports become segregated but they now include the lib/ folder in the path which I don't want:
import {someFunction} from 'a-library/lib/functions';
import {SomeModel} from 'a-library/lib/models';
What I would actually like to accomplish is the same but without lib/. I have a working solution but it seems too convoluted. Here is what works:
In package.json, remove the main types and files key.
Delete or empty the index.ts
To publish replace the simple npm publish with the following steps:
copy package.json and paste it into /lib folder
cd into the /lib folder and run npm pack and take note of the created tarball's name
run npm publish {{TARBALL_NAME}}
cd back up to the project root
As a result, the published package has the following folder structure once installed:
functions/
index.ts
my-function.ts
models/
index.ts
my-model.ts
Because things are no longer nested within a lib/ directory the consumer can import as I wished:
import {someFunction} from 'a-library/functions';
import {SomeModel} from 'a-library/models';
The problem is that packing and publishing to accomplish this seems too cumbersome. I'll never get my teammates to by into a 3 or 4 step process when they've just been running npm publish all this time.
Is there a simpler way to accomplish what I'm after?

npm module missing files after publish

For reference, the repo is https://github.com/microsoftly/luis-response-builder.
The node module files are generated with tsc and output to the dist folder. I have a prepublishOnly step that removes the dist folder, runs tsc, then runs the test against the transpiled js. The tests pass when I publish just fine.
The problem is, when I install the project anywhere else, the dist folder contains only the file with the path dist/src/index.js.
I cannot for the life of me figure out why the file is missing when installed but not when published.
Quoting from npm-publish Documentation:
All files in the package directory are included if no local .gitignore or .npmignore file exists. If both files exist and a file is ignored by .gitignore but not by .npmignore then it will be included.
Your repository's .gitignore file contains the following:
node_modules
dist
*.env
yarn-error.log
Since dist is being ignored, it's not committed with npm publish, as per the documentation.
Check out the package.json documentation about files.
Since you haven't included the files key, it will only include the file specified in main (along with some other default files).
The files value is an array so you can include multiple files and/or folders.
eg:
files: [
"dist",
"config/somefile.js"
]

How do I deal with d.ts files when publishing my typescript code to npm

I have been following this article:
How to create strongly-typed npm packages
and have been trying to setup my typescript project to publish it to npm.
It all seems to make sense but what is not covered is how to deal with d.ts files.
My project looks somewhat like this:
src
node
server.ts
browser
client.ts
common
contracts.d.ts
so when I compile this with "declaration": true and "outDir: "dist" I get:
dist
node
server.js
server.d.ts
browser
client.js
client.d.ts
both my server.ts file and client.ts files have
import {SomeType} from "../common/contracts";
in so when someone else uses this package the typescript compilation will fail as server.d.ts and client.d.ts both still have this import.
Node will run fine though as client.js and server.js do NOT have this import. tsc must remove imports of d.ts files.
What I want to happen is for the contracts.d.ts file to be copied to the dist folder as part of the build. How do I do that as part of the tsc build?
Current Workaround
What I am currently doing to get round this is rename my contracts.d.ts to just contracts.ts which means that all required files are present in the dist folder but it does mean that both the client and the server are having to load an empty contracts.js file that only contains
"use strict";
//# sourceMappingURL=contracts.js.map
I think that I have come up with quite a good solution to this.
I have moved my declaration files into a contracts folder so my project looks like this:
src
node
server.ts
browser
client.ts
dist
node
server.js
server.d.ts
browser
client.js
client.d.ts
contracts
common.d.ts
I then just include the contracts folder in the npm package and import files using ../../contracts/common. This path works both from the src folder when compiling and from the dist folder when building against this package.
If though the contracts are just types, I would still declare them in a .ts file. Or are the contracts generated from somewhere else?

Resources