NodeJS require file from absolute path - node.js

I need to import some js files from the user's file system, I can't seem to do it using the absolute path of that file, I get the Cannot find module error
// /home/paul/Desktop/File.js
module.exports = {
data: "random string"
}
// Where I actually import it
const files = await fsPromises.readdir(desktopPath);
files.forEach((file) => {
if (/.*\.js$/.test(file)) {
const myImport = require(path.join(desktopPath, file));
console.log(myImport);
}
});
The error
Error: Cannot find module '/home/paul/Desktop/File.js'
at webpackEmptyContext (webpack:///./src_sync?:2:10)
at eval (webpack:///./src/background.js?:218:65)
at Array.forEach (<anonymous>)
at eval (webpack:///./src/background.js?:216:9)
at async electron/js2c/browser_init.js:197:563 {
code: 'MODULE_NOT_FOUND'
}
When I click on the file path it opens my File.js

Related

next-translate Cannot find module './locales/en/common.json'

I am trying to integrate the next-translate library into my Next app, however I am getting an error when configuring the loadLocaleFrom function
This is what my i18n.js file looks like:
module.exports = {
locales: ["en", "fr", "es", "ru", "ar", "zh", "hi", "sw"],
defaultLocale: "en",
pages: {
"*": ["common"],
"/": ["home"],
},
loadLocaleFrom: async (lang, ns) => {
try {
const m = await import(`./locales/${lang}/${ns}.json`);
return {
...m.default,
};
} catch (error) {
console.log(error);
}
},
};
And my next.config file:
const withPlugins = require("next-compose-plugins");
const withImages = require("next-images");
const nextTranslate = require("next-translate");
module.exports = withPlugins([withImages, nextTranslate], {
reactStrictMode: true,
images: {
disableStaticImages: true,
},
});
package.json version:
next-translate: ^1.5.0
next: 12.1.6
react: 17.0.2
Even though my directory has both, the common.json and the home.json files in the correct folder structure, the loadLocaleFrom function still throws an error that looks like this:
Error: Cannot find module './locales/en/common.json'
at webpackEmptyContext (D:\projects\mk\mk-academy\.next\server\pages\index.js:529:10)
at eval (webpack-internal:///./i18n.js:64:89)
at runMicrotasks (<anonymous>)
at processTicksAndRejections (node:internal/process/task_queues:96:5)
at async Object.loadLocaleFrom (webpack-internal:///./i18n.js:63:23)
at async Promise.all (index 0) {
code: 'MODULE_NOT_FOUND'
}
I did try using the appWithI18n hoc in _app.js but that doesn't solve it too. I also did try moving the locales to a different directory under src but that shouldn't make a difference.
The image shows my directory structure
require worked for me instead of import
await require(`./locales/${lang}/${ns}.json`)

Jest mock a const

I want to test a js file where it has a reference of a const coming from another import (parser.js)
const { cp } = CML
How can I mock this and only this and not the rest of functions?. It is throwing this error:
ReferenceError: CML is not defined
at Object.<anonymous> (src/state/lib/parser.js:2:16)
at Object.<anonymous> (src/state/reducers/stateReducer.js:2:1)
at Object.<anonymous> (src/state/reducers/index.js:4:1)
at Object.<anonymous> (src/state/store/index.js:4:1)
at Object.<anonymous> (src/state/store/store.spec.js:4:1)
CML is a var defined in other js resource file.
This is the parser.js file:
/* global CML */
const { cp } = CML;
// Massaging approvals array data
// Adding status and trimming unused values
export default {
approvals: (approvals = [], globalActions = []) => (
approvals.map(approval => {
let status = 'default';
let rejected = false;
let reviewed = 0;
...
And in stateReducer class this is the import of the parser:
import parser from '../lib/parser';
jest.mock('./state/lib/parser', function() { // Put the exact path you've imported in your file
return {
CML: 123,
};
});

NodeJs Script that compiles scss files fails because of postcss rule for undefined variables

I am using scss-bundle to import an scss file and resolve all his #import statements to later save it again as scss file.
This works fine and below is an example to see how it works:
scss-bundle.ts
import { Bundler } from 'scss-bundle';
import { relative } from 'path';
import { writeFile } from 'fs-extra';
/** Bundles all SCSS files into a single file */
async function bundleScss(input, output) {
const {found, bundledContent, imports} = await new Bundler()
.Bundle(input, ['./src/styles/**/*.scss']);
if (imports) {
const cwd = process.cwd();
const filesNotFound = imports
.filter((x) => !x.found)
.map((x) => relative(cwd, x.filePath));
if (filesNotFound.length) {
console.error(`SCSS imports failed \n\n${filesNotFound.join('\n - ')}\n`);
throw new Error('One or more SCSS imports failed');
}
}
if (found) {
await writeFile(output, bundledContent);
}
}
bundleScss('./src/styles/file-to-import.scss', './src/styles/imported-file.scss');
Where file-to-import.scss is the following file:
#import './file-to-import-1';
#import './file-to-import-2';
And file-to-import-1.scss and file-to-import-2.scss are the following files:
file-to-import-1.scss
.price-range {
background-color: $range-header-background-1;
}
file-to-import-2.scss
.qr-code {
background-color: $range-header-background-2;
}
The result of executing the script is:
imported-file.scss:
.price-range {
background-color: $range-header-background-1;
}
.qr-code {
background-color: $range-header-background-2;
}
Until this everything is working well.
Now ... I want to use postcss-css-modules in order to hash the names of the classes, the result should be something like this:
imported-file.scss after being hashed
._3BQkZ {
background-color: $range-header-background-1;
}
.Xb2EV {
background-color: $range-header-background-2;
}
I have already achieved that but only if I define the variables $range-header-background-1 and $range-header-background-2.
However, I can not define the variables yet because I need to defined them on run time as query params of an Http request.
If I run the script without defining the variables the following error is display:
(node:1972) UnhandledPromiseRejectionWarning: Unhandled promise rejection (rejection id: 2): CssSyntaxError: <css input>:372:14: Unknown word
(node:1972) [DEP0018] DeprecationWarning: Unhandled promise rejections are deprecated. In the future, promise rejections that are not handled will terminate the Node.js process with a non-zero exit code.
Here is the scss-budle.ts with postcss-css-modules call:
import { Bundler } from 'scss-bundle';
import { relative } from 'path';
import * as path from 'path';
import { writeFile } from 'fs-extra';
import * as postcssModules from 'postcss-modules';
import * as postcss from 'postcss';
import * as fs from 'fs';
/** Bundles all SCSS files into a single file */
async function bundleScss(input, output) {
const {found, bundledContent, imports} = await new Bundler()
.Bundle(input, ['./src/styles/**/*.scss']);
if (imports) {
const cwd = process.cwd();
const filesNotFound = imports
.filter((x) => !x.found)
.map((x) => relative(cwd, x.filePath));
if (filesNotFound.length) {
console.error(`SCSS imports failed \n\n${filesNotFound.join('\n - ')}\n`);
throw new Error('One or more SCSS imports failed');
}
}
if (found) {
await writeFile(output, bundledContent);
const hashedResult = await postcss().use(postcssModules({
generateScopedName: '[hash:base64:5]',
getJSON(cssFileName: any, json: any, outputFileName: any) {
let jsonFileName = path.resolve('./src/styles/imported-file.json');
fs.writeFileSync(jsonFileName, JSON.stringify(json));
}
})).process(bundledContent);
await writeFile(output.replace('.scss', '-hashed.scss'), hashedResult.css, 'utf8');
return;
}
}
bundleScss('./src/styles/file-to-import.scss', './src/styles/imported-file.scss');
Does anybody know how to continue executing postcss-css-modules without stopping because the scss variables are not defined?
Thanks in advance.
I was able to run the script successfully using postcss-scss as parser of postcss:
import * as postcssScss from 'postcss-scss';
...
const hashedResult = await postcss([
postcssModules({
generateScopedName: '[hash:base64:8]',
getJSON(cssFileName: any, json: any, outputFileName: any) {
let jsonFileName = path.resolve('./src/styles/imported-file.json');
fs.writeFileSync(jsonFileName, JSON.stringify(json));
}
})
]).process(bundledContent, { parser: postcssScss});
Below, I leave the script complete:
scss-bundle.ts
import { Bundler } from 'scss-bundle';
import { relative } from 'path';
import * as path from 'path';
import { writeFile } from 'fs-extra';
import * as postcssModules from 'postcss-modules';
import * as postcss from 'postcss';
import * as fs from 'fs';
import * as postcssScss from 'postcss-scss';
/** Bundles all SCSS files into a single file */
async function bundleScss(input, output) {
const {found, bundledContent, imports} = await new Bundler()
.Bundle(input, ['./src/styles/**/*.scss']);
if (imports) {
const cwd = process.cwd();
const filesNotFound = imports
.filter((x) => !x.found)
.map((x) => relative(cwd, x.filePath));
if (filesNotFound.length) {
console.error(`SCSS imports failed \n\n${filesNotFound.join('\n - ')}\n`);
throw new Error('One or more SCSS imports failed');
}
}
if (found) {
await writeFile(output, bundledContent);
const hashedResult = await postcss([
postcssModules({
generateScopedName: '[hash:base64:8]',
getJSON(cssFileName: any, json: any, outputFileName: any) {
let jsonFileName = path.resolve('./src/styles/imported-file.json');
fs.writeFileSync(jsonFileName, JSON.stringify(json));
}
})
]).process(bundledContent, { parser: postcssScss});
await writeFile(output.replace('.scss', '-hashed.scss'), hashedResult.css, 'utf8');
return;
}
}
bundleScss('./src/styles/file-to-import.scss', './src/styles/imported-file.scss');

Node JS Error: Cannot find module './services'

I am trying to create stubs using sinon to run the test but its throwing error.
Its trying to find a module services and saying the module is not found but I have the services.js in the same folder as test. So I am not sure why its failing.
Can someone please advise what is wrong in the code.
1) the car-lookup controller "before each" hook for "should return filtered TAP response":
Error: Cannot find module './services' from 'C:\nodejsworkspace\olive\server\api\car-lookup'
at Function.module.exports [as sync] (node_modules\proxyquire\node_modules\resolve\lib\sync.js:40:15)
at Proxyquire._resolveModule (node_modules\proxyquire\lib\proxyquire.js:137:20)
at Proxyquire.<anonymous> (node_modules\proxyquire\lib\proxyquire.js:205:35)
at Array.reduce (<anonymous>)
at Proxyquire._withoutCache (node_modules\proxyquire\lib\proxyquire.js:204:6)
at Proxyquire.load (node_modules\proxyquire\lib\proxyquire.js:129:15)
at Context.<anonymous> (test\unit\server\api\car-lookup\car-lookup.controller.test.js:30:18)
controller = proxyquire('../../../../../server/api/car-lookup/car-lookup.controller.js', {
'./services': { taClient: new MockTaClient() }
});
});
Below is how I think the services are being exported from the car-lookup.controller.js
Below is car lookup controller.js
If you see in the first line it is trying to import services and services is not a direct js file. I have an index.js file in the ../../directory which is what the first line is referring to. Directory structure is also below. Please advise.
>server
> api
> car-lookup
>car-lookup.controller.js
>server
>services
>index.js
'use strict';
const services = require('../../services');
const { ApiError, ValidationError } = require('../../errors');
const AccountModel = require('../../models/account-model');
const lookupAccount = (req, res, next) => {
const retrieveAccount = (oktaToken) => {
return services.tapClient.retrieveAccount(req.body);
};
const sendResponse = (account) => {
res.send(new AccountModel(account));
};
const onError = (err) => {
next(err instanceof ValidationError ?
new ApiError(err, 400) :
err);
};
retrive()
.then(retrieveAccount)
.then(sendResponse)
.catch(onError);
};
module.exports = {
lookupAccount
};
Make sure you are exporting the file services properly

NUXT: Module not found: Error: Can't resolve 'fs'

I'm starting out with vue and nuxt, I have a project using vuetify and I'm trying to modify the carousel component to dynamically load images from the static folder. So far I've come up with:
<template>
<v-carousel>
<v-carousel-item v-for="(item,i) in items" :key="i" :src="item.src"></v-carousel-item>
</v-carousel>
</template>
<script>
function getImagePaths() {
var glob = require("glob");
var options = {
cwd: "./static"
};
var fileNames = glob.sync("*", options);
var items = [];
fileNames.forEach(fileName =>
items.push({
'src': '/'+fileName
})
);
return items;
}
export default {
data() {
return {items :getImagePaths()};
}
};
</script>
When I test this I see:
ERROR in ./node_modules/fs.realpath/index.js
Module not found: Error: Can't resolve 'fs' in '....\node_modules\fs.realpath'
ERROR in ./node_modules/fs.realpath/old.js
Module not found: Error: Can't resolve 'fs' in ....\node_modules\fs.realpath'
ERROR in ./node_modules/glob/glob.js
Module not found: Error: Can't resolve 'fs' in '....\node_modules\glob'
ERROR in ./node_modules/glob/sync.js
Module not found: Error: Can't resolve 'fs' in '.....\node_modules\glob'
googling this I see a bunch of references like https://github.com/webpack-contrib/css-loader/issues/447.
These suggest that you have to midify the webpack config file with something like:
node: {
fs: 'empty'
}
I know very little about webpack. I found https://nuxtjs.org/faq/extend-webpack/ , but am not sure how to modify the webpack config file in this case.
How do I do this?
You can't use NodeJs specific module on browser.
To solve your issue, you can create an API using Nuxt server middleware. The code below, inspired by https://github.com/nuxt-community/express-template.
Create a file, index.js in api/index.js. Then fill it with:
const express = require('express')
// Create express instance
const app = express()
// Require API routes
const carousel = require('./routes/carousel')
// Import API Routes
app.use(carousel)
// Export the server middleware
module.exports = {
path: '/api',
handler: app
}
Create carousel.js in api/routes/carousel.js. Then fill it with:
const { Router } = require('express')
const glob = require('glob')
const router = Router()
router.get('/carousel/images', async function (req, res) {
const options = {
cwd: './static'
}
const filenames = glob.sync('*', options)
let items = [];
filenames.forEach(filename =>
items.push({
'src': '/'+filename
})
);
return res.json({ data: items })
})
module.exports = router
Register your server middleware in nuxt.config.js
module.exports = {
build: {
...
},
serverMiddleware: [
'~/api/index.js'
]
}
Call the api in your page / component. I assume you're using Axios here (axios-module).
<script>
export default {
async asyncData ({ $axios }) {
const images = (await $axios.$get('/api/carousel/images')).data
return { images }
}
}
</script>
I know this is an old question, but it may be helpful for someone to disable fs in their browser.
Like this:
nuxt.config.js
build: {
extend (config, { isDev, isClient }) {
config.node= {
fs: 'empty'
}
// ....
}
},
Add this in your nuxt-config.js:
build: { extend (config, { isDev, isClient }) {
config.node = {
fs: 'empty'
}
// ....
}},

Resources