Guided by eslint's prefer-destructuring rule, I defined some constants like this:
const {
NODE_ENV,
API_URL,
} = process.env;
Is it possible to export these constants by prefixing the statement by export?
export const {
NODE_ENV,
API_URL,
} = process.env;
This would seem natural, but eslint-plugin-import complains about a violation of the import/named rule: API_URL not found in '../constants'. In fact, this usage of export is also not described on the relevant MDN page.
Do we then have to repeat all constants in a separate export statement?
const {
NODE_ENV,
API_URL,
} = process.env;
export {
NODE_ENV,
API_URL,
};
Is it possible to export these constants by prefixing the statement by
export?
export const {
NODE_ENV,
API_URL,
} = process.env;
Yes, this is totally valid according to the spec. You can use destructuring patterns in the declarations of exported consts.
This would seem natural, but
eslint-plugin-import
complains about a violation of the
import/named
rule: API_URL not found in '../constants'.
Sounds like that plugin is broken. In fact, your exact use case was reported as working before.
Article 15.2.2.3 of the spec says:
...
ExportDeclaration : export VariableStatement
ExportDeclaration : export Declaration
Article 13.1.4 says:
Declaration : LexicalDeclaration
Article 13.3 says:
LexicalDeclaration:
LetOrConst BindingList;
LetOrConst :
let
const
BindingList :
LexicalBinding
BindingList, LexicalBinding
LexicalBinding:
BindingPattern Initializer
Therefore this:
// ExportDeclaration
export // export
// Declaration
// LexicalDeclaration:
const // LetOrConst
// LexicalBindingList
// LexicalBinding
{ NODE_ENV, API_URL } // BindingPattern
= process.env; // Initializer
is totally valid JavaScript.
Related
How to include functions in namespace / module when don't have module?
example: I have a namespace:
namespace Java {}
in typescript, usually when we need a function in namespace or module, we add 'export':
namespace Java {
export function version() {
return "java8";
}
}
namespace JavaScript {
function JavaVer() {
return Java.version();
}
}
But if I set module to none:
// tsconfig
"module": "none",
If module is none, I cannot use import / export:
website/sourcecode/main.ts:17:21 - error TS1148: Cannot use imports, exports, or module augmentations when '--module' is 'none'.
17 export function version() {}
so what can I do?
image:
You can use a plain object:
TS Playground
const Java = {
version () {
return "java8";
},
};
const JavaScript = {
JavaVer () {
return Java.version();
},
};
const vJ = Java.version(); // string
const vJS = JavaScript.JavaVer(); // string
console.log(vJ === vJS); // true
It was answered in here: It's actually "can't have any imports or exports at the top level". Imports and exports inside namespaces are fine because they don't export anything from .ts file at runtime, and as long as file remains 'not a module' module=None works fine. Long explanation here
I have env var SERVER_URL=localhost:8000
config.js
export const SERVER_URL = process.env.SERVER_URL;
export { SERVER_URL as default };
and action:
function fetchData(apiUrl, timeout) {
return timeoutPromise(timeout || 15000, fetch(`${SERVER_URL}${apiUrl}`))
.then(checkHttpStatus)
.then(parseJSON);
}
but after use this fetchData I get http://localhost:8000/undefined/some_api
idk where from came this undefined
If you are using create-react-app, only environment variables prefixed with REACT_APP_ will be available.
Try console.log(SERVER_URL), that's where your undefined came from.
Create an environment variable REACT_APP_SERVER_URL instead and refer to it with process.env.REACT_APP_SERVER_URL in your app.
Inside config.js:
const SERVER_URL = process.env.SERVER_URL;
export default SERVER_URL;
Other file app.js:
import SERVER_URL from './config';
I am exporting a function like this which works.
module.exports = function (options: any): RequestHandler {
// Do stuff
}
I am trying to add a definition for the exported function, but I am not sure if this is the right way to do it:
declare global {
export function tsm(options: any): RequestHandler
}
When I try to test it both of the following say that this is valid:
const tsm = require('ts-middleware')
global.tsm() // Gives intellisense
tsm() // Also gives intellisense
It shouldn't give information about global.tsm(), so I think that I created my definition wrong. What is the correct way to create a function definition?
I don't want to use the function like this:
const tsm = require('ts-middleware')
tsm.tsm()
But I do want to use it like this:
const tsm = require('ts-middleware')
tsm()
To define typings for a module, use declare module 'x' {...}. i.e.:
declare module 'ts-middleware' {
export = (option: any): RequestHandler
}
However, you do not really need to do that because you wrote your code in TypeScript. The compiler can generate the typings for you automatically.
You just need to add declaration: true in your tsconfig.json:
// tsconfig.json
{
"compilerOptions": {
"declaration": true
}
}
Also, I would strongly recommend you to write your code using ESM. i.e. instead of module.exports = ...:
// named export, preferred
export function foo(options: any): RequestHandler { ... }
// or default export
export default function foo(options: any): RequestHandler { ... }
// import in TypeScript for named export
import { foo } from 'ts-middleware'
// import in TypeScript for default export
import foo from 'ts-middleware'
// require in JavaScript commonjs
const middleware = require('ts-middleware')
middleware.foo(...)
As you know, it's possible to access to exported variables and functions of the main js-file in the module, e. g.:
module1.js
export const MODULE1_CONSTANT1 = 'Test Const From the module1.js';
main.js
import { MODULE1_CONSTANT1 } from './module1';
console.log(MODULE1_CONSTANT1);
However: is it way to access to the main.js variables from the module1.js? I suppose, the answer will be same, so is it possible to exchange by variables between modules?
I know that it's not only JavaScript matter and project build system has the influence too, so let's consider Webpack in this question.
Use keyword require replace keyword import(because import MUST in top of source, it is ES6 syntax), and make a function to access each module, I think it can implement variables exchange between modules.
// module1.js
export const MODULE1_CONSTANT1 = 'Test Const From the module1.js';
export function MAIN_CONSTANT1() {
return require('./main').MAIN_CONSTANT1;
};
// main.js
export const MAIN_CONSTANT1 = 'Test Const From the main.js';
export function MODULE1_CONSTANT1() {
return require('./module1').MODULE1_CONSTANT1;
};
// hello.js
import {MAIN_CONSTANT1 as main_MAIN_CONSTANT1, MODULE1_CONSTANT1 as main_MODULE1_CONSTANT1} from './main';
import {MAIN_CONSTANT1 as module1_MAIN_CONSTANT1, MODULE1_CONSTANT1 as module1_MODULE1_CONSTANT1} from './module1';
console.log('main_MAIN_CONSTANT1', main_MAIN_CONSTANT1);
console.log('main_MODULE1_CONSTANT1', main_MODULE1_CONSTANT1());
console.log('module1_MAIN_CONSTANT1', module1_MAIN_CONSTANT1());
console.log('MODULE1_CONSTANT1', module1_MODULE1_CONSTANT1);
// output
// >>> MAIN_CONSTANT1 Test Const From the main.js
// >>> MODULE1_CONSTANT1 Test Const From the module1.js
// >>> module1_MAIN_CONSTANT1 Test Const From the main.js
// >>> module1_MODULE1_CONSTANT1 Test Const From the module1.js
EDIT
This is NOT a TypeScript question but rather a best-practices one. The example in TypeScript but really, the question here is how do I, correctly, expose multiple exports from multiple files that compose a module, and how to correctly import them.
EDIT 2
There's still something not right
So, on my Module2's index I have this:
export * from "./queryFilter";
On Module1 user.ts I import it by using
import { queryFilter as QueryFilter } from "Module2";
(...)
var User = {...}
User.getById = (userId: string) => {
...
}
export { User }
And my Module1's index.ts I export it as
export * from "./model/user";
Then, on my main project I import it using
import * as Schema from "Module1";
var User = Schema.User;
However, this throws an error whenever I try to call User.getById:
Debug: internal, implementation, error
TypeError: Uncaught error: Cannot read property 'getByEmail' of undefined
From this approach, what am I doing wrong???
I'm writing a couple of node modules for the first time ever and I do have some questions regarding proper declaration/usage of this.
So I'm creating a module that will require another custom module, let's call them Module1 and Module2.
So, Module1 is required by the main application, but Module1 also requires Module2.
Now on Module2 I have a bunch of files and on each one I export what I need. Here's a sample:
Module2 - Utils.ts:
"use strict"
const RandomString = require("randomstring");
let randomString = (numCharacters: number) => {
return RandomString.generate({
length: numCharacters,
capitalization: 'uppercase',
charset: 'alphanumeric'
});
}
module.exports.randomString = randomString;
Module2 - queryFilter.ts:
"use strict"
export default class QueryFilter {
name: string;
op: string;
value: any;
scope: string;
constructor(name: string, op: string, value: any, scope: string) {
this.name = name;
this.op = op;
this.value = value;
this.scope = scope;
}
public static GetConditionQuery(filters: QueryFilter[], params: string[]) {
(...)
}
public static queryComparator(value1: any, value2: any, operator: string): any {
(...)
}
}
On Module1, I added Module2 to package.json so when I want to use QueryFilter, for instance, I require it like this:
Module1 - Class.ts:
import { QueryFilter } = require("Module2").queryFilter;
Now my question is, is it enough to export individual items from each file in my Module2 and use it in this fashion? Or should I have a index that would export every file from Module2 so that Module1 can see them?
Something along the lines of:
Module2 - index.ts:
export "./utils"
export "./queryFilter"
(...)
What is the correct way of doing this? I'm a total newb to this and the docs I've read didn't shed any light on this..
Best Regards
Following your last comment, this the 'typescript solution' for creating a module/library. The solution would be similar for "pure" ES6; typings in Typescript just add a small layer of difficulty.
Assuming you write a module/library with multiple files:
func1.ts
export func1(param1: number): string { ... }
func2.ts
export func2(): number { ....}
Create an index.ts which re-exports the interesting parts of your module/lib
export * from './func1'
export * from './func2'
....
Obviously you can choose to (re)export and make public only part of the code e.g. export { thisFunc, thatClass } from './anotheFile'
Compile the module with declarations and commonjs flags, and make sure that the package.json main points to index.js, while the typings entry points to the generated index.d.ts
This module/library can now be used from Javascript or Typescript using an ES6 style import syntax
import { func1, func2 } from 'mymodule'
If this is Typescript, the typings of the 2 functions will automatically be imported too.