Skip to content

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

Open
@JLHwung

Description

@JLHwung

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: babel/babel#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.

Metadata

Metadata

Assignees

No one assigned

    Type

    No type

    Projects

    No projects

    Milestone

    No milestone

    Relationships

    None yet

    Development

    No branches or pull requests

    Issue actions