node_modules import from a directory inside what is specified in "main" (package.json)? - node.js

Is it possible to import from something other that what "main" points to?
In my library that is installed into node_modules, I have the main set to
lib/index.js
so (using es2015 imports - source was ts compiled js), I can do
import { FunctionA, FunctionB } from 'MyTestLibrary';
This works because these functions are exported inside of index.js under libs.
I also have an index inside a directory which exports functionC and functionD, the structure is here
/lib/otherdir/index.js
so if I do an import like so
import { FunctionC, FunctionD } from 'MyTestLibrary/otherdir';
my IDE does not complain but running the application I get a
Cannot find module MyTestLibrary/otherdir
Everything is exported as it should be.

You can access the directory directly like this:
import { FunctionC, FunctionD } from 'MyTestLibrary/lib/otherdir'

Related

How can I import other file in service worker file using workbox-webpack-plugin injectMode?

I am using vue-cli and workbox-webpack-plugin injectMode
new InjectManifest({
swSrc: './src/sw.ts',
swDest: 'sw.js',
}),
in sw.ts, I try to import other file
import { precacheAndRoute } from 'workbox-precaching'
import { registerRoute } from 'workbox-routing'
import { WorkboxPlugin, setCacheNameDetails, RouteHandler } from 'workbox-core'
import { CacheableResponsePlugin } from 'workbox-cacheable-response'
import { ExpirationPlugin } from 'workbox-expiration'
import Strategies, { CacheFirst, StaleWhileRevalidate } from 'workbox-strategies'
// import other file
import { CustomMessage, MessageType, MESSAGE_META, SWRouting } from './utils/registerSW'
but when building APP, it will fail,
error: js/chunk-2d213953.a6b52dae.js from Terser
Unexpected token: punc (:) [js/chunk-2d213953.a6b52dae.js:3,12]
when I remove this import statment, building works well.
So, Could I import other files ? How ?
Generally speaking, what you're trying to do should work. The InjectManifest plugin will kick off a webpack child compilation for the your swSrc file, and will inherit whatever plugins and config you have set up for your main, parent compilation. It should be able to bundle ES modules into a final service worker.
It sounds like there's something specific in one of those ./utils/registerSW imports that is causing Terser to be unable to parse the bundled code, though. I would recommend starting by just importing a very small, no-op function from ./utils/registerSW, and confirm that that works. Then try importing each of those functions from ./utils/registerSW one at a time until you find the one that's causing issues, and check the original source code to see what might be triggering it.
It's possible that the child compilation kicked off by InjectManifest is misconfigured, and perhaps that's due to a bug that needs to be fixed, but I would start with those debugging steps first.

Import current module by name in typescript

Is it possible for a module to import "itself" by its own name in typescript?
For instance, lets say there is a module my-module with a bunch of test.
Is there a chance to import it inside the tests using import ... from "my-module" instead of using local path (e.g. import ... from "./my-module")?
As I know it can be done using the require, but it seems that import does not support this.
You can use the TypeScript tsconfig paths option e.g.
{
"paths": {
"module": ["src/path/to/module"]
}
}
More
https://www.typescriptlang.org/docs/handbook/module-resolution.html

NodeJS How to import JS file into TypeScript

I'm new with TypeScript. I'm currently learning NodeJS Loopback 4 framework which use Typescript language. And my question is how to import some function, class which has been exported in JS file into my TS file. After search several way but it still doesn't work with me.
Here's example:
// /src/index.ts
import {plus} from './lib/test';
console.log(plus(1,2));
// /src/lib/test.js
export function plus(x, y) {
return x + y;
}
I also try using definition typescript like this
// /src/lib/test.d.ts
export declare function plus(x: number, y: number): number;
But still got error when import this function in index.ts file
Error: Cannot find module './lib/test'
at Function.Module._resolveFilename (module.js:543:15)
It looks like the tsconfig.json doesn't have 'allowJs' enabled because it exports declarations.
Is there a reason you are not wanting this to be a typescript file? If you change test.js to test.ts, by making it a .ts should allow it to be recognised in your index file.
UPDATE
Full chat history to get to this point can be found here.
Repository used to test found here
OK so easy solution as #maaz-syed-adeeb mentions will work:
import { path } from './lib/test.js'
The reason the extension is important is because the definition file takes priority over a javascript file in a typescript environment. That is why the module import was blowing up.
To avoid specifying the .js extension you can also setup your directory structure like this:
src
|- index.ts
|- lib
|- test.js
|- test.d.ts
|- index.[js|ts]
in ./lib/index file export all from test:
//./src/lib/index.[js|ts]
export * from './test'
and then import all from lib:
// ./src/index.ts
import { path } from './lib'
// or
import { path } from './lib/test.js'
If you are using a blend of javascript and typescript (say you are moving over to typescript with an existing code base), you will need to update your tsconfig.json to include so you don't get the warnings in your IDE:
{
"compilerOptions": {
"allowJs": true,
"declaration": false
}
}
This is so your javascript files will be transpiled to your destination directory along with the typescript files.

Resolve .jsx extensions on imports in node

I have a CRA project in which I've added SSR.
It's supper dummy, it has this structure:
|- App.js
|- Header
|- Header.jsx
|- Header.scss
The App just contains the Header, which is imported without specifying the extension.
import React, { Component } from 'react';
import './App.css';
import Header from './Header/Header';
class App extends Component {
render() {
return (
<Header />
);
}
}
export default App;
With npm start all runs successfully. If I compile the code and run it with node instead, it breaks with this error Element type is invalid: expected a string (for built-in components) or a class/function (for composite components) but got: object.
There seem to be a problem when resolving imports without an extension. It finds the .scss file instead of the .jsx. Specifying the extension on import or removing conlicting files (i.e. Header.scss) solves the issue.
However, I would like to keep using imports without extension, as I normally do in CRA.
I don't know how to specify this on my settings.
I've just pushed this simple example so you can run it yourself: https://github.com/dnaranjo89/resolve_extensions_ssr

Creating node module with subfolders

I am developing npm module. I have following index.ts
export * from './src/A/index';
At this moment, in app import statement looks as follow:
import {something} from 'myModule';
I would like to add some extra logic to my module, and organize it like:
export * from './src/A/index';
export * from './src/B/index';
export * from './src/C/index';
What should I write in index.ts to make my module to be used in this way:
import {something} from 'myModule/A'
import {something2} from 'myModule/B'
etc.?
What should I write in index.ts to make my module to be used in this way
Given that you want to use import {something} from 'myModule/A' implies that myModule/A folder should have an index.ts that exports something.
This conflicts with the fact that A/index is actually located in myModule/src/A/index.
Move the file and it should work.

Resources