Import JSON inside NPM Module - javascript

I made an npm module, this module export a function that load a json file and then export the result ( a little bit simplified )
The probleme is when I import this module inside another project I have this error :
no such file or directory, open 'C:\Users\{my_username}\github\{name_of_the_project}\file.json'
I looks like when I import my module, it try to read the json inside the current directory and not inside the npm module.
The code inside my module :
export default function() {
return readFile('./swagger.json')
.then(data => JSON.parse(data))
}

Final answer (for ES Module) :
import { readFile } from 'fs/promises';
import { fileURLToPath } from 'url';
import path from 'path';
export default function() {
const __filename = fileURLToPath(import.meta.url);
const __dirname = path.dirname(__filename);
return readFile(`${__dirname}/swagger.json`)
.then(data => JSON.parse(data))
}
If you don't use ES Module (but commonJS), __dirname already exist so you can do :
export default function() {
return readFile(`${__dirname}/swagger.json`)
.then(data => JSON.parse(data))
}

Related

Module not found: Can't resolve 'fs', Next.Js

import nookies from 'nookies';
import { firebaseAdmin } from "../firebaseAdmin";
import { TChildren } from "../types/app/app.types";
interface Props {
children: TChildren;
}
export default function ProtectedRoute(props: Props): JSX.Element {
return <>
{props.children}
</>
}
export const getServerSideProps = async (ctx: GetServerSidePropsContext) => {
const cookies = nookies.get(ctx);
const data = await firebaseAdmin.auth().verifyIdToken(cookies.token);
console.log(data);
return {
props: { message: `Your email is .` },
};
};
await firebaseAdmin.auth().verifyIdToken throws error module not found: can't resolve fs, How to fix this error?
I know that we have different types of runtime environments like edge, browser nodeJs, but based of the docs and examples getServerSide Props runs on nodeJs environment which means that I shouldn't get this kind of error...
Is the 'fs' module available in the environment?
npm i fs-extra
Then using commonjs:
const fs = require('fs-extra')
OR using latest es6 module system:
import fs from 'fs-extra'

what type do I use for app in express typescript

I'm exporting controllers in an index.ts, does anyone know what type do I use when passing app as a parameter in line 7?
import userController from "./userController.js"
import getController from "./getController.js"
import productController from "./productController.js"
const exportArr = [userController, getController, productController]
export default (app: any) => {
exportArr.forEach(controller => controller(app))
}
Make sure you install express types npm install #types/express and in your .ts file import {Application} from 'express'
Your code would look like this:
import { Application } from "express";
import userController from "./userController.js"
import getController from "./getController.js"
import productController from "./productController.js"
const exportArr = [userController, getController, productController]
export default (app: Application) => {
exportArr.forEach(controller => controller(app))
}

Javascript unit testing errors, stubbed function still being called

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";

Netlify Vue Build Failing To Find Export Modules

So I have a couple of modules that I am importing in to my main.js and store.js file that are not being found when building in Netlify and I cannot understand why. When I run my build locally there is no issues.
So the 2 files are ability.js and storage.js
This is the alarm from the build in netlify
12:48:10 PM: These relative modules were not found:
12:48:10 PM: * ./utils/ability.js in ./src/main.js, ./src/store.js
12:48:10 PM: * ./utils/storage.js in ./src/store.js
12:48:10 PM: ERROR Build failed with errors.
Here is the ability.js file
import { Ability } from '#casl/ability'
export const ability = new Ability()
export const abilityPlugin = (store) => {
ability.update(store.state.rules)
const rules = store.subscribe((mutation) => {
switch (mutation.type) {
case 'createSession':
ability.update(mutation.payload[0])
break
case 'destroySession':
ability.update([{ actions: '', subject: '' }])
break
}
})
return rules
}
here is the storage.js file
export default (options) => (store) => {
if (localStorage.state) {
const storedState = JSON.parse(localStorage.state)
store.replaceState(Object.assign(store.state, storedState))
}
return store.subscribe((mutation, state) => {
if (options.destroyOn && options.destroyOn.indexOf(mutation.type) !== -1) {
return localStorage.removeItem('state')
}
const newState = options.storedKeys.reduce((map, key) => {
map[key] = state[key]
return map
}, {})
localStorage.state = JSON.stringify(newState)
})
}
and here are the 2 files where I import these modules
main.js
import Vue from 'vue';
import App from './App.vue';
import router from './router';
import store from './store';
import { abilitiesPlugin } from '#casl/vue';
import { ability } from './utils/ability.js';
Vue.use(abilitiesPlugin, ability);
new Vue({
router,
store,
render: h => h(App),
}).$mount('#app')
store.js
import Vue from 'vue'
import Vuex from 'vuex'
import axios from 'axios'
import { abilityPlugin, ability as appAbility } from './utils/ability.js'
import storage from './utils/storage.js'
export const ability = appAbility
Vue.use(Vuex)
axios.defaults.baseURL = 'https://aewcpa.traxit.pro/api'
axios.defaults.headers.common['header1'] = {
'X-Requested-With': 'XMLHttpRequest',
}
export default new Vuex.Store({
plugins: [
storage({
storedKeys: ['rules', 'token'],
destroyOn: ['destroySession']
}),
abilityPlugin
],
})
The directory structure with issues
The directory structure that currently works
Is Utils in the root of your project? Are you using the Vue Webpack Template?
If so the # resolver is configured for you (ES6 import using at ('#') sign in path in a vue.js project using Webpack)
If so change:
from './utils/ability.js' to from '#/utils/storage.js'
and
from './utils/storage.js' to from '#/utils/storage.js'

how ES6 imports and exports works?

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.

Categories

Resources