parcel: Parcel reports "Export 'X' is not defined" if a ESM module tries to export a `function`

πŸ› bug report

If in an ESM module the export statement refers to a function, this consistently fails the build.

πŸŽ› Configuration (.babelrc, package.json, cli command)

To reproduce, clone: https://github.com/mweststrate/parcel-bug, yarn install, yarn build

This happens with an out-of-the-box configuration with parcel, no .babelrc, package.json:

{
  "name": "parcel-bug",
  "version": "1.0.0",
  "main": "index.js",
  "author": "Michel Weststrate <mweststrate@gmail.com>",
  "license": "MIT",
  "devDependencies": {
    "parcel-bundler": "^1.12.2"
  },
  "scripts": {
    "build": "parcel public/index.html"
  },
  "dependencies": {
    "immer": "^2.1.4"
  }
}

πŸ€” Expected Behavior

The project should build without error, even when an export statement references a function

😯 Current Behavior

Build failure, any referred function is reported as Export '...' is not defined

When using the immer package with parcel I consistently get the following build error:

🚨  /home/michel/Dropbox/presentaties/parcel-bug/node_modules/immer/dist/immer.module.js:1065:113: Export 'original' is not defined (1065:113)
  1063 | 
  1064 | export default produce;
> 1065 | export { produce, setAutoFreeze, setUseProxies, applyPatches$1 as applyPatches, createDraft, finishDraft, Immer, original, isDraft, isDraftable, NOTHING as nothing, DRAFTABLE as immerable };
       |                                                                                                                 ^
  1066 | 
  1067 | 

The package does bundle correctly when original, isDraft and isDraftable are removed from the export statement. Unlike all other exports, which are defined as var, these three are defined as functions in the module scope in node_modules/immer/dist/immer.module.js, like:

function original(value) {
  if (value && value[DRAFT_STATE]) {
    return value[DRAFT_STATE].base;
  } // otherwise return undefined
}

πŸ’ Possible Solution

πŸ”¦ Context

I’m converting a CRA app to parcel, however this is withholding me from that.

πŸ’» Code Sample

https://github.com/mweststrate/parcel-bug

🌍 Your Environment

Software Version(s)
Parcel 1.12.2
Node 6.4.1
npm/Yarn 1.12.3
Operating System Linux x250 4.18.0-15-generic #16-Ubuntu SMP Thu Feb 7 10:56:39 UTC 2019 x86_64 x86_64 x86_64 GNU/Linux

About this issue

  • Original URL
  • State: closed
  • Created 5 years ago
  • Reactions: 7
  • Comments: 16 (3 by maintainers)

Most upvoted comments

Following the lead from @Zero2key, the babel parser seems to be the culprit and just doing this package gets our builds working for now (as a workaround until a fix is introduced): "@babel/parser": "<7.4.0",

Confirmed that adding just the following to package.json works as a work around (not sure what other things it breaks obviously)

  "resolutions": {
    "@babel/parser": "7.3.0"
  },

Fixed in Babel 7.4.2

Just released parcel v1.12.3 which downgrades Babel to <7.4 while we figure this out.

Also got the same thing withredux :node_modules/redux/es/redux.js:636:9: Export 'createStore' is not defined (636:9)

It triggered by this line in Parcel.

Setting strictMode to null (which seems to be the default) or true works. false fails with that error.

https://github.com/parcel-bundler/parcel/blob/32f332782e830036c775dc7ad2631b5801719dc3/packages/core/parcel-bundler/src/assets/JSAsset.js#L56-L64

Reproduction using only Babel:

const parser = require("@babel/parser");

const code = `
function original(value) {
  if (value) {
    return value.base;
  }
}

export { original };
`;

console.log(parser.parse(code, {
  strictMode: false, // <-------------------- works with `true` or `null`
  sourceType: 'module',
}));

So I guess it’s a Babel bug?

There is no matching babel issue open, correct? (which isn’t strange since 7.4.0 was only released yesterday).

Also got the same thing withredux :node_modules/redux/es/redux.js:636:9: Export 'createStore' is not defined (636:9)

I lock these package version parcel used, @babel/*** < 7.4.0. Now resolve this problem. Seems @babel/***@7.4.0 problem, it have breaking change babel/babel#7646 (comment)

    "@babel/core": "<7.4.0",
    "@babel/plugin-transform-runtime": "<7.4.0",
    "@babel/preset-env": "<7.4.0",
    "@babel/code-frame": "<7.4.0",
    "@babel/generator": "<7.4.0",
    "@babel/parser": "<7.4.0",
    "@babel/plugin-transform-flow-strip-types": "<7.4.0",
    "@babel/plugin-transform-modules-commonjs": "<7.4.0",
    "@babel/plugin-transform-react-jsx": "<7.4.0",
    "@babel/template": "<7.4.0",
    "@babel/traverse": "<7.4.0",
    "@babel/types": "<7.4.0",

Same issue here:

[...]node_modules/react-router-dom/esm/react-router-dom.js:247:42: Export 'NavLink' is not defined (247:42)