Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

require.context() alternative when using ES modules

I have a project where I want to use ES modules and use import instead of require.

So I have added in package.json "type": "module".

There is a case now where I have to import some files and the only way I know to do that is by using require.context.


My file (which auto-imports routes):

import { createRouter, createWebHistory } from 'vue-router'

/*
 * Auto imports routes from @/pages. It only requires a route.js file inside each page
 * */
function autoImportRoutes() {
  const filePaths = require.context('@/pages/', true, /route.js/)
  console.log(filePaths.keys())
  return filePaths.keys().map(filePath => {
    const pathWithoutLeadingDot = filePath.replace('.', '') // remove first dot of ./path-name
    return require(`@/pages${pathWithoutLeadingDot}`).default
  })
}

const routes = autoImportRoutes()

const router = createRouter({
  history: createWebHistory(process.env.BASE_URL),
  routes
})

export default router


The error I get:

(node:36528) Warning: require() of ES modules is not supported.
require() of babel.config.js from project-path\no
de_modules\@babel\core\lib\config\files\module-types.js is an ES module file as it is a .js file whose nearest parent package.json contains "type": "module" which defines all .js files in that package scope as ES modules.
Instead rename babel.config.js to end in .cjs, change the requiring code to use import(), or remove "type": "module" from project-path\package.js
on.

If I remove, the "type": "module" from package.json everything works, but I wanted to know if there is a way to make this work.

I understand that require.context() (probably) is not allowed when using ES modules, but then how to do the same functionality without using require.context() ?


Update: I searched this a bit and it seems that it's not possible to do what I want (at least without hacking around with node file system) by using ES modules for 2 reasons.

  1. Haven't found an import alternative to require.context()
  2. import() it asynchronous which will make my code fail because vue-router doesn't waits. Could be workarounds to make it wait though, but too hacky.

So right now, I will stick with removing "type": "module" from package.json

Any answer is welcome and thanks for your time :)

like image 904
Roland Avatar asked May 03 '26 08:05

Roland


1 Answers

You don't need to (in fact, aren't supposed to) use require with require.context. The context object itself is callable, and will require the relevant module when called with the relevant key. Your import function should be:

function autoImportRoutes() {
  const filePaths = require.context('@/pages/', true, /route.js/)
  return filePaths.keys().map(filePath => {
    return filePaths(filePath).default
  })
}
like image 144
Steve Avatar answered May 06 '26 02:05

Steve