what did you upgrade? don’t forget to clean and build-world whenever messing with npm packages, since npm likes to wipe your compiled ReScript dependency js artifacts.
What was the motivation of upgrading it?
It seems like they change the way how module resolution work, so there might be some changes needed in the bs-platform’s package.json as well?
Changelog: https://github.com/martpie/next-transpile-modules/releases
Besides, upgrading a package, no matter what kind of dependency, by 2 major version just asks for troubles due to breaking changes. In opam those errors are easy to spot ahead of time, but in JS there is no such guarantee.
No reason, just watching dependabot proactively, so that I can upgrade later on whenever it becomes necessary
Confirmed, when I do the following, the build gets passed bs-platform and then trips on reason-react:
cd node_modules/bs-platform && touch index.js && sed -i 's/^{/{ "main": "index.js",/' package.json
Sounds like next-transpile-modules should expose an extra parameter to explicitly provide a directory when the library is out of the user’s control. Alternatively, I could bother each rescript library author to add “main-is”…
For reference, this comment was left in a PR by the first person who started using next-transpile-modules:
we can now return a promise from getInitialProps. (trick was to ask bucklescript to output es6 and not commonjs)
I just realized that in order to update to webpack5 in NextJS we have to use the latest next-transpile-modules
as mentioned here
- When using
next-transpile-modules
make sure you use the latest version which includes this patch
Some goodies about upgrading webpack are:
- Improved Disk Caching:
next build
is significantly faster on subsequent builds- Improved Fast Refresh: Fast Refresh work is prioritized
- Improved Long Term Caching of Assets: Deterministic code output that is less likely to change between builds
- Improved Tree Shaking
- Support for assets using
new URL("file.png", import.meta.url)
- Support for web workers using
new Worker(new URL("worker.js", import.meta.url))
- Support for
exports
/imports
field inpackage.json
In this GitHub issue I reported that next-transpile-modules need rescript to have an entry point in order to be compatible with next-transpile-modules v5+. But @Hongbo stated that rescript doesn’t have the concept of entry point.
I’m a bit bummed and concerned that this might be the end of the road for a while regarding upgrading to the latest webpack v5 in NextJS.
A solution could be to fork next-transpile-modules and bend it to our needs.
Okay nice! I am interested in this. Shouldn’t be too hard to find a solution… I will have a look at it for the rescript nextjs template
@jorge I got my template working with webpack5 and next-transpile-modules
just right now.
Took me a while to understand what’s the issue, but there’s currently two things that need to be fixed:
-
As you stated correctly, the
package.json
ofbs-platform
(and@rescript/react
) needs either amain
field pointing to a file, or an emptyindex.js
within the root folder, otherwise the webpack resolver will not find the package -
There seems to be an issue with the webpack rule in
next-transpile-module
that causes webpack to not treat the packages withinlib/es6/X.js
as a esm module (Reference Error: module is not defined
). To fix this, I had to adapt the rule on line 224 to the following:
config.module.rules.push({
test: /\.+(js|jsx|mjs|ts|tsx)$/,
use: options.defaultLoaders.babel,
include: matcher,
+ type: "javascript/auto",
});
Not sure if this is a bug.
this is great to hear @ryyppy!
for #1 could it point to a readme file? or does it has to be .js
?
I think it would be misleading to point to a fake entry file. On the other hand it is important to support webpack 5.
Did you open an issue for #2?
I am honestly not sure why this is needed in the first place. next-transpile-modules
uses Webpack’s enhanced-resolve
functionality to resolve the package root dir… and for some reason it won’t recognize it if there’s not a main file (which I find surprising).
Not yet because I am not entirely sure if my change would be in the interest of the package maintainer.
I am trying to add the main and empty index.js
but I just saw that it is not only bs-platform but all the bs dependencies.
Seems like #2 is fixed in ntm
v7
Running this patch in next.config.js
gets the job done (quick and dirty).
const bsconfig = require('./bsconfig.json');
const withPlugins = require('next-compose-plugins');
const fs = require('fs');
function patchResDeps() {
['bs-platform'].concat(bsconfig['bs-dependencies']).forEach((bsDep) => {
fs.writeFileSync(`./node_modules/${bsDep}/index.js`, '');
const json = require(`./node_modules/${bsDep}/package.json`);
json.main = 'index.js';
fs.writeFileSync(
`./node_modules/${bsDep}/package.json`,
JSON.stringify(json, null, 2),
);
});
}
patchResDeps(); // update package.json and create empty `index.js` before transpiling
const transpileModules = ['bs-platform', 'three'].concat(
bsconfig['bs-dependencies'],
);
const withTM = require('next-transpile-modules')(transpileModules);
module.exports = withTM({
future: {
webpack5: true,
},
//....
})
Nice, this actually helped me upgrading the rescript-lang .org codebase to the newest ES6 module setup.
Let’s see if we can figure out a solution for the next.config.js
later on. For now this must suffice.
@ryyppy Good to hear! Nice teamwork
side-question: did you replace bs-fetch
with src/common/XmlHttpRequest.res
?
XmlHttpRequest is useful for React components with useEffect
… for fetching done on server-side, I just create an adhoc fetch binding like here.
Not sure why bs-fetch
was in there… probably forgot to remove it in the past.
I just updated to the latest next-transpile-modules@v7.1.1
without using patchResDeps
and it worked
Great! Will try it out on rescript-lang.org. If it works there, it’s certainly working for all cases.
Try upgrading next-transpile-modules by kanishka-work · Pull Request #371 · rescript-association/rescript-lang.org · GitHub - here you go.
ERR_ESM_REQUIRE - Webpack 5 config should support ESM packages · Issue #23725 · vercel/next.js · GitHub - ESM seems almost supported