vuejs / vue-cli

🛠️ webpack-based tooling for Vue.js Development
https://cli.vuejs.org/
MIT License
29.76k stars 6.33k forks source link

vue-server-renderer can not import @babel/runtime esm helpers #6018

Open JLHwung opened 3 years ago

JLHwung commented 3 years ago

Version

3.4.0

Although I did not verify that whether the issue can be reproduced on latest version, I believe it is reproducible on latest dev branch according to the execution path analysis below.

Reproduction link

https://github.com/sns45/esm-issue

Environment info

  System:
    OS: macOS 10.15.7
  Binaries:
    Node: 15.0.1 - /usr/local/bin/node
    Yarn: 1.22.10 - /usr/local/bin/yarn
    npm: 7.0.3 - /usr/local/bin/npm

Steps to reproduce

npm install
npm run build
npm run start

visit http://localhost:8080

What is expected?

undefined is printed to HTML

What is actually happening?

error stack is printed:

Error [ERR_REQUIRE_ESM]: Must use import to load ES Module: /path/to/esm-issue/node_modules/@babel/runtime-corejs2/helpers/esm/arrayWithHoles.js
require() of ES modules is not supported.
require() of /path/to/esm-issue/node_modules/@babel/runtime-corejs2/helpers/esm/arrayWithHoles.js from /path/to/esm-issue/node_modules/vue-server-renderer/build.prod.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 arrayWithHoles.js to end in .cjs, change the requiring code to use import(), or remove "type": "module" from /path/to/esm-issue/node_modules/@babel/runtime-corejs2/helpers/esm/package.json.

    at new NodeError (node:internal/errors:258:15)
    at Object.Module._extensions..js (node:internal/modules/cjs/loader:1100:13)
    at Module.load (node:internal/modules/cjs/loader:948:32)
    at Function.Module._load (node:internal/modules/cjs/loader:789:14)
    at Module.require (node:internal/modules/cjs/loader:972:19)
    at require (node:internal/modules/cjs/helpers:88:18)
    at /path/to/esm-issue/node_modules/vue-server-renderer/build.prod.js:4564:15
    at Object.88c0 (js/main.b4608c10.js:1:5367)
    at r (webpack/bootstrap:33:22)
    at Module.0419 (js/main.b4608c10.js:1:3869)

Context: https://github.com/babel/babel/issues/12223

Technically it is an integration issue between @vue/babel-preset-app and vue-server-renderer.

@vue/babel-preset-app instructs @babel/transform-runtime to use esmodules: true for runtime imports. That means if we have a JS file for example,

const a = [...b]

it will be transformed by babel to

import "@babel/runtime-corejs2@7.12.1/helpers/esm/arrayWithHoles"
const a = [...b]

and then transformed by webpack (we specifies output.library = "commonjs2") to

require("@babel/runtime-corejs2@7.12.1/helpers/esm/arrayWithHoles")
const a = [...b]

When the transformed result are required from vue-server-renderer, the error will be thrown because "@babel/runtime-corejs2@7.12.1/helpers/esm" is an es module thus meant to be imported only.

Workaround: Users can workaround this issue by specifying VUE_CLI_BABEL_TRANSPILE_MODULES=true in server build scripts:

{
  "build:server": "cross-env WEBPACK_TARGET=node VUE_CLI_BABEL_TRANSPILE_MODULES=true vue-cli-service build"
}

Suggested Action: I am aware that vue-server-render may not support esm soon because vm modules are still experimental as of node.js 15.0. It will be great if @vue/babel-preset-app can acknowledge the server rendering use cases and avoid esmodules: true until sever-renderer supports ES module.

sns45 commented 3 years ago

This is also reproducible in the latest version of vue-cli-4. Repo: https://github.com/sns45/esm-issue/tree/vue-cli-4

npm install
npm run build
npm run start
phil294 commented 3 years ago

As pointed out by auven here, this can be worked around with babel.config.js:

module.exports = {
  presets: [
    // '@vue/cli-plugin-babel/preset'
    [
      '@vue/cli-plugin-babel/preset',
      {
        useBuiltIns: 'entry'
      }
    ]
  ]
}

