Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

__non_webpack_require__ incompatible with experiments.outputModule + devtool: 'eval-source-map' #17971

Open
cmfcmf opened this issue Jan 16, 2024 · 5 comments
Labels

Comments

@cmfcmf
Copy link

cmfcmf commented Jan 16, 2024

Bug report

What is the current behavior?

When using experiments.outputModule = true in combination with __non_webpack_require__ and devtool: 'eval-source-map' (or any other of the eval-based devtools), then you get Error: Cannot use 'import.meta' outside a module when trying to run the bundled file. This is because import.meta is accessed in the code that is passed as a string to eval, which does not have access to import.meta.

If the current behavior is a bug, please provide the steps to reproduce.

Full minimal sample project: https://stackblitz.com/edit/github-qjzdxl?file=webpack.config.cjs&view=editor

Run npm install && npm run build && npm run start to get the error.

Important files:

  • package.json which specifies type: "module"
  • webpack.config.cjs:
      const path = require('path');
      
      module.exports = {
        entry: './src/index.js',
        devtool: 'eval-source-map',
        output: {
          filename: 'main.js',
          path: path.resolve(__dirname, 'dist'),
        },
        experiments: {
          outputModule: true,
        },
        optimization: {
          minimize: false,
        },
      };
  • src/index.js:
      __non_webpack_require__('path');
      console.log('it worked');

What is the expected behavior?

Webpack should use a different mechanism to access import.meta when using an eval-based devtool that avoids accessing import.meta inside of strings passed to eval. Running the compiled file should print it worked to the console.

Other relevant information:
webpack version: 5.89.0
Node.js version: 18.18.0
Operating System: Linux
Additional tools: None

@alexander-akait
Copy link
Member

Yeah, not sure how we can solve it, because we need import.meta.url for https://nodejs.org/api/module.html#modulecreaterequirefilename, I want to say it is a limitation, why do not use createRequire in code?

@cmfcmf
Copy link
Author

cmfcmf commented Jan 21, 2024

I am unable to use createRequire, because I'd need import.meta.url for it:

Input:

const path = require('path');

module.exports = {
  entry: './src/index.js',
  devtool: 'eval-source-map',
  target: 'node18',
  externalsPresets: { node: true },
  output: {
    filename: 'main.js',
    path: path.resolve(__dirname, 'dist'),
  },
  experiments: {
    outputModule: true,
  },
  optimization: {
    minimize: false,
  },
};
import * as module from 'node:module';

const customRequire = module.createRequire(import.meta.url);
customRequire('something');

Output:

/*
 * ATTENTION: An "eval-source-map" devtool has been used.
 * This devtool is neither made for production nor for readable output files.
 * It uses "eval()" calls to create a separate source file with attached SourceMaps in the browser devtools.
 * If you are trying to read the output file, select a different devtool (https://webpack.js.org/configuration/devtool/)
 * or disable the default devtool with "devtool: false".
 * If you are looking for production-ready output files, see mode: "production" (https://webpack.js.org/configuration/mode/).
 */
import { createRequire as __WEBPACK_EXTERNAL_createRequire } from "module";
/******/ var __webpack_modules__ = ({

/***/ 590:
/***/ (() => {

eval("\n;// CONCATENATED MODULE: external \"node:module\"\nconst external_node_module_namespaceObject = __WEBPACK_EXTERNAL_createRequire(import.meta.url)(\"node:module\");\n;// CONCATENATED MODULE: ./src/index.js\n\n\nconst customRequire = external_node_module_namespaceObject.createRequire(\"file:///home/projects/github-qjzdxl/src/index.js\");\ncustomRequire('something');\n//# sourceURL=[module]\n//# sourceMappingURL=data:application/json;charset=utf-8;base64,eyJ2ZXJzaW9uIjozLCJmaWxlIjoiNTkwLmpzIiwibWFwcGluZ3MiOiI7O0FBQUEsTUFBTSxvQ0FBNEIsb0U7O0FDQUk7O0FBRXRDLHNCQUFzQixrREFBb0IsQ0FBQyxrREFBZTtBQUMxRCIsInNvdXJjZXMiOlsid2VicGFjazovL2dldHRpbmctc3RhcnRlZC11c2luZy1hLWNvbmZpZ3VyYXRpb24vZXh0ZXJuYWwgbm9kZS1jb21tb25qcyBcIm5vZGU6bW9kdWxlXCI/YTRiNSIsIndlYnBhY2s6Ly9nZXR0aW5nLXN0YXJ0ZWQtdXNpbmctYS1jb25maWd1cmF0aW9uLy4vc3JjL2luZGV4LmpzPzg4YjciXSwic291cmNlc0NvbnRlbnQiOlsiY29uc3QgX19XRUJQQUNLX05BTUVTUEFDRV9PQkpFQ1RfXyA9IF9fV0VCUEFDS19FWFRFUk5BTF9jcmVhdGVSZXF1aXJlKGltcG9ydC5tZXRhLnVybCkoXCJub2RlOm1vZHVsZVwiKTsiLCJpbXBvcnQgKiBhcyBtb2R1bGUgZnJvbSAnbm9kZTptb2R1bGUnO1xuXG5jb25zdCBjdXN0b21SZXF1aXJlID0gbW9kdWxlLmNyZWF0ZVJlcXVpcmUoaW1wb3J0Lm1ldGEudXJsKTtcbmN1c3RvbVJlcXVpcmUoJ3NvbWV0aGluZycpO1xuIl0sIm5hbWVzIjpbXSwic291cmNlUm9vdCI6IiJ9\n//# sourceURL=webpack-internal:///590\n");

/***/ })

/******/ });
/************************************************************************/
/******/ 
/******/ // startup
/******/ // Load entry module and return exports
/******/ // This entry module can't be inlined because the eval-source-map devtool is used.
/******/ var __webpack_exports__ = {};
/******/ __webpack_modules__[590]();
/******/ 

As you can see, this still leads to import.meta.url being used inside of eval and the actual import.meta.url being replaced with a hard-coded filepath.

@alexander-akait
Copy link
Member

I see...

@webpack-bot
Copy link
Contributor

This issue had no activity for at least three months.

It's subject to automatic issue closing if there is no activity in the next 15 days.

@alexander-akait
Copy link
Member

bump

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
Projects
Status: Priority - High
Development

No branches or pull requests

3 participants