Does anyone know of a better way to do this?
The goal: import, use, and export createLogger from the same file (application entry point).
WebStorm gives me a duplicate declaration warning.
import createLogger from './logger';
const logger = createLogger('namespace');
export { default as createLogger };
export { * as plugins } from './plugins';
export setup = () => {
// ...
logger.log('');
}
export start = async () => {
// ...
logger.log('');
}
To export multiple functions from the same file just do this:
import createLogger from './logger';
const logger = createLogger('namespace');
import plugins from './plugins';
import anotherLib from './anotherLib';
const setup = () => {
// ...
logger.log('');
}
const start = async () => {
// ...
logger.log('');
}
// export everything without default
export { plugins,
createLogger,
anotherLib,
setup,
start}
You can import them in another file after this is done.
Here's a sandbox to see how it works.
Have a look at this documentation about the export statement.
Related
Recently i saw a video that i guy was exporting a module in commonjs:
// src/routes/index.js file
module.exports = [
require('./user'),
require('./auth'),
require('./demo')
]
// src/routes/user.js
const exppres = require('express')
const api = express.Router()
api.post('/user' , doSomething())
// src/handler.js
const express = require('express')
const api = require('./routes')
const app = express()
app.use(api) // add all routes
I tried all different ways of doing, like:
export default {
import "./user",
import "./auth"
}
and in server layer
import api from './routes'
but nothing works...
Someone knows how to do it?
Try this
module.exports = {
user:require('./user'),
auth:require('./auth'),
demo: require('./demo')
}
Then access them like this
const {user,auth, demo} = require("path to the expoted module")
I don't quite understand what you mean by "for its side effects only", because then you wouldn't need to export anything. Importing for side effects only is done like this with ES6 modules:
import './user';
import './auth';
import './demo';
If you wanted to re-export something from these modules, you'd typically write
export * from './user';
export * from './auth';
export * from './demo';
or
export { default as user } from './user';
export { default as auth } from './auth';
export { default as demo } from './demo';
You would not export an array.
I am trying to write some unit tests and I am getting errors in the test and I am trying to understand why the errors happen.
The unit test is for the index.ts file that calls the features/index.ts file. I am stubbing the default export from features/index.ts with sinon. But when I run the tests I get the following error TypeError: Cannot read property 'resolve' of undefined pointing at the file features/feature1.ts
I have added the relavant extracts from the tests and typescript files below.
features/feature1.ts
import path from "path";
import fs from "fs";
import {Setup} from "../types";
const TEMPLATE_ROOT = path.resolve(__dirname,"../../templates");
const INDEX_TEMPLATE = fs.readFileSync(TEMPLATE_ROOT, "index.js"), "utf8");
export const setup: Setup = async ({config, options}) => {
// Internal code removed
}
features/index.ts
import {setup as feature1} from "./feature1.ts";
import {setup as feature2} from "./feature2.ts";
type FeatureTypes = "feature1" | "feature2"
type Features = {
[key in FeatureTypes]: Setup;
};
const features: Features = {
feature1: feature1,
feature2: feature2
}
export default features
index.ts
import features from "./features"
import { Config, Options } from "./types";
export async function init(config: Config, options: Options): Promise<void> {
const nextFeature = options.features ? options.features.shift() : undefined;
if (nextFeature) {
// Other irrelevant code
await Promise.resolve(features[nextFeature]({ config, options }));
return init(config, options);
}
}
index.spec.ts
import { expect } from "chai";
import * as sinon from "sinon";
import { init } from '.'
import * as features from "./features";
import { Config, Options } from "./types"
describe("init", () => {
const sandbox: sinon.SinonSandbox = sinon.createSandbox();
let featuresStub: sinon.SinonStub;
beforeEach(() => {
featuresStub = sandbox.stub(features, "default").returns({
feature1: sandbox.stub().resolves(),
feature2: sandbox.stub().resolves(),
});
});
afterEach(() => {
sandbox.restore();
});
it("should call setup features", async () => {
const setup: Setup = {
features: [
"feature1",
"feature2",
],
};
await init({}, options);
expect(featuresStub).to.have.been.calledOnce;
});
// rest of tests
});
I have also tried the changing the stub setup to be:
import * as feature1 from ".features/feature1";
import * as feature2 from ".features/feature2";
// Other code
describe("init", () => {
const sandbox: sinon.SinonSandbox = sinon.createSandbox();
let feature1Stub: sinon.SinonStub;
let feature2Stub: sinon.SinonStub;
beforeEach(() => {
feature1Stub = sandbox.stub(feature1, "setup");
feature2Stub = sandbox.stub(feature2, "setup");
feature1Stub.resolves()
feature2Stub.resolves()
});
// Rest of code and tests
});
I don't know why it would be trying to run code const TEMPLATE_ROOT = path.resolve(__dirname,"../../templates"); if I have stubbed the function that calls it.
Figured it out the imports were wrong
import path from "path";
import fs from "fs";
should be:
import * as path from "path";
import * as fs from "fs";
It's possible to do a barrel in Vuejs?
If yes, please show a example, I search in the web, but i didn't find anything
Like js
// app/domain/index.js
export * from './negotiation';
export * from './negotiations';
// app/app.js
import { Negotiation, Negotiations } from './domain';
You can do
export {default as MyModule} from './MyModule.vue';
When I barrel .vue files I do it this way:
Creating the barrel
//index.js
import File1 from './file1'
import File1 from './file1'
export {
File1,
File2
}
Using the barrel file
import { File1, File2 } from './path'
Probably, this will work:
// app/domain/index.js
import NegotiationModule from './negotiation';
import NegotiationsModule from './negotiations';
export const Negotiation = NegotiationModule;
export const Negotiations = NegotiationsModule;
// app/app.js
import { Negotiation, Negotiations } from './domain';
(I haven't tested it, so it could not work)
Create index.js file in the same folder as the components (negotiation, negotiations)
app/domain/index.js
import negotiation from './negotiation.vue'
import negotiations from './negotiations.vue'
export default { negotiation, negotiations };
app/app.js
import domains from './domain';
const { negotiation, negotiations } = domains;
export default {
components: { negotiation, negotiations }
}
I'm studying Redux with React Native and I have an example like this:
reducer.js
import {combineReducers} from "redux";
import {HomeReducer as home} from "../routes/Home/modules/home";
const makeRootReducer = () => {
return combineReducers({
home
});
};
export default makeRootReducer;
createStore.js
import {createStore, applyMiddleware, compose} from 'redux';
import thunk from "redux-thunk";
import {createLogger} from 'redux-logger';
import makeRouteReducer from './reducer';
const log = createLogger({diff: true, collapsed: true});
export default (initialState = {}) => {
const middleware = [thunk, log];
const enhancers = [];
return store = createStore(
makeRouteReducer(),
initialState,
compose(
applyMiddleware(...middleware),
...enhancers
)
);
}
It works fine but I don't understand why I have to use export default in reducer.js.
When I try to use
// reducer.js
export makeRootReducer
and
// createStore.js
import {makeRouteReducer} from './reducer';
It didn't work.
Please help me by explaining it in detail.
Thank you very much.
You're talking about named exports and default exports...
Example of a named export:
export const someFunction = () => {
// some code here...
}
Now you can import this in another file like this:
import {someFumnction} from './nameOfFile'
But if you do:
export default function someFunction () {
// some code here...
}
That's a default export and you have to import it like this:
import someFunction from './nameOfFile'
In your example if you change this:
const makeRootReducer = () => {
return combineReducers({
home
});
};
export default makeRootReducer;
To this:
export const makeRootReducer = () => {
return combineReducers({
home
});
};
It will become a named export and not a default export and now you can do:
import {makeRootReducer} from....
Hope that clarifies... And here is more info
I am writing react application and i has dir with actions files my example action file looks like
export const USER_LOADING_START = 'USER_LOADING_START';
export const USER_LOADED = 'USER_LOADED';
export function userLoadingStart() {
return {
type: USER_LOADING_START
};
}
export function userDataLoaded(value) {
return {
type: USER_LOADED,
payload: {
value: value
}
};
}
and in actions dir i have a file named index.js which content is
import * as userActions from './userActions';
let exp = {
...userActions,
};
export default exp;
So in other files i want to import my action creators so i use:
import {userLoadingStart} from './actions';
and it doesn't work but if i write:
import actions from '../actions';
const { userLoadingStart } = actions;
then it is working correctly, so what am i doing wrong ?
i tried
export {
...userActions,
...spinnerActions,
...errorActions
}
and
export exp
but it doesn't compile by webpack
So in other files i want to import my action creators so i use:
import {userLoadingStart} from './actions';
For that to work, it means ./actions must export named values. The issue is that your logic currently bundles everything up and exports it as single named export named default. The easiest way to do that would be for your index to do
export * from './userActions';
to essentially pass everything from ./userActions through as exports of ./actions.