Convert old CJS module into ESM and import into TS files - node.js

I am wanting to convert an old module, https://github.com/capaj/object-resolve-path, into ESM so I can use it via an import statement, in order to move all my NodeJS Lambda functions to ESM.
I have forked the repo, and changed the 2 main .js files to .mjs, updated the exports, as well as update the main property in package.json to point to the object-resolve-path.mjs file.
In my NodeJS Lambda function, I have then installed the fork via NPM from my private repo, which pulls the new code in.
However, when I try to import the package in my code now, using import * as resolvePath from 'object-resolve-path'; I get an error:
Could not find a declaration file for module 'object-resolve-path'.
What am I missing? The module isn't written in TS, so why is it asking for a declaration file?

Related

'ReferenceError: require is not defined' while importing fs module

I am new to NodeJS. I was importing the 'fs' module in NodeJS and this happened.
Is this because of the new import syntax in the current versions?
What went wrong?
Thanks in advance!
This is because something is telling nodejs that this is the newer ESM module. This could be your package.json file or something else. In an ESM module file, you use import, not require() to load modules.
You can see in the stack trace where it shows Object.loadESM and that's how you know it is trying to load this module as an ESM module.
With an ESM module, perhaps you want this:
import fs from "fs";
or
import * as fs from'fs';
Or, if you intend to use a CommonJS module instead (where you can use require()), then we need to see your package.json file to figure out why the loader is attempting to load your file as an ESM module.

Is it not possible to import modules from another module if they are in the same dir? (Haskell)

To demonstrate my question, I've created a test project like this ->
The directory "Data" has only 2 modules, namely "Test3.hs" and "Test4.hs". They are empty modules for test purposes. (implementation: "module Data.Test3 where" )
"Test1.hs" imports all the modules like this ->
which results in an error ->
I am using WinGHCi to import the modules, which automatically changes the directory to "cd: ~\.hs".
I also tried to import the modules by using GHCi and by manually changing the dir. But ended up with the same result as above.
So I come to conclusion that there is no way of importing your own modules from the same directory and you have to always create sub dirs only for this purpose.
Is that right?
You need to decide where your root directory is, run GHCi from that directory, and then consistently name all your modules relative to that same directory.
You need to name your modules consistently both in the module declaration (module Foo where...) and in the import statements (import Foo).
So you need either:
module Test.Test1 where
import Test.Data.Test3
import Test.Data.Test4
import Test.Test2
or run GHCi from inside Test and remove all the Test prefixes. But you can't have the prefix on some but not others. You have to be consistent everywhere. Each module name is basically a file path from the current directory to where the source file is.

Isomorphic import of CommonJS modules

I've written a small library that's meant to run both in the browser and on the server. The library in turn uses npm libraries published as CommonJS modules (e.g. lodash.isequal).
I'd like to compile the library two different ways:
Using tsc, generating commonjs modules for use on the server
Through webpack, using the awesome-typescript-loader, generating es6 modules for webpack to bundle
Per the docs, the correct way of importing CommonJS libraries which override module.exports is as follows:
import isEqual = require('lodash.isequal');
However for the second compilation case, typescript complains that
error TS1202: Import assignment cannot be used when targeting ECMAScript modules. Consider using 'import * as ns from "mod"', 'import {a} from "mod"', 'import d from "mod"', or another module format instead.
I've managed to get code generation to work properly by importing it as:
import * as isEqual from 'lodash.isequal';
but that requires disabling typechecks, since otherwise typescript complains with errors like the following:
error TS2497: Module '"/home/user/ts-mod-test/node_modules/#types/lodash.isequal/index"' resolves to a non-module entity and cannot be imported using this construct.
Since TypeScript 2.7, this issue can be resolved by using synthetic default imports. Using the esModuleInterop flag, isEqual (and similar modules) can be imported like in babel and webpack:
import isEqual from 'lodash.isequal';
For webpack with the module option set to es6, the import will be left as-is, and webpack itself will handle the synthetic default. For node, with module set to CommonJS, the corresponding emit will be const lodash_isequal_1 = __importDefault(require("lodash.isequal"));, where the __importDefault handles the non-es module case like Babel

Meteor Shell, can't import files from any folder: Error: Cannot find module ‘/imports/api/donuts/collection.js’

I am having some trouble importing modules into the meteor shell.
Simple example:
1.create new project (meteor create myproject)
2.create file /imports/api/donuts/collection.js and paste content:
// file: /imports/api/donuts/collection.js
import { Mongo } from 'meteor/mongo';
const Donuts = new Mongo.Collection('donuts');
export default Donuts;
3.Run meteor shell and import the file by:
import Donuts from '/imports/api/donuts/collection.js'
than this error hits up:
Error: Cannot find module '/imports/api/donuts/collection.js'
at Function.require.resolve (packages/modules-runtime.js:129:19)
at Module.resolve (packages/modules-runtime.js:81:25)
at Module.Mp.import (/home/ec2-user/.meteor/packages/modules/.0.7.7.mccaq7++os+web.browser+web.cordova/npm/node_modules/reify/lib/runtime.js:61:29)
at repl:1:-37
at packages/shell-server/shell-server.js:458:25
at /home/ec2-user/.meteor/packages/promise/.0.8.8.i94065++os+web.browser+web.cordova/npm/node_modules/meteor-promise/fiber_pool.js:32:39
What's wrong? File permissions are ok, I start the meteor shell from project root.
Thanks!
Meteor originally loaded all of the source files using its default load order.
In more recent versions (circa v1.3), it treats special directories differently. One of those directories is imports.
Any directory named imports/ is not loaded anywhere and files must be imported using import.
(from the Meteor docs)
When using the shell, you can only import resources that were included in the build. If the module (file) you are trying to import is not included in your import tree (chain of imports starting somewhere outside of the /imports directory), it will not be available for import.

Typescript import ts file from node module

Maybe it's a duplicate but I've searched for an hour and haven't found the answer.
I have a node module named a-module which contains some .ts files (for example a.ts)
I have another node module b-module which has a-module among its dependencies.
I want to import some .ts file from a-module to b-module.
In some file within b-module I write:
import a = require('a-module/a');
console.log(a);
When then I'm trying to compile b-module with tsc, is says
Cannot find external module 'a-module/a'.
What am I doing wrong?
P.S. I have ArcticTypescript plugin for SublimeText, and seems that it is enough intelligent to find a-module/a. Why then tsc doesn't manage to locate my file?
P.P.S My file structure looks like that
b-module/
node_modules/
a-module/
a.ts
b.ts
I'm trying to import a.ts to b.ts.
import a = require('a-module/a');
You need to either use relative paths i.e. ../a-module/a or declare it for TypeScript explicitly i.e. declare module "a-module/a".

Resources