2

I have some functions in a javascript file (helpers.js) that are imported into a react file (caller.jsx).

helpers.js:

async function one() {
  // ...
}

function two() {
  // ...
}

module.exports = { one, two }

caller.jsx:

const { one, two } = require("../utils/helpers")

When I run my local React server (npm run start), everything works fine. I can use the app and it works.

When I run a production build (npm run build) and serve up the javascript from that build, it doesn't work, and there's an error message in the console:

main.d780c23e.chunk.js:1 Uncaught TypeError: Cannot assign to read only property 'exports' of object '#<Object>'
    at Module.<anonymous> (main.d780c23e.chunk.js:1)
    at Module.228 (main.d780c23e.chunk.js:1)
    at i ((index):3)
    at Module.375 (main.d780c23e.chunk.js:1)
    at i ((index):3)
    at t ((index):3)
    at Array.r [as push] ((index):3)
    at main.d780c23e.chunk.js:1

And the compiled code in the browser shows the problem at the exports of helpers.js, right at the equals sign (=):

            b.exports = {
                one: function() { ... },
                two: function() { ... }
                }
            }

I have also tried importing the symbols in caller.jsx:

import { one, two } from "../utils/helpers"

In that case, the production build complains that the symbol is not exported.

./src/hooks/caller.jsx
Attempted import error: 'two' is not exported from '../utils/helpers'.

And if I delete two, then it complains about one.

It seems the CommonJS style of code (with module.exports) isn't working in the ESModule style of code (with import).

However, I have some other files (call them caller2.jsx and helper2.js) where it is working for helper2.js to use module.export and caller2.jsx to use an import statement.

I am flummoxed about how to tell what's going in.

It IS exported, damnit! Why does only the production compiler say it's not?

Versions: node v16.10.0, npm 7.24.0, react 17.0.2, react-scripts 4.0.3.

EDIT: Some build info: we build using npm. Here are the scripts in package.json:

"scripts": {
    "start": "react-scripts start",
    "build": "react-scripts build"
}

As an example, here is the full output of build:

$ npm run build

> myapp@0.1.0 build
> react-scripts build

Creating an optimized production build...
Compiled successfully.

File sizes after gzip:

  421.79 KB        build/static/js/2.9462f3d3.chunk.js
  23.57 KB         build/static/css/2.0a9ec390.chunk.css
  20.85 KB (+1 B)  build/static/js/main.2d21dfa5.chunk.js
  2.49 KB          build/static/css/main.8d569477.chunk.css
  1.73 KB          build/static/js/3.2618e91d.chunk.js
  1.17 KB          build/static/js/runtime-main.2616b467.js

The project was built assuming it is hosted at /.
You can control this with the homepage field in your package.json.

EDIT 2: We are using hardhat, so we cannot use ESModule exports. See for example this github issue, or this stackoverflow question.

Bergi
  • 630,263
  • 148
  • 957
  • 1,375
dfrankow
  • 20,191
  • 41
  • 152
  • 214
  • https://flaviocopes.com/cannot-assign-readonly-property-export/ try and export them the es Modules way? – Dan Dec 14 '21 at 23:08
  • 1
    *How* are you building and bundling your modules? Please mention the tooling you use and post its configuration, including what the difference between the `start` and `build` commands is. – Bergi Dec 14 '21 at 23:14
  • @Dan we cannot export because the helpers must be accessible in hardhat, which doesn't support esmodules. I'd link info on that, but I'm on my phone. – dfrankow Dec 15 '21 at 00:33
  • @Bergi - We build with npm. Added the "start" and "build" targets in package.json above: `react-scripts start` and `react-scripts build`, standard stuff. – dfrankow Dec 15 '21 at 00:36
  • @dfrankow I think what Bergi@ means by building is how are you creating assets for distribution? for example: WebPack is tool which can be used for the same. along the same lines, you must be using some tool for bundling. – AppleCiderGuy Dec 15 '21 at 00:52
  • @appleciderguy I don't believe so. I think react-build looks to be using webpack under the hood, but I can't tell how. I pasted the entire output of the build above. – dfrankow Dec 15 '21 at 01:16
  • The issue got closed, without being resolved. But could you confirm if removing the async syntax from the export makes it work in production? https://github.com/facebook/create-react-app/issues/8555 – Dan Dec 15 '21 at 01:41
  • Does this help at all https://hardhat.org/guides/typescript.html ? – segFault Dec 15 '21 at 02:49
  • @Dan That is an amazing find. It looks so relevant. Sadly, I removed all "async" keywords from the helpers file, and I still get the issue. I may spend some time tomorrow trying to make a simpler test case. – dfrankow Dec 15 '21 at 04:12
  • @segFault Thank you for your thoughts. You are suggesting perhaps we could convert all of this (helpers.js and hardhat code) to typescript? Perhaps, but that is fairly drastic. I might convert hundreds of lines of code and still not have something that compiles. – dfrankow Dec 15 '21 at 04:15
  • @Dan When I greatly simplified the file, it wouldn't build until I took out every "async" (said one of the functions wasn't exported). I think this may be a part of the answer. But then .. what do I do? Maybe make two versions of the file, one with CommonJS exports for hardhat, and one with ESModule exports for React? – dfrankow Dec 15 '21 at 04:23
  • 1
    FYI I ended up making a dastardly hack to produce two versions of the file, one for React and one for hardhat. This seems like a task for Babel, but that wasn't working well because of some other Javascript hell, so I just wrote my own script. – dfrankow Dec 15 '21 at 21:58

0 Answers0