Description
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 require
d 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 import
ed 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.