Currently my package.json exports all folders with an index file. With this I can import #foo/my-package or #foo/my-package/foo/deep
"exports": {
".": "./_build/code/index.js",
"./*": "./_build/code/*/index.js"
},
I am trying to figure out how to add an exception based on a second extension. Basically I would like to export something like #foo/my-package/foo/deep/index.message
I've tried this exports configuration, duplicating entries before and after the generic export in case I got wrong the precedence.
"exports": {
".": "./_build/code/index.js",
"./*/index.message": "./_build/code/*/index.message.js",
"./*/index.message.js": "./_build/code/*/index.message.js",
"./*": "./_build/code/*/index.js",
"./*/index.message.js": "./_build/code/*/index.message.js",
"./*/index.message": "./_build/code/*/index.message.js"
},
How can I write a rule to export files based on a second extension like '.message.'?
Related
I am not sure if I am using rootDirs correctly. From what I understand it is for making virtual directories at build time, for things such as one angular component library depending on another angular component library.
My base tsconfig looks like this (simplified):
{
"compilerOptions": {
"baseUrl": "./",
"rootDirs": [
"projects/component-library/example-1",
"projects/component-library/example-2"
],
"paths": {
"#org/component-library/*": [
"projects/component-library/*"
],
"#angular/*": [
"./node_modules/#angular/*"
]
},
}
}
I then have two components:
The first one is exported like this:
export * from './src/example-1';
Then component two uses it like this:
import { ExampleOneComponent } from '#org/component-library/example-1';
Which then produces this at build time ng build component-library for #org/component-library/example-2.
example-1/public-api.ts is not under 'rootDir' example-2.
'rootDir' is expected to contain all source files.
I have the following file structure:
dist
example-1/
example-2/
tsconfig.json
projects
component-library
example-1
src
example-1.component.ts
public-api.ts
ng-package.json
package.json
example-2
src
example-2.component.ts
public-api.ts
ng-package.json
package.json
The rootDirs option in the TypeScript compiler configuration is used to specify a list of root folders that should be used to resolve non-relative module names. This is used when you want to make it easier for the compiler to find modules that are in multiple entry points, or are in a different location than the source files.
In your case, you have two Angular components, example-1 and example-2, which are in different entry points. To reference example-1 from example-2, you need to use the paths option in the TypeScript compiler configuration to map the path of the example-1 module to its location.
In the tsconfig.json file, you can add the following:
{
"compilerOptions": {
"baseUrl": "./",
"rootDirs": [
"projects/component-library/example-2"
],
"paths": {
"#org/component-library/example-1": [
"projects/component-library/example-1/src/example-1"
],
"#angular/*": [
"./node_modules/#angular/*"
]
}
}
}
In the above configuration, you are specifying the rootDirs as the location of example-2, which is the root folder of the current entry point. The paths option maps the #org/component-library/example-1 module to its location in the projects/component-library/example-1/src/example-1 folder.
Now, in your example-2 component, you can import the example-1 component as follows:
import { ExampleOneComponent } from '#org/component-library/example-1';
With these changes, you should be able to build and reference the example-1 component from the example-2 component.
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
so i am creating a graphQL server using type-graph and mikro-orm
everything was fine till i got this error that says => Error: Cannot find module 'src/entities/Post' and that module exists as you can see in this picture:
folder structure
and this is what the error looks like int the terminal: error in the terminal
by the way i am using script called watch: "tsc -w" to convert typescript into javascript.
this is a code example of my postResolver:
import { Post } from './src/entities/Post';
import { MyContext } from 'src/types';
import {Ctx, Query, Resolver} from 'type-graphql';
#Resolver()
export class postResolver {
#Query(()=> [Post])
posts(#Ctx() {em}: MyContext) : Promise<Post[]>{
return em.find(Post, {})
}
}
it says that the module ./src/entities/Post does not exist while it exists and i really don't know why
Fastest way to solve it would be using relative imports (import { Post } from '../entities/Post') instead of absolute like you did.
Another way to satisfy node to keep using absolute paths, is adding the following to your tsconfig file. Note that you will need to add a path for every directory at 'src' level, you want to import.
"compilerOptions": {
"baseUrl": "src",
"paths": {
"src/*": ["src/*"],
"entities/*": ["src/entities/*"],
"resolvers/*": ["src/resolvers/*"]
...
},
...
}
Or you could use a package like this one installed to your devDependecies
I found a plugin rollup-plugin-multi-input which fixes the problem of not being able to specifiy a glob to the test rollup config. For the unt tests, the entry point is not a single entity from which an import graph can be derived. It is just a collection of source files containing tests, which doesnt fit input requirement of rollup.
However, my attempt at trying to use it was fruitless:
rollup-config.tests.mjs:
import multi from 'rollup-plugin-multi-input';
const testConfig = {
input: ['test/**/*.spec.ts'],
external: ["chai", "mocha", "dirty-chai"],
output: {
format: "es",
file: `dist/${name}-bundle.test.js`,
plugins: [],
sourcemap: true
},
plugins: [
multi(),
resolve(),
commonjs(),
typescript({
tsconfig: "./tsconfig.test.json"
})
],
}
just resulted in this error:
[!] TypeError: multi is not a function
TypeError: multi is not a function
Looking at the exported code from the plugin, I can see that the default export is a function:
var _default = function(param) {
}
exports.default = _default;
So I don't know why this doesnt work.
I since discovered that there is another plugin that does a similar thing: #rollup/plugin-multi-entry:
import entry from "rollup-plugin-multi-entry";
plugins: [
entry(),
resolve(),
commonjs(),
typescript({
tsconfig: "./tsconfig.test.json"
})
],
so configured and invoked in exactly the same way, but now it works in the way that I wanted it to; the test bundle is created and mocha indeed sees all the tests and executes them successfully.
So let's take a look at that export and see if there is a difference in what is exported:
Well the first thing to notice is that its dist folder contains a .mjs file and a .js file. Since we're importing from an ESM package ("type": "module" in package.json), I guess we're using the default export from the .mjs file:
function multiEntry() {
...
}
export default multiEntry;
With rollup-plugin-multi-input, I even tried using the createRequire from "module":
import { createRequire } from "module";
const require = createRequire(import.meta.url);
const multi = require('rollup-plugin-multi-input');
but that failed for the same reason.
So whats the problem here? Why does default import from rollup-plugin-multi-input not work?
I have a Typescript library I've written which is being emitted as follows. I'm not sure how to import from this module, though.
node_modules/my-module/dist/index.js (partial)
define("services/UserService", ["require", "exports", ..., "services/BaseService"], function (require, exports, ..., BaseService_31) {
"use strict";
var UserService = (function (_super) {
// ... stuff here ...
return UserService;
}(BaseService_31.BaseService));
exports.UserService = UserService;
});
I've installed this package with npm and configured JSPM as follows:
config.js (partial)
System.config({
defaultJSExtensions: true,
transpiler: "none",
paths: {
"*": "dist/*",
"github:*": "jspm_packages/github/*",
"npm:*": "jspm_packages/npm/*",
"npm-ext:*": "node_modules/*"
},
map: {
...
"my-module": "npm-ext:my-module/dist/index.js",
...
}
});
I was expecting to be able to import this class as follows...
import {UserService} from "my-module/services/UserService";
I expected SystemJS to resolve the path to my-module and then locate the services/UserService module, and grab the single export UserService. But in the Chrome Console I see this is the path which is being loaded:
node_modules/my-module/dist/index.js/models/UserService.js
What's the correct way to import a module such as this?
Bonus: how can I get around including the full path to index.js?
Your library code was emitted using named define
define("services/UserService",
And it looks like there are several such modules defined in the index.js file, that is, index.js is a bundle.
The only way to import such module using SystemJS is
import {UserService} from "services/UserService";
That is, imported module name must match exactly the name given to define. In your case, the location of the file does not affect module name in any way.
Now, SystemJS has to be configured to load library file, node_modules/my-module/dist/index.js, when it sees that import. For bundles, the preferred way to to it is via bundles config:
bundles: {
"npm-ext:my-module/dist/index.js": ["services/UserService.js"]
}
Module name here, services/UserService.js, must have .js extension because it must match imported module name after defaultJSExtesions:true is applied.
If you want the module to be imported as my-module/services/UserService.js, then you need to make sure it is registered with that name. The easiest way is to have corresponding source file structure when compiling the library - that is, have UserService.ts in my-module/services folder.
You can find more information about named define in SystemJS module format docs, which says in particular
Named defines are supported and will write directly into the loader registry.
A single named define will write into the loader registry but also be treated as the value of the module loaded if the names do not match. This enables loading a module containing define('jquery', ....
P.S. Your browser tries to load
node_modules/my-module/dist/index.js/models/UserService.js
where does models come from?