Parcel: When using --experimental-scope-hoisting with Typescript, "Cannot read property 'id' of undefined" error

Created on 7 Feb 2019  路  1Comment  路  Source: parcel-bundler/parcel

馃悰 bug report

When I build my package basedirs with experimental scope hoisting, it fails with the error Cannot read property 'id' of undefined.

馃帥 Configuration (.babelrc, package.json, cli command)

馃 Expected Behavior

When I use parcel build --experimental-scope-hoisting -t node, it should build.

馃槸 Current Behavior

When I use parcel build --experimental-scope-hoisting -t node, it fails with this error:

馃毃  Cannot read property 'id' of undefined
    at replaceExportNode (basedirs/node_modules/parcel-bundler/src/scope-hoisting/concat.js:34:14)
    at ReferencedIdentifier (basedirs/node_modules/parcel-bundler/src/scope-hoisting/concat.js:317:20)
    at newFn (basedirs/node_modules/@babel/traverse/lib/visitors.js:230:17)
    at NodePath._call (basedirs/node_modules/@babel/traverse/lib/path/context.js:53:20)
    at NodePath.call (basedirs/node_modules/@babel/traverse/lib/path/context.js:40:17)
    at NodePath.visit (basedirs/node_modules/@babel/traverse/lib/path/context.js:88:12)
    at TraversalContext.visitQueue (basedirs/node_modules/@babel/traverse/lib/context.js:118:16)
    at TraversalContext.visitSingle (basedirs/node_modules/@babel/traverse/lib/context.js:90:19)
    at TraversalContext.visit (basedirs/node_modules/@babel/traverse/lib/context.js:146:19)
    at Function.traverse.node (basedirs/node_modules/@babel/traverse/lib/index.js:94:17)

馃拋 Possible Solution

Unknown. Maybe an interaction with the Typescript part of the build process?

馃敠 Context

I want to be able to produce a more minifed version of the build for npm registry publishing.

馃捇 Code Sample

馃實 Your Environment

| Software | Version(s) |
| ---------------- | ---------- |
| Parcel | v1.11.0
| Node | v8.15.0 and v11.8.0
| npm/Yarn | Yarn v1.9.4 and v1.13.0
| Operating System | macOS v10.14.2

Bug Confirmed Bug Help Wanted 馃尦 Tree Shaking

Most helpful comment

The issue seems to be that the scope hoisting logic doesn't know about the node builtin packages, that are excluded from bundling. A part of the fix is this (and imports need to be rewritten to require), but the require calls need to be excluded as well:

diff --git a/packages/core/parcel-bundler/src/scope-hoisting/hoist.js b/packages/core/parcel-bundler/src/scope-hoisting/hoist.js
index 0f5b9af0..0e068495 100644
--- a/packages/core/parcel-bundler/src/scope-hoisting/hoist.js
+++ b/packages/core/parcel-bundler/src/scope-hoisting/hoist.js
@@ -4,6 +4,7 @@ const t = require('@babel/types');
 const template = require('@babel/template').default;
 const rename = require('./renamer');
 const {getName, getIdentifier, getExportIdentifier} = require('./utils');
+const nodeBuiltins = require('node-libs-browser');

 const WRAPPER_TEMPLATE = template(`
   var NAME = (function () {
@@ -344,6 +345,10 @@ module.exports = {
   },

   ImportDeclaration(path, asset) {
+    if (asset.options.target === 'node' && path.node.source.value in nodeBuiltins) {
+      return;
+    }
+
     // For each specifier, rename the local variables to point to the imported name.
     // This will be replaced by the final variable name of the resolved asset in the packager.
     for (let specifier of path.node.specifiers) {

>All comments

The issue seems to be that the scope hoisting logic doesn't know about the node builtin packages, that are excluded from bundling. A part of the fix is this (and imports need to be rewritten to require), but the require calls need to be excluded as well:

diff --git a/packages/core/parcel-bundler/src/scope-hoisting/hoist.js b/packages/core/parcel-bundler/src/scope-hoisting/hoist.js
index 0f5b9af0..0e068495 100644
--- a/packages/core/parcel-bundler/src/scope-hoisting/hoist.js
+++ b/packages/core/parcel-bundler/src/scope-hoisting/hoist.js
@@ -4,6 +4,7 @@ const t = require('@babel/types');
 const template = require('@babel/template').default;
 const rename = require('./renamer');
 const {getName, getIdentifier, getExportIdentifier} = require('./utils');
+const nodeBuiltins = require('node-libs-browser');

 const WRAPPER_TEMPLATE = template(`
   var NAME = (function () {
@@ -344,6 +345,10 @@ module.exports = {
   },

   ImportDeclaration(path, asset) {
+    if (asset.options.target === 'node' && path.node.source.value in nodeBuiltins) {
+      return;
+    }
+
     // For each specifier, rename the local variables to point to the imported name.
     // This will be replaced by the final variable name of the resolved asset in the packager.
     for (let specifier of path.node.specifiers) {
Was this page helpful?
0 / 5 - 0 ratings