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.