Webpack-cli: [Feature]: Consider supporting webpack.config.mjs alongside webpack.config.js

Created on 25 Feb 2018  ·  30Comments  ·  Source: webpack/webpack-cli

Do you want to request a feature or report a bug?
Feature.

What is the current behavior?
webpack.config.mjs cannot be used in place of webpack.config.js.

What is the expected behavior?
webpack.config.mjs could be used instead of webpack.config.js.

If this is a feature request, what is motivation or use case for changing the behavior?
Consistency.


This issue was moved from webpack/webpack#6566 by @sokra. Orginal issue was by @TomasHubelbauer.

Discussion Feature Request

Most helpful comment

This needs an update as node has officially released modules without a flag (albeit experimental)

Node is heading towards ESM over the next few years, so this needs to be addressed.

All 30 comments

@TomasHubelbauer

There is --experimental-modules which could be set to enable import

The problem here is not import, which is what is enabled by any node with that option, but import(), which is only supported on node 9.6.0. Supporting loading those files would _also_ make webpack-cli itself only run on node >= 9.6.0 with --experimental-modules enabled.

This is because webpack has to be able to recover from not being able to import webpack.config.{mjs,js,json}, maybe because the user gave --config as an option or because it's in another format that webpack supports. The import is also relative to process.cwd(), a dynamic value, necessitating a dynamic import.

Although, since it is import() instead of import, it might be possible to try to use it via eval instead of directly, to be able to fallback to require 🤔

You could use the --config-register flag?

@ev1stensberg I think we're missing docs for that flag.

@TomasHubelbauer Till we add it to the docs, you can try doing what @jdalton has mentioned here.

https://github.com/webpack/webpack-cli/commit/ab9421136887b7e9e10f25a39b59fb32f07b5037#r26371308

He doesn't really mention the actual command. Just do webpack help to get the description and expected use.

Did someone on the thread answer/fix your issue @TomasHubelbauer ?

This is a feature request, the way I understand it, there are some ideas floating around and maybe the issue will get triaged for feasibility and put on a roadmap?

To be clear, I am not blocked or anything by not being able to do this right now, I'd just like to see it be a possibility in the future.

Cause I think it's doable, if you run webpack --config-register babel-register std/esm

https://github.com/standard-things/esm can be used for this feature

@ev1stensberg @montogeek Thanks, I'll try that out!

This is how I am using it to enable import in a webpack file:
npm script
image
webpack.config.js
image

In webpack 4 you can use its -r flag (alias of the longer --config-register flag).
For the esm case you'll want to load that first if you're also using other loaders:

webpack -r esm @babel/register

or

webpack -r esm -r @babel/register

Thanks for clearing up @jdalton , closing this now, as the issue/feat has been solved ( ? )

It would still be cool if this worked out of the box and was built it to WebPack, but custom config loader is a good option.

That's not a fix, that's a workaround that's done by emulation. It's not loading native modules.

One thing we could do is to detect .mjs endings and use webpack with std/esm instead?

That'd just be blessing the workaround.

The _only_ valid fix that won't _require_ users not using the feature to enable experimental modules is eval(`import(${JSON.stringify(pathToConfig)})`).

If the eval turns out false, we can fall back to std/esm?

Yeah, if the eval itself throws a SyntaxError then it's because the currently executing node either can't or hasn't enabled parsing for import(). If the resulting Promise rejects, though, that is because there actually was an error importing the config and that error should be respected.

/** @param {string} modulePath */
function tryImport (modulePath) {
  try {
    return eval(`import(${JSON.stringify(modulePath)})`);
  } catch (e) {
    // import() not supported on the currently executing node
    return Promise.resolve().then(() => {
      // optionally try the @std/esm stuff here if desired
      const result = require(modulePath)
      if (typeof result !== 'object' || result === null || !result.__esModule) {
        // this is technically supposed to be cached but there probably won't be any
        // harm not to cache it in this use case
        result = Object.create(null, { default: { value: result, enumerable: true } })
      }
      return result
    })
  }
}

