I have developed an npm package that builds three js files.
in my project I want to import js files like this:
import MyButton from '#bslm/ui/MyButton'
so i used the exports field in my package.json like this:
"type": "module",
"exports": {
"./MyButton": "./dist/my-button.common.js",
"./MyInput": "./dist/my-input.common.js",
"./MyImage": "./dist/my-image.common.js",
}
but when i try:
import MyButton from 'mypackage/MyButton'
I get this error: These dependencies were not found
node version: 14.18.1
npm version: 8.5.4
Remove the leading '.'. If you use './' as the keys you need to use objects like {"default":"./dist/my-button-common.js" } instead of a simple name.
Related
I have installed ow by
npm i --save ow
and when I use it in my TypeScript project, I get
/home/ss/projects/m/node_modules/ts-node/src/index.ts:843
return new TSError(diagnosticText, diagnosticCodes, diagnostics);
^
TSError: ⨯ Unable to compile TypeScript:
src/modules/setPropertyOffer.ts(1,16): error TS2307: Cannot find module 'ow' or its corresponding type declarations.
Doing
npm i --save #types/ow
doesn't exist.
Question
How are the types installed for ow?
As of version "1.1.0"
I had to do this import ow from "ow/dist";
I think this is because they have not specified the main field on their package.json
If you can't find the some library's type, you have to make a type file for that.
Add the custom typeroot option (./#types) in tsconfig.json
// tsconfig.json
{
// ...
"typeRoots": ["./node_modules/#types", "./#types"]
// ...
}
Create a folder for some library and create a index.d.ts file.
// ./#types/someLibrary/index.d.ts
declare module 'someLibrary';
For ow:
// ./#types/ow/index.d.ts
declare module 'ow';
I have a react ts project where I installed a pure js module: crypto-prices. Considering this module doesn't have any #types source, I created a decs.d.ts file with:
declare module "crypto-prices"
This removes the IDE issue. Yet, when I try to use the cryptoPrice modules through
import cryptoPrice from 'crypto-prices'
I get the following error:
Can't resolve 'crypto-prices' in ...
Import it like this,
import * as cryptoPrice from 'crypto-prices'
You need to include decs.d.ts in tsconfig.json. If decs.d.ts is in the same folder as tsconfig.json it should look something like below:
tsconfig.json
{
"include": [
"./src/**/*",
"./decs.d.ts"
],
"compilerOptions": {
...
}
}
I have this how do you make your custom module global accross you project and import it by providing the name of the module rather than the path like the modules in npm ecosystem
import CustomModule from "custom-modules";
After looking for a while i found the answer. You have to add your exports in package.json in order to use them with the name or path provided in package.json. e.g.
{
"name": "my-mod",
"exports": {
".": "./lib/index.js",
"./lib": "./lib/index.js",
"./lib/index": "./lib/index.js",
"./lib/index.js": "./lib/index.js",
"./feature": "./feature/index.js",
"./feature/index.js": "./feature/index.js",
"./package.json": "./package.json"
}
}
You can go Here for more details
I am trying to build a CLI for a node js only todo app using commander and conf modules in node js, with chalk to colour the output . I am not sure how to resolve the errors being returned:
ReferenceError: require is not defined in ES module scope, you can use import instead
This file is being treated as an ES module because it has a '.js' file extension
contains "type": "module". To treat it as a CommonJS script, rename it to use the '.cjs' file extension.
I'm getting the above error for both conf and commander
Any suggestions on how I could go about debugging this, or changing approach to using readline and events/EventEmitter would be better, will be appreciated, Thanks
Below is a REDACTED version of code:
list.js
const conf = new (require('conf'))();
const chalk = require('chalk');
function list() {
const todoList = conf.get('todo-list');
if (todoList && todoList.length) {
console.log(
chalk.blue.bold(
'Tasks in green are done. Tasks in yellow are still not done.'
)
}
}
module.exports = list;
index.js file
const { program } = require('commander');
const list = require('./list');
program.command('list').description('List all the TODO tasks').action(list);
program.command('add <task>').description('Add a new TODO task').action(add);
program.parse();
package.json file
{
"main": "index.js",
"type": "module",
"keywords": [],
"dependencies": {
"chalk": "^5.0.0",
"chalk-cli": "^5.0.0",
"commander": "^8.3.0",
"conf": "^10.1.1"
},
"bin": {
"todos": "index.js"
}
}
In your package.json you have:
"type": "module",
This means files with the .js suffix are assumed to be ECMAScript rather than CommonJS. If you want to use CommonJS you can change the file suffix or change the "type" property.
Or you can use the new syntax. In ECMAScript you use import, in CommonJS you use require.
To read more about "type" see: https://nodejs.org/dist/latest-v16.x/docs/api/packages.html#determining-module-system
After some more research I found out I was 'muddying the waters' between CJS or ESM modules.
CJS modules use require and that is the old way of doing things prior to ES6 modules
ESM modules use import
My package.json says type: module telling NodeJS that I am using ESM. But the code is saying CJS.
These are the steps I take to fix this:
rename index.js to index.mjs
update package.json accordingly
replace all require calls with import statements
replace module.exports = list with default export = list (or used a named export)
When trying to extend the Request interface from the package express to add some custom properties, I'm getting the following typescript error:
TS2339: Property '' does not exist on type 'Request<ParamsDictionary>'.
Do you know how to solve that?
Since a recent update of its typings and dependencies, I found that the following should fix the errors in your application.
In your tsconfig.json
{
"compilerOptions": {
//...
"typeRoots": [
"./custom_typings",
"./node_modules/#types"
],
}
// ...
}
And in your custom typings
// custom_typings/express/index.d.ts
declare namespace Express {
interface Request {
customProperties: string[];
}
}
Just add the following, what this does is it simply adds a custom property to the express Request interface
declare global {
namespace Express {
interface Request {
propertyName: string; //or can be anythin
}
}
}
I recently had the same issue, I followed the solution in the previous comments and this repo and I still had the same issue. After doing more digging it seems like it's a bug with ts-node.
To solve this you need to run your server with a --files flag
So if you normally run your server
ts-node ./src/server.ts or nodemon ./src/server.ts
Change it to
ts-node --files ./src/server.ts or nodemon --files ./src/server.ts
After that, I was able to get rid of both the VScode errors and errors while starting the server.
In my case it was missing types for express. What I'm currently working on is migrating our codebase from Yarn to PNPM. The difference with PNPM is it doesn't hoist dependencies the way Yarn does so I had to add the dependencies on the package.json for each workspace that would use that dependency.
This is the error I encountered:
TSError: ⨯ Unable to compile TypeScript:
../server/src/api/filters/googleFilter.ts:6:23 - error TS2339: Property 'headers' does not exist on type 'Request<core.ParamsDictionary>'.
6 const idToken = req.headers.authorization;
It took me quite a few searches to look for a fix when I decided to open up the node_modules folder of that workspace. Inside node_modules/#types/express/index.d.ts
/// <reference types="express-serve-static-core" />
/// <reference types="serve-static" />
import * as bodyParser from "body-parser";
import serveStatic = require("serve-static");
import * as core from "express-serve-static-core";
import * as qs from "qs";
I saw my IDE showing errors telling me that it cannot find the types for express-serve-static-core and serve-static so what I did was to add it on the package.json of that workspace and that fixed the errors on the terminal.
Hope this helps someone else who will encounter the same issue with PNPM.
This worked for me!
Using ts-node
Add the following file to add a property to the express Request interface as suggested by #Rishav Sinha
Add this file src/types/types.custom.d.ts
declare global {
declare namespace Express {
interface Request {
user?: any,
page?: number,
}
}
}
// If this file has no import/export statements (i.e. is a script)
// convert it into a module by adding an empty export statement.
export { }
Add in tsconfig.json
{
"compilerOptions": {
//...
"typeRoots": [
"./types",
"./node_modules/#types"
],
}
// ...
}
Run this command with --files options as suggested by #Shahar Sharron
If you installed globally ts-node
$ ts-node --files ./src/index.ts
or to run from your project dependencies ts-node
$ npx ts-node --files ./src/index.ts
Using nodemon
If you want to use nodemom
Add this file in folder project nodemon.json
{
"watch": ["src/**/*.ts"],
"ext": "ts,json",
"ignore": [
"src/**/*.spec.ts",
"src/**/*.test.ts"
],
"exec": "npx ts-node --files ./src/index.ts"
}
Run nodemon
$ nodemon