parcel icon indicating copy to clipboard operation
parcel copied to clipboard

Transforming node:builtin to built-in when targeting commonjs

Open aminya opened this issue 2 years ago • 7 comments

🙋 feature request

Currently, Parceljs silently uses node:builtin inside commonjs although this doesn't work. There should be a transformer that converts this to normal nodejs imports when targeting commonjs.

import { execFileSync } from "node:fs"

🤔 Expected Behavior

const { execFileSync } = require("fs")

😯 Current Behavior

const { execFileSync } = require("node:fs")

💁 Possible Solution

🔦 Context

💻 Examples

aminya avatar May 03 '22 18:05 aminya

Another place where node:* specifiers aren't handled yet: https://github.com/parcel-bundler/parcel/blob/bb923d69f02612d65bc5f430a1cd2f7b21895252/packages/transformers/js/core/src/fs.rs#L54

mischnic avatar May 05 '22 08:05 mischnic

Where is the code that handles this?

aminya avatar May 26 '22 07:05 aminya

The resolver is in https://github.com/parcel-bundler/parcel/blob/v2/packages/utils/node-resolver-core/src/NodeResolver.js, search for node: in that file.

But I think there's currently no way for a resolver to say "don't bundle this dependency (so isExcluded: true), but rewrite it from node:fs to fs".

mischnic avatar May 26 '22 07:05 mischnic

Which option specifies that the target is commonjs? This line should be replaced with something like:

      filename = ifTargetCommonjs ? builtin.replace(/^node:/, "") : builtin;

https://github.com/parcel-bundler/parcel/blob/f2d0a3a27d6e493b23ddc2edbc8a4c0053ff34ab/packages/utils/node-resolver-core/src/NodeResolver.js?rgh-link-date=2022-05-26T07%3A12%3A32Z#L273

aminya avatar May 26 '22 07:05 aminya

Found a workaround using Babel using @upleveled/babel-plugin-remove-node-prefix. Add this to the babel config, and it should be transformed automatically:

babel.config.json

{
  "plugins": ["@upleveled/babel-plugin-remove-node-prefix"],
  "sourceMap": "inline"
}

aminya avatar Jul 06 '22 05:07 aminya

Unfortunately, Parcel doesn't run babel on the dependencies. I have to use something like

cross-env NODE_ENV=production babel ./dist/*.js --out-dir ./dist --retain-lines --source-maps true --plugins @upleveled/babel-plugin-remove-node-prefix --minified

This also makes the code size bloat. Babel does more than it needs to

aminya avatar Jul 06 '22 05:07 aminya

I noticed that this also doesn't work when targeting the browser. I expect Parcel use the web polyfil for such dependencies, but it instead errors out.

aminya avatar Aug 20 '22 06:08 aminya