With preconstruct dev, using import.meta.url results in SyntaxError: Cannot use 'import.meta' outside a module when loaded in Node.
With preconstruct build, import.meta.url is transformed to the following in the CommonJS output, which loads just fine:
(typeof document === 'undefined' ? new (require('u' + 'rl').URL)('file:' + __filename).href : (document.currentScript && document.currentScript.src || new URL('dist/{outputName}.js', document.baseURI).href))
I figure that in the case of preconstruct build, Rollup is doing the transform, while with preconstruct dev Babel is the only thing transforming the code, leaving import.meta.url untouched. It seems Babel with @babel/plugin-transform-modules-commonjs is like this by design:
babel/babel#9299 (comment)
If you want to transform it, you'll need another plugin (that we don't offically provide because the spec doesn't say what should there be inside that object).
babel-plugin-transform-import-meta partially resolves the issue. It allows consuming the module as CommonJS, but due to how Babel must be configured with Preconstruct, adding it to the Babel config breaks other build types. Since the Babel config applies to ALL build types including ESM, the transform applies to the ESM output, where __filename is invalid. Thus, the following error happens when the ESM build is loaded in Node: ReferenceError: __filename is not defined in ES module scope.
Would it make sense for Preconstruct to support using import.meta.url with preconstruct dev by adding babel-plugin-transform-import-meta in the Babel config used in the require hook? I did a quick test and it seems both preconstruct dev and preconstruct build work fine as a result.
With
preconstruct dev, usingimport.meta.urlresults inSyntaxError: Cannot use 'import.meta' outside a modulewhen loaded in Node.With
preconstruct build,import.meta.urlis transformed to the following in the CommonJS output, which loads just fine:I figure that in the case of
preconstruct build, Rollup is doing the transform, while withpreconstruct devBabel is the only thing transforming the code, leavingimport.meta.urluntouched. It seems Babel with@babel/plugin-transform-modules-commonjsis like this by design:babel/babel#9299 (comment)
babel-plugin-transform-import-metapartially resolves the issue. It allows consuming the module as CommonJS, but due to how Babel must be configured with Preconstruct, adding it to the Babel config breaks other build types. Since the Babel config applies to ALL build types including ESM, the transform applies to the ESM output, where__filenameis invalid. Thus, the following error happens when the ESM build is loaded in Node:ReferenceError: __filename is not defined in ES module scope.Would it make sense for Preconstruct to support using
import.meta.urlwithpreconstruct devby addingbabel-plugin-transform-import-metain the Babel config used in the require hook? I did a quick test and it seems bothpreconstruct devandpreconstruct buildwork fine as a result.