I am setting up my module aliases in a NextJS project and everything runs fine so far.
The issue I have comes when I have a folder utils that includes both, an index.ts but also another someModule.ts.
My imports looked like this before:
import { someHelper } from '../utils'
import { anotherHelper } from '../utils/someModule'
Assuming I am setting the following module alias "#/utils/*": ["utils/*"], I would need to amend the first of the two imports like this:
import { someHelper } from '#/utils/index' // <-- see how I need to add index
unless I am extending the tsconfig with a second module alias like this: "#/utils": ["utils"].
This feels a bit like duplication to me, so I am wondering whether this is needed or do you have another option how to solve this?
Related
I have a TypeScript application working with es16 modules, most of them are imported statically. I want to use a (validator-) module now that is only imported in debug mode. It's all working, but I don't understand how to type things so that I get code completion and error-checking.
in my main class in main.ts I have:
...
if(debug){
import('./validator.js').then((module) => this.validate(module))
}
...
the validate method looks like that:
private validate(module):void{
new module.Validator(dataToValidate);
}
validator.js contains:
export class Validator{
coonstructor(data:MyDatatype){
stuff going on here...
}
}
what I would like to know/do is:
in the validate method:
private validate(module:someMeaningfulType){...}
and also I'd like to import the Validator class, without actually importing it.
if I wrote
import {Validator} from './validate.ts'
at the top of main.ts I would load the file regardles of I need it, which defeats the whole point of dynamic imports.
I might try to whrite a type declartaion for module and Validator in main.ts, but even if that wouldn't conflict somehow, I would have to manually keep it in sync with the actual module, which is not what I want - obviously.
I might miss something obvious, but I cannot find out what. I find id hard to search for the (pure) use of native es2020/2022 modules with Typescrit, as there is so much information about node-modules etc. overshadowing it.
You can actually use import with typeof to get the type of the imported module:
private validate(module: typeof import("./validator.js")) { ... }
Alternatively, you can use a type-only import, which will be erased in the output:
import type * as ValidatorModule from "./validator.js";
// ...
private validate(module: ValidatorModule) { ... }
i have some issue with gulp and es6 module import, i need add hash to my import for better version control and add a prefix from this:
import { someVar } from "./someFile.js";
to this:
import { someVar } from "./someFile.js?v=1.0.0";
Is there any way to automate it with gulp?
Or meaby some other solution could work.
For now im changing the name of the folder to prevent cacheing.
best if it works with dynamic import's too
Current cssuseragent package (2.1.31) doesn't export anything. There is only one variable named cssua. I want import/require it into my project with webpack.
I have tried to adding export keyword before cssua variable and it worked. But this is not a good solution. If anybody else upgrade the package in future, she/he won't know that s/he must do this.
In CLI:
npm i cssuseragent
Then I export cssua variable:
//'export' was not exist, I added it
export var cssua = (
//some code here
)(/*some arguments here*/)
Then I can import:
import { cssua } from 'cssuseragent';
Is there any way to say "If you resolve to this file in import/require, get it as 'custom-name' with its all content" to webpack with a loader or plugin? Because changing source code of a 3rd party module is not a good way. Also it may not be as easy as this every time, the module can be huge. And I want a generic way to do this, maybe like adding just the path of module.
I don't know of a webpack plugin that does that, but you can
// customExport.js
import { cssua } from 'cssuseragent';
export default { cssua };
in another file
// other_file,js
import customExport from "customExport.js";
I am using Next.js for React. I like how Arc (other react boilerplate) dynamically imports components without requiring developer to specify path.
import { Input, Label, Field, HomePage, PageTemplate } from 'components'
Folder structure may look somewhat like this:
components
|_ index.js
|_ atoms
|_ Input
|__ index.js
|_ molecules
|_ organisms
|_ templates
and I'd like to import it like:
import { Input } from 'components'
Code that is used for dynamic import: components/index.js
const req = require.context('.', true, /\.\/[^/]+\/[^/]+\/index\.js$/)
req.keys().forEach((key) => {
const componentName = key.replace(/^.+\/([^/]+)\/index\.js/, '$1')
module.exports[componentName] = req(key).default
})
However it doesn't work. The error I get:
Module not found: Error: Cannot resolve module 'components'...
The issue is that require.context is not available on serverside.
I suppose I need to specify this path to be imported like this in loader config. Can anybody share a hint on how is this done properly?
I don't think there is a simple and reliable way to do what you want with Next.js
The standard/"correct" answer is to use a relative path to import your local components. It is a bit more boilerplate, but I think you'll ultimately find it to be less work than fighting with Next.js to make it do things the Arc way.
To followup on #Robsonsjre's suggestion:
Why dont you make your /components/index.js export all components in the folder?
I think there is an implied "you write that index.js file". For your example, it would look something like this:
export {default as Input } from './atoms/Input';
export {default as Foo } from './molecules/Foo';
// etc
The catch is that you'd have to remember to update this file every time you add or remove a component. It's probably possible to automate that, but I'm not aware of any system to do it off the top of my head.
This way is not exactly what you want, but works similar, well for performance because its only object pointers to imported components
//Input.js
class Input extends Component {
render() {
return <div>'input'</div>
}
}
export default Input
//index.js
export { default as Input } from './Input/Input'
//otherComponent.js
import { Input } from './components' //path to folder components
I got this module like this:
module MyModule {
export class Constants {
public static WIDTH:number = 100;
public static HEIGHT:number = 100;
....
}
}
export = MyModule;
Now I need to use MyModule.Constants.WIDTH in another class but I can't use import (I need to deliver this class js to a third party, and they don't use requirejs). Right now I use reference to get code checking but it keep giving this error (at transpilling time)
error TS2095: Could not find symbol 'MyModule'
What should I do now so I can use autocomplete and get rid of this error?
I hope you're not mindplay on the TypeScript forum otherwise I'm about to repeat myself.
export and import work together. You should either be using both or neither. If you check what the generated code looks like with and without the export keyword you'll see that export causes a module to be built. Since the third party can't use RequireJS I don't think this is what you want.
I would structure my classes like the following:
// file pkg/Foo.ts
module company.pkg {
export class Foo {}
}
// file pkg2/Bar.ts
module company.pkg2 {
export class Bar{}
}
Putting everything into the name space of your company minimizes the chance of a conflict with another library. Classes know about each other using a reference /// <reference path="..." /> which will allow it to compile.
Since you're not doing modules I would also compile to a single file using --out filename.js. That gets all the files included in (usually) the right order.