Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

path.join in require statement

I try to use Path.join in require statement like this:

import Path from 'path'

const assetPath = Path.join(process.cwd(), `./lib/asset-manifest.json`)

console.log(assetPath)
'/home/dev/Website/lib/asset-manifest.json'

console.log(
  assetPath === '/home/dev/Website/lib/asset-manifest.json'
)
true

const assets = require(assetPath)

But that throws error that:

Error: Cannot find module '/home/dev/Website/lib/asset-manifest.json'

Though the file is there and require works if I put the string manually in it:

const assets = require('/home/dev/Website/lib/asset-manifest.json')

So I wonder why does not Path.join works in require ?

Best regards

like image 595
user1665355 Avatar asked Dec 30 '18 14:12

user1665355


Video Answer


2 Answers

import path from 'path';

// you can use process.cwd() if you want
const assetPath = path.join(path.dirname(require.main.filename), `lib/asset-manifest`);

const test = () => {
  var assets = require(assetPath);
  console.log(assets);
};

export default test();

You need to surround the require inside a function. Otherwise require will run before the path is assigned to the assetPath variable. This is because require is SYNC and runs in perspective to file or function in which it is called. Because you are stating this is required it gets immediately executed before anything else.

Best practice moving forward is to stop using require for json files. Require caches content and so if the JSON file changes in production your users may get old data. Instead use fs.readfile(path, (err, data) => JSON.parse(data))

There is a webpack configuration you may want to try in your case.

WEBPACK DOCS: Don't Check Require Dependencies

WEBPACK DOCS: Generate Require Func

const requireJSON = typeof __webpack_require__ === "function" ? __non_webpack_require__ : require;
const assets = requireJSON(assetPath);

This should return all possible paths for the require.

like image 99
Dallas Baker Avatar answered Oct 06 '22 10:10

Dallas Baker


webpack is a static module bundler, require here is not like the require in nodejs.

The previous one includes files at static compilation phase, the another includes files at runtime.

Your case, const assets = require(assetPath), assetPath is not defined at static compilation phase, that's why throw the error.

Let's see the bundled result:

// const assets = require(assetPath);
const assets = await __webpack_require__("./ lazy recursive")(assetPath);

// below is the "./ lazy recursive" module
function webpackEmptyAsyncContext(req) {
    // Here Promise.resolve().then() is used instead of new Promise() to prevent
    // uncaught exception popping up in devtools
    return Promise.resolve().then(() => {
        var e = new Error("Cannot find module '" + req + "'");
        e.code = 'MODULE_NOT_FOUND';
        throw e;
    });
}
webpackEmptyAsyncContext.keys = () => ([]);
webpackEmptyAsyncContext.resolve = webpackEmptyAsyncContext;
webpackEmptyAsyncContext.id = "./ lazy recursive";
module.exports = webpackEmptyAsyncContext
like image 39
Yan Avatar answered Oct 06 '22 10:10

Yan