I doubt this will be helpful to anyone, but just in case: In my case, the error was not triggered by the inclusion of @vue/cli-plugin-babel, but by a webpack tapping for piping transpiled coffeescript output through babel, and also only after some recent package upgrade.

relevant part of vue.config.js ``` config.module .rule('coffee') .after('vue') .test(/\.coffee$/) .use('coffee/babel') .loader('babel-loader') // <----------- .end() .use('coffee/loader') .loader('coffee-loader') .end() ```
LeonAlvarez commented 3 years ago

Getting similar error on Error [ERR_REQUIRE_ESM]: Must use import to load ES Module: ...t/node_modules/@babel/runtime/helpers/esm/defineProperty.js Any update on this, for me the sugestion didnt fix it (build but get a blank page)

kimmy-wang commented 2 years ago

same issue. Any updates? @sodatea

internal/modules/cjs/loader.js:1015
      throw new ERR_REQUIRE_ESM(filename, parentPath, packageJsonPath);
      ^

Error [ERR_REQUIRE_ESM]: Must use import to load ES Module: /Users/ying/workspace/FEProjects/vue3-node-boilerplate/node_modules/@babel/runtime/helpers/esm/objectSpread2.js
require() of ES modules is not supported.
require() of /Users/ying/workspace/FEProjects/vue3-node-boilerplate/node_modules/@babel/runtime/helpers/esm/objectSpread2.js from /Users/ying/workspace/FEProjects/vue3-node-boilerplate/dist/node/js/admin.5e0dffa7.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 objectSpread2.js to end in .cjs, change the requiring code to use import(), or remove "type": "module" from /Users/ying/workspace/FEProjects/vue3-node-boilerplate/node_modules/@babel/runtime/helpers/esm/package.json.

    at Object.Module._extensions..js (internal/modules/cjs/loader.js:1015:13)
    at Module.load (internal/modules/cjs/loader.js:863:32)
    at Function.Module._load (internal/modules/cjs/loader.js:708:14)
    at Module.require (internal/modules/cjs/loader.js:887:19)
    at require (internal/modules/cjs/helpers.js:74:18)
    at Object.193e (/Users/ying/workspace/FEProjects/vue3-node-boilerplate/dist/node/js/admin.5e0dffa7.js:4902:18)
    at __webpack_require__ (/Users/ying/workspace/FEProjects/vue3-node-boilerplate/dist/node/js/admin.5e0dffa7.js:21:30)
    at Module.f23d (/Users/ying/workspace/FEProjects/vue3-node-boilerplate/dist/node/js/admin.5e0dffa7.js:65702:22)
    at __webpack_require__ (/Users/ying/workspace/FEProjects/vue3-node-boilerplate/dist/node/js/admin.5e0dffa7.js:21:30)
    at Object.3830 (/Users/ying/workspace/FEProjects/vue3-node-boilerplate/dist/node/js/admin.5e0dffa7.js:14045:24)
    at __webpack_require__ (/Users/ying/workspace/FEProjects/vue3-node-boilerplate/dist/node/js/admin.5e0dffa7.js:21:30)
    at Object.d2ac (/Users/ying/workspace/FEProjects/vue3-node-boilerplate/dist/node/js/admin.5e0dffa7.js:52613:41)
    at __webpack_require__ (/Users/ying/workspace/FEProjects/vue3-node-boilerplate/dist/node/js/admin.5e0dffa7.js:21:30)
    at Object.7ad8 (/Users/ying/workspace/FEProjects/vue3-node-boilerplate/dist/node/js/admin.5e0dffa7.js:29343:15)
    at __webpack_require__ (/Users/ying/workspace/FEProjects/vue3-node-boilerplate/dist/node/js/admin.5e0dffa7.js:21:30)
    at Object.c60b (/Users/ying/workspace/FEProjects/vue3-node-boilerplate/dist/node/js/admin.5e0dffa7.js:47138:17) {
  code: 'ERR_REQUIRE_ESM'
}