Note that the Promise.resolve().then part is important; you should not try to run require on the same tick as this.

.mjs is experimental and nodejs team are still discussing the implementation concerns. So it could be dropped or change in the feature. Honestly I wouldn't put effort on something that could change, risking breaking changes and more efforts from people.

I think we should put this for chill on now, eval is not a good thing and using the eval code for a rejected promise would mean a lot of work to get it right and tight. We could spawn a child process to get the config through esm/std once we're more laid up for it.

@evenstensberg

node 13.2 has been released with .mjs support without flag: https://github.com/nodejs/node/releases/tag/v13.2.0

can we think about use webpack.config.mjs and webpack.config.cjs as config file?

Definitely, are you able to test it against webpack-cli@beta?

@evenstensberg I am happy to participate in the test. What kind of tests do I need to do?

This needs an update as node has officially released modules without a flag (albeit experimental)

Node is heading towards ESM over the next few years, so this needs to be addressed.

@evenstensberg

Definitely, are you able to test it against webpack-cli@beta?

tried to test

have an error

 ~/projects/purescript-halogen-mdl   master ●✚  webpack --config ./webpack/server.mjs

 Compilation Results

 Version: 4.42.0
 Built: Mon Mar 23 2020 20:17:01 GMT+0200 (Eastern European Standard Time)
 Compile Time: 31ms
 Output Directory: /home/srghma/projects/purescript-halogen-mdl/dist
 Hash: d6cd0376242f850d00fc



[webpack-cli] configuration
The 'mode' option has not been set, webpack will fallback to 'production' for this value. Set 'mode' option to 'development' or 'production' to enable defaults for each environment.
You can also set it to 'none' to disable any default behavior. Learn more: https://webpack.js.org/configuration/mode/


[webpack-cli] Configuration ./webpack/server.mjs not found in /home/srghma/projects/purescript-halogen-mdl/webpack/server.mjs


[webpack-cli] Entry module not found: Error: Can't resolve './src' in '/home/srghma/projects/purescript-halogen-mdl'


~/projects/purescript-halogen-mdl   master ●✚  cat /home/srghma/projects/purescript-halogen-mdl/webpack/server.mjs
import merge from 'webpack-merge'
import path from 'path'

// import shared from './shared'

console.log('asdf')

export default {
  target: 'node',

  output: {
    path: path.resolve(root, 'docs'),
    filename: "server.js"
  },

  entry: path.resolve(root, "./docs-src/server.entry.js"),
}

 ~/projects/purescript-halogen-mdl   master ●✚  cat yarn.lock | grep webpack-cli
"@webpack-cli/logger@^1.0.1-alpha.4":
  resolved "https://registry.yarnpkg.com/@webpack-cli/logger/-/logger-1.0.1-alpha.4.tgz#f22b5ce6cd2f2d5089cae49583d0ee9c2de2d455"
"@webpack-cli/package-utils@^1.0.1-alpha.4":
  resolved "https://registry.yarnpkg.com/@webpack-cli/package-utils/-/package-utils-1.0.1-alpha.4.tgz#d6f8b3ef1f371a4f581c3eaf994f604942e0c0e1"
    "@webpack-cli/logger" "^1.0.1-alpha.4"
webpack-cli@beta:
  resolved "https://registry.yarnpkg.com/webpack-cli/-/webpack-cli-4.0.0-beta.8.tgz#62dfd9daaba6d46d2035f91d8aa08fda4ae2fc9f"
    "@webpack-cli/logger" "^1.0.1-alpha.4"
    "@webpack-cli/package-utils" "^1.0.1-alpha.4"

Few months later. Any update? I think supporting modules in webpack.config.js makes a lot more sense now

I had to drop webpack from one of my projects and move to rollup. There were too many invasive changes to make webpack work with "type": "module" in package.json. I would think .mjs support would be a required stepping stone to be compatible with ESM-only packages.

Edit: Back on webpack. Using --config webpack.config.cjs seems to make it work. https://github.com/webpack/webpack-cli/issues/1622#issuecomment-703114134

Was this page helpful?
0 / 5 - 0 ratings