Coder Social home page Coder Social logo

browserify / common-shakeify Goto Github PK

View Code? Open in Web Editor NEW
104.0 4.0 18.0 160 KB

browserify tree shaking plugin using `common-shake`

Home Page: https://www.npmjs.com/package/common-shakeify

License: MIT License

JavaScript 100.00%
browserify tree-shaking commonjs browserify-plugin

common-shakeify's Introduction

common-shakeify

browserify tree shaking plugin based on common-shake, the CommonJS tree shaker originally by @indutny.

Comments out unused exports from CommonJS modules.

With input files:

// math.js
exports.min = function (a, b) { return a < b ? a : b }
exports.max = function (a, b) { return a < b ? b : a }

// app.js
var math = require('./math')
console.log(math.max(10, 20))

This plugin will rewrite the files to:

// math.js
/* common-shake removed: exports.min = */ void function (a, b) { return a < b ? a : b }
exports.max = function (a, b) { return a < b ? b : a }

// app.js
var math = require('./math')
console.log(math.max(10, 20))

Use a minifier on the output to remove the exports entirely.

Install

npm install --save-dev common-shakeify

Usage

With the browserify cli:

browserify -p common-shakeify /my/app.js > bundle.js
# Minify
uglify-js bundle.js --compress > bundle.min.js

With the browserify Node API:

var commonShake = require('common-shakeify')

var b = browserify({ entries: '/my/app.js' })
  .plugin(commonShake, { /* options */ })
  .bundle()

// Minify & save
var uglify = require('minify-stream')
b
  .pipe(uglify())
  .pipe(fs.createWriteStream('bundle.min.js'))

Note that using a minifier transform like uglifyify doesn't eliminate the commented-out exports. Transforms run before common-shakeify, so you have to use a minifier on the final bundle to remove the unused exports.

Options

verbose, v

When true, print messages to stderr when exports are deleted, or the tree-shaker bails out on a module. Default false. The verbose flag only works when no custom handlers are passed, so if you're using eg. a custom onExportDelete you have to print these messages manually.

$ browserify -p [ common-shakeify -v ] app.js > bundle.js
common-shake: removed `decode` in node_modules/vlq/dist/vlq.js:10:7
common-shake: bailed out: `module.exports` assignment in node_modules/process-nextick-args/index.js:20:3

onExportDelete(filename, exportName)

Handler called for every exported identifier that is being removed. filename is the path to the file that exports the identifier. exportName is the name of the identifier. Return false to bail and keep the identifier.

onModuleBailout(module, reasons)

Handler called when a module cannot be tree-shaked for some reason. module is the Module object from common-shake. reasons is an array of reasons that caused this module to be deoptimised.

onGlobalBailout(reasons)

Handler called when tree-shaking is skipped entirely, usually because there is a dynamic require call in the source. reasons is an array of reasons for skipping tree-shaking.

ecmaVersion

Parse with this ecmaVersion as interpreted by acorn. (default: 10)

License

MIT

common-shakeify's People

Contributors

dependabot[bot] avatar dy avatar goto-bus-stop avatar josephg avatar pirxpilot avatar ralphtheninja avatar tornqvist avatar wooorm avatar

Stargazers

 avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar

Watchers

 avatar  avatar  avatar  avatar

common-shakeify's Issues

Verbose mode throws an error when --full-paths flag is not used

In verbose mode, the call to path.relative throws an error when --full-paths flag is not used. This is because the module name will be a number.

https://github.com/browserify/common-shakeify/blob/master/index.js#L30

Example:

$ browserify -g [ loose-envify purge --NODE_ENV production ] -p [ esmify ] -p [ common-shakeify -v ] -t babelify ./lib/index.js -o ./build/index.prod.js

internal/validators.js:112
    throw new ERR_INVALID_ARG_TYPE(name, 'string', value);
    ^

TypeError [ERR_INVALID_ARG_TYPE]: The "to" argument must be of type string. Received type number
    at validateString (internal/validators.js:112:11)
    at Object.relative (path.js:1054:5)
    at /node_modules/common-shakeify/index.js:33:83
    at Array.forEach (<anonymous>)
    at Object.onModuleBailout (/node_modules/common-shakeify/index.js:28:17)
    at /node_modules/common-shakeify/index.js:152:14
    at Map.forEach (<anonymous>)
    at DestroyableTransform.onend [as _flush] (/node_modules/common-shakeify/index.js:140:22)
    at DestroyableTransform.prefinish (/node_modules/readable-stream/lib/_stream_transform.js:138:10)
    at DestroyableTransform.emit (events.js:223:5) {

does not remove imports that belongs to dead code which is removed by common-shake

Thanks for the efforts. This plugin works great. I will try to explain the case i came across.

"index.es6" imports {Storage} from "abc" which intern import {Cookie} from "xyz".
"abc" is using {Cookie} from "xyz". But Index.es6 is not using {Storage} from "abc". Now common-shake is removing {Storage} from the code but {Cookie} remains in the output file. If I remove reference to {Cookie} from abc then common-shake is removing {Cookie} as well.

Here is the file structure

index.es6

import {Storage} from "./abc";
console.log("this is an example");

abc.es6

import {Cookie} from "./xyz";

export var Storage = function(){
}
Storage.prototype = {
  getCookie: function(){
    let cookie = new Cookie(); // if i remove this line then common-shake removes Cookie from the output
  }
}

xyz.es6

export var Cookie= function(){
}

Cookie.prototype = {
  readCookie: function(){
     console.log("reading cookie");
  }
}

v1.1 has a bug compared to v0 and v1.0: require can't take a number

I get this error output in my tests:

  node:internal/validators:114
    throw new ERR_INVALID_ARG_TYPE(name, 'string', value);
    ^

TypeError [ERR_INVALID_ARG_TYPE]: The "id" argument must be of type string. Received type number (298)
    at new NodeError (node:internal/errors:388:5)
    at validateString (node:internal/validators:114:11)
    at Module.require (node:internal/modules/cjs/loader:1005:3)
    at require (node:internal/modules/cjs/helpers:102:18)

I suspect this was introduced in #31.

Name is too long

Should've been "shakeify". Browserify is already just commonjs, so the "common" is unnecessary.

require('os') is broken

// a.js
var _ = require('./b')
// b.js
exports.a = exports.b = function () {}

browserify -p common-shakeify a.js produces

(function(){function r(e,n,t){function o(i,f){if(!n[i]){if(!e[i]){var c="function"==typeof require&&require;if(!f&&c)return c(i,!0);if(u)return u(i,!0);var a=new Error("Cannot find module '"+i+"'");throw a.code="MODULE_NOT_FOUND",a}var p=n[i]={exports:{}};e[i][0].call(p.exports,function(r){var n=e[i][1][r];return o(n||r)},p,p.exports,r,e,n,t)}return n[i].exports}for(var u="function"==typeof require&&require,i=0;i<t.length;i++)o(t[i]);return o}return r})()({1:[function(require,module,exports){
/* common-shake removed: exports.a = */ /* common-shake removed: exports.b = */ function () {}

},{}],2:[function(require,module,exports){
var a = require( './b' )

},{"./b":1}]},{},[2]);

Which is Uncaught SyntaxError: Unexpected token (.

Because we can't just do function () {} in javascript.

@goto-bus-stop

typedarray-pool is broken

Stumbled upon this in tinyify not working in dy/budo. typedarray-pool turned out to not shake properly.

The bug case:

// a.js
exports.x0 =
exports.x1 =
exports.x2 = function () {}
// b.js
require('./a').x0()

Produces

(function(){function r(e,n,t){function o(i,f){if(!n[i]){if(!e[i]){var c="function"==typeof require&&require;if(!f&&c)return c(i,!0);if(u)return u(i,!0);var a=new Error("Cannot find module '"+i+"'");throw a.code="MODULE_NOT_FOUND",a}var p=n[i]={exports:{}};e[i][0].call(p.exports,function(r){var n=e[i][1][r];return o(n||r)},p,p.exports,r,e,n,t)}return n[i].exports}for(var u="function"==typeof require&&require,i=0;i<t.length;i++)o(t[i]);return o}return r})()({1:[function(require,module,exports){
exports.x0 =
/* common-shake removed: exports.x1 = */ void 0, /* common-shake removed: exports.x2 = */ function () {}

},{}],2:[function(require,module,exports){
require('./a').x0()

},{"./a":1}]},{},[2]);

exports.x0 here === void 0

@goto-bus-stop

invalid output

fails on the ssr test in bankai

input:

var html = require('choo/html')
var choo = require('choo')

var app = choo()
app.route('/', function () {
  return html`<body>meow</body>`
})
if (module.parent) module.exports = app
else app.mount('body')

this is uglified first among other things, and causes invalid output from common-shakeify

Updating `@babel/core` to version 7.22.15+ shakes out needed exports

Running the following code results in a TypeError: (0 , _$b_2.fn3) is not a function error.

index.js

import { fn1 } from './a';

fn1();

a.js

import { fn3 } from './b';

export const fn2 = () => {
    fn3();
};

export const fn1 = () => {
    fn2();
};

b.js

export const fn3 = () => {};

It could be related to the way exports are transpiled, it changed from this:

exports.var = var;
var fn = function fn(arg) {

To this:

var fn = exports.fn = function fn(arg) {
@babel/core 7.22.11
(function(){function r(e,n,t){function o(i,f){if(!n[i]){if(!e[i]){var c="function"==typeof require&&require;if(!f&&c)return c(i,!0);if(u)return u(i,!0);var a=new Error("Cannot find module '"+i+"'");throw a.code="MODULE_NOT_FOUND",a}var p=n[i]={exports:{}};e[i][0].call(p.exports,function(r){var n=e[i][1][r];return o(n||r)},p,p.exports,r,e,n,t)}return n[i].exports}for(var u="function"==typeof require&&require,i=0;i<t.length;i++)o(t[i]);return o}return r})()({1:[function(require,module,exports){
"use strict";

Object.defineProperty(exports, "__esModule", {
  value: true
});
/* common-shake removed: exports.fn2 = */ exports.fn1 = void 0;
var _b = require("./b");
var fn2 = function fn2() {
  (0, _b.fn3)();
};
/* common-shake removed: exports.fn2 = */ void fn2;
var fn1 = function fn1() {
  fn2();
};
exports.fn1 = fn1;

},{"./b":2}],2:[function(require,module,exports){
"use strict";

Object.defineProperty(exports, "__esModule", {
  value: true
});
exports.fn3 = void 0;
var fn3 = function fn3() {};
exports.fn3 = fn3;

},{}],3:[function(require,module,exports){
"use strict";

var _a = require("./a");
(0, _a.fn1)();

},{"./a":1}]},{},[3])
@babel/core 7.22.15
(function(){function r(e,n,t){function o(i,f){if(!n[i]){if(!e[i]){var c="function"==typeof require&&require;if(!f&&c)return c(i,!0);if(u)return u(i,!0);var a=new Error("Cannot find module '"+i+"'");throw a.code="MODULE_NOT_FOUND",a}var p=n[i]={exports:{}};e[i][0].call(p.exports,function(r){var n=e[i][1][r];return o(n||r)},p,p.exports,r,e,n,t)}return n[i].exports}for(var u="function"==typeof require&&require,i=0;i<t.length;i++)o(t[i]);return o}return r})()({1:[function(require,module,exports){
"use strict";

Object.defineProperty(exports, "__esModule", {
  value: true
});
/* common-shake removed: exports.fn2 = */ exports.fn1 = void 0;
var _b = require("./b");
var fn2 = /* common-shake removed: exports.fn2 = */ function fn2() {
  (0, _b.fn3)();
};
var fn1 = exports.fn1 = function fn1() {
  fn2();
};

},{"./b":2}],2:[function(require,module,exports){
"use strict";

Object.defineProperty(exports, "__esModule", {
  value: true
});
/* common-shake removed: exports.fn3 = */ void void 0;
var fn3 = /* common-shake removed: exports.fn3 = */ function fn3() {};

},{}],3:[function(require,module,exports){
"use strict";

var _a = require("./a");
(0, _a.fn1)();

},{"./a":1}]},{},[3])

remove unused modules if they have sideEffects: false

Following from #17, although we can't remove unused modules in the general case, if something does

var _ = require('lodash')
exports.a = function () { /* something not using lodash */ }
exports.b = function (x) { _.map(x, /* etc */) }

and you're not using exports.b, exports.b will be dropped, lodash becomes unused, and we can check the lodash package.json file to see that it is safe to remove the require() call.

So this is intended to address the case where all uses of a module have been shaken out, not for the case where it's not used in the first place—then it might be a polyfill or something.

Bundle not tree-shaked even in the most simple use case

Here is a super simple package.js script:

var iconv = require('iconv-lite');

console.warn('We are not using iconv at all!');

As you can see, iconv is never used.

Using the CLI command of the documentation browserify -p [common-shakeify -v] package.js > bundle.js, the final bundle is not tree-shaked. There is only one common-shake comment in the generated bundle:

/* common-shake removed: exports.byteLength = */

I expect the whole iconv module to be removed since it is not used at all.

shakes out functions that I used

I'm not sure if this plugin in production ready yet, but it seems that it removed functions that I'm definitely using.

Using import to get the modules, but running babel as a browserify transform, so that should rewrite everything to require.

seems that most of the incorrectly removed functions are from the crypto-browserify package.

emit event on verbose mode

It'd be cool for Bankai if we could catch the names of the pruned modules, and log them out as log-level debug. That way people can like debug what's going on inside bankai :D

[email protected] crashes with browserify --full-paths option

Issue did not exist in [email protected].

In [email protected], I started getting this error:

/Users/feross/code/bitmidi.com/node_modules/common-shakeify/index.js:92
    Object.keys(row.indexDeps).forEach((name) => {
           ^

TypeError: Cannot convert undefined or null to object
    at Function.keys (<anonymous>)
    at DestroyableTransform.onfile [as _transform] (/Users/feross/code/bitmidi.com/node_modules/common-shakeify/index.js:92:12)
    at DestroyableTransform.Transform._read (/Users/feross/code/bitmidi.com/node_modules/readable-stream/lib/_stream_transform.js:184:10)
    at DestroyableTransform.Transform._write (/Users/feross/code/bitmidi.com/node_modules/readable-stream/lib/_stream_transform.js:172:83)
    at Labeled.Pipeline._write (/Users/feross/code/bitmidi.com/node_modules/stream-splicer/index.js:70:22)
    at doWrite (/Users/feross/code/bitmidi.com/node_modules/readable-stream/lib/_stream_writable.js:428:64)
    at writeOrBuffer (/Users/feross/code/bitmidi.com/node_modules/readable-stream/lib/_stream_writable.js:417:5)
    at Labeled.Writable.write (/Users/feross/code/bitmidi.com/node_modules/readable-stream/lib/_stream_writable.js:334:11)
    at Labeled.ondata (/Users/feross/code/bitmidi.com/node_modules/readable-stream/lib/_stream_readable.js:619:20)
    at Labeled.emit (events.js:198:13)
/Users/feross/code/bitmidi.com/node_modules/disc/bin/discify:59
    if (err) throw err
             ^

Looking at the changes made for 0.6.1 this definitely seems like it was introduced there. Haven't had a chance to look further into the cause.

The full command I'm using is browserify --no-detect-globals --extension mjs --plugin tinyify --full-paths . with latest browserify.

Using b.require with react and react-dom results in an error

> browserify -r react -r react-dom -p tinyify

/.../node_modules/tinyify/node_modules/common-shakeify/index.js:222
  return row[kDuplicates] || []
            ^

TypeError: Cannot read property 'Symbol(duplicates)' of undefined
    at getDuplicates (/.../node_modules/tinyify/node_modules/common-shakeify/index.js:222:13)
    at analyzer.modules.forEach (/.../node_modules/tinyify/node_modules/common-shakeify/index.js:121:21)
    at Map.forEach (<anonymous>)
    at DestroyableTransform.onend [as _flush] (/.../node_modules/tinyify/node_modules/common-shakeify/index.js:118:22)
    at DestroyableTransform.prefinish (/.../node_modules/readable-stream/lib/_stream_transform.js:138:10)
    at emitNone (events.js:106:13)
    at DestroyableTransform.emit (events.js:208:7)
    at prefinish (/.../node_modules/readable-stream/lib/_stream_writable.js:619:14)
    at finishMaybe (/.../node_modules/readable-stream/lib/_stream_writable.js:627:5)
    at endWritable (/.../node_modules/readable-stream/lib/_stream_writable.js:638:3)

It appears to only happen when I use them both; if I -r them separately then it works fine. I tried it with some simpler packages such as once and xtend together and that appeared to work just fine.

The package.json:

{
  "private": true,
  "scripts": {
    "test": "browserify -r react -r react-dom -p tinyify"
  },
  "dependencies": {
    "react": "16.6.3",
    "react-dom": "16.6.3"
  },
  "devDependencies": {
    "browserify": "16.2.3",
    "tinyify": "2.4.3"
  }
}

deduped modules

browserify dedupes modules with the same source, that looks like:

arguments[4][DEDUPED_MODULE_ID][0].apply(exports,arguments)

this is breaking common-shakeify detection of exports for those modules.

a reproduction:

require('i18next').use(require('i18next-xhr-backend'))

Fails to shake Apollo Client

This plugin fails to shake Apollo Client leading to an immensely bloated bundle.

Apollo Client provides a CommonJS bundle, which allegedly is targeted for Node, but I can't see anything about that bundle which would throw off common-shakeify.

This simple example, which should include only the base ApolloClient class and its dependencies actually includes the entire Apollo Client bundle, resulting in a minified bundle size of ~490 kb.

// test.js
var { ApolloClient } = require('@apollo/client/core')
module.exports = new ApolloClient({})
$ npx browserify -p common-shakeify -g uglifyify test.js | wc -c
486954

This is the Apollo Client CommonJS bundle: https://unpkg.com/@apollo/[email protected]/core/core.cjs.js

Errors on browserify -r

Made a repro here
https://github.com/laduke/common-shake-repro

Hopefully i'm not just holding it wrong.
Looks like same message as from #10 ?

 browserify -r net-browserify-stub:net index.js -p common-shakeify
/common-shake-repro/node_modules/common-shakeify/index.js:239
  return row[kDuplicates] || [

TypeError: Cannot read property 'Symbol(duplicates)' of undefined
    at getDuplicates (/Users/travis/src/common-shake-repro/node_modules/common-shakeify/index.js:239:13)
    at analyzer.modules.forEach (/Users/travis/src/common-shake-repro/node_modules/common-shakeify/index.js:122:21)
    at Map.forEach (<anonymous>)
    at DestroyableTransform.onend [as _flush] (/Users/travis/src/common-shake-repro/node_modules/common-shakeify/index.js:119:22)
    at DestroyableTransform.prefinish (/Users/travis/src/common-shake-repro/node_modules/readable-stream/lib/_stream_transform.js:138:10)
    at DestroyableTransform.emit (events.js:197:13)
    at prefinish (/Users/travis/src/common-shake-repro/node_modules/readable-stream/lib/_stream_writable.js:619:14)
    at finishMaybe (/Users/travis/src/common-shake-repro/node_modules/readable-stream/lib/_stream_writable.js:627:5)
    at endWritable (/Users/travis/src/common-shake-repro/node_modules/readable-stream/lib/_stream_writable.js:638:3)
    at DestroyableTransform.Writable.end (/Users/travis/src/common-shake-repro/node_modules/readable-stream/lib/_stream_writable.js:594:41)

Just upgraded to v1 - TypeError: Cannot read properties of undefined (reading 'dedupe')

Just upgraded the dependencies in an old project and tried re-running the browserify portion.

common-shakeify v1.1.1
Node 16.16.0
OSX Arm

b = browserify(options).plugin(commonShakeify, {});

b.transform('babelify', {
    presets: ['@babel/preset-env'],
    sourceMaps: true
  });

So just using the default options, but when running it I get:

TypeError: Cannot read properties of undefined (reading 'dedupe')
    at /node_modules/common-shakeify/index.js:150:15
    at Map.forEach (<anonymous>)
    at DestroyableTransform.onend [as _flush] (/node_modules/common-shakeify/index.js:143:22)
    at DestroyableTransform.prefinish (/node_modules/readable-stream/lib/_stream_transform.js:138:10)
    at DestroyableTransform.emit (node:events:527:28)
    at DestroyableTransform.emit (node:domain:537:15)
    at prefinish (/node_modules/readable-stream/lib/_stream_writable.js:619:14)
    at finishMaybe (/node_modules/readable-stream/lib/_stream_writable.js:627:5)
    at endWritable (/node_modules/readable-stream/lib/_stream_writable.js:638:3)
    at DestroyableTransform.Writable.end (/node_modules/readable-stream/lib/_stream_writable.js:594:41)
    at DestroyableTransform.onend (/node_modules/readable-stream/lib/_stream_readable.js:577:10)
    at Object.onceWrapper (node:events:641:28)
    at DestroyableTransform.emit (node:events:539:35)
    at DestroyableTransform.emit (node:domain:537:15)
    at endReadableNT (/node_modules/readable-stream/lib/_stream_readable.js:1010:12)
    at processTicksAndRejections (node:internal/process/task_queues:83:21)

Any ideas what this might be? Not changed anything other than the version numbers of packages.

Some kind of error sometimes

So, if I have pull-ws in my choo app and use bankai as the dev server, bankai will crash when it first starts up; Then if I save a file, it recompiles and it works.

Chatted with @yoshuawuyts and we narrowed it down to common-shakeify by commenting out transforms in bankai (https://github.com/choojs/bankai/blob/master/lib/graph-script.js) until it worked.

Here's is the stack trace.

scripts:browserify.bundle Assigning to rvalue (3:45)
SyntaxError: Assigning to rvalue (3:45)
    at Parser.pp$4.raise (/Users/travis/source/commonshake/node_modules/acorn/dist/acorn.js:2610:13)
    at Parser.pp$2.toAssignable (/Users/travis/source/commonshake/node_modules/acorn/dist/acorn.js:1529:12)
    at Parser.pp$3.parseMaybeAssign (/Users/travis/source/commonshake/node_modules/acorn/dist/acorn.js:1839:47)
    at Parser.pp$3.parseExpression (/Users/travis/source/commonshake/node_modules/acorn/dist/acorn.js:1803:19)
    at Parser.pp$1.parseStatement (/Users/travis/source/commonshake/node_modules/acorn/dist/acorn.js:797:45)
    at Parser.pp$1.parseTopLevel (/Users/travis/source/commonshake/node_modules/acorn/dist/acorn.js:690:23)
    at Parser.parse (/Users/travis/source/commonshake/node_modules/acorn/dist/acorn.js:543:15)
    at parse (/Users/travis/source/commonshake/node_modules/acorn/dist/acorn.js:3669:37)
    at module.exports (/Users/travis/source/commonshake/node_modules/falafel/index.js:22:15)
    at /Users/travis/source/commonshake/node_modules/static-module/index.js:30:13

I made a repro repo
https://gist.github.com/laduke/7441c3564d74905f6d409924bccbf68f

Breaks split-require

I just noticed that #43 completely breaks split-require. Only module.exports = whatever work, but all named exports are dropped. I've created a test case in my fork but am struggling to figure out what's wrong.

I'm not fully familiar with the inner workings of split-require and even less so in combination with common-shakeify, @goto-bus-stop, can you see why this change would break split-require?

Originally posted by @tornqvist in #43 (comment)

TypeError: Cannot read property 'Symbol(duplicates)' of undefined

getDuplicates fails with this when i use browserify --no-bundle-external.

  return row[kDuplicates] || []
             ^

TypeError: Cannot read property 'Symbol(duplicates)' of undefined
    at getDuplicates (/home/arch/Code/goto-bus-stop/common-shakeify/index.js:214:14)
    at analyzer.modules.forEach (/home/arch/Code/goto-bus-stop/common-shakeify/index.js:115:21)

encountering a spread operator results in fatal error

hello and thank you for all your great open source work! 👋

here's a simplified repro case for an error i'm running into in the wild.

// foo.js
const bar = require('./bar')
console.log(bar)

// bar.js
const baz = require('./baz')
module.exports = { ...baz }

// baz.js
module.exports = { foo: 3 }
# Node 14
% browserify foo.js -p [ common-shakeify -v ] -o bundle.js
/Users/john/code/web/node_modules/@goto-bus-stop/common-shake/lib/shake/analyzer.js:367
        (prop.key.type !== 'Literal' && prop.key.type !== 'Identifier')) {
                  ^

TypeError: Cannot read property 'type' of undefined
    at Analyzer.siftModuleExports (/Users/john/code/web/node_modules/@goto-bus-stop/common-shake/lib/shake/analyzer.js:367:19)
    at Analyzer.siftAssignment (/Users/john/code/web/node_modules/@goto-bus-stop/common-shake/lib/shake/analyzer.js:329:10)
    at AssignmentExpression (/Users/john/code/web/node_modules/@goto-bus-stop/common-shake/lib/shake/analyzer.js:256:40)
    at c (/Users/john/code/web/node_modules/@goto-bus-stop/common-shake/lib/shake/walk.js:19:16)
    at Object.skipThrough (/Users/john/code/web/node_modules/@goto-bus-stop/common-shake/node_modules/acorn-walk/dist/walk.js:186:39)
    at c (/Users/john/code/web/node_modules/@goto-bus-stop/common-shake/lib/shake/walk.js:20:15)
    at Object.base.ExpressionStatement.base.ParenthesizedExpression (/Users/john/code/web/node_modules/@goto-bus-stop/common-shake/node_modules/acorn-walk/dist/walk.js:204:37)
    at c (/Users/john/code/web/node_modules/@goto-bus-stop/common-shake/lib/shake/walk.js:20:15)
    at Object.skipThrough (/Users/john/code/web/node_modules/@goto-bus-stop/common-shake/node_modules/acorn-walk/dist/walk.js:186:39)
    at c (/Users/john/code/web/node_modules/@goto-bus-stop/common-shake/lib/shake/walk.js:20:15)

right now i'm using babelify and working around this issue by transpiling for browsers that don't support spreading, but that's less than ideal.

i'd log an issue in common-shake, but i'm at a loss for what's going on under the hood.

Browserify + common-shakeify + Chart.js = infinite stack trace

I created this issue here: chartjs/Chart.js#11479

Expected behavior

I'm using [email protected] + [email protected] + [email protected].

In JavaScript I have this:

const Chart = require('chart.js/auto');

console.log('Hello');

Bundling will give me a stack trace and a crash.

Current behavior

ile@ilepc:~/src/sc2/browserify-chartjs$ ./run.sh 
/home/ile/src/sc2/browserify-chartjs/node_modules/escope/lib/scope.js:417
            var ref = new _reference2.default(node, this, assign || _reference2.default.READ, writeExpr, maybeImplicitGlobal, !!partial, !!init);
                      ^

RangeError: Maximum call stack size exceeded
    at ClassScope.__referencing (/home/ile/src/sc2/browserify-chartjs/node_modules/escope/lib/scope.js:417:23)
    at Referencer.Identifier (/home/ile/src/sc2/browserify-chartjs/node_modules/escope/lib/referencer.js:425:33)
    at Visitor.visit (/home/ile/src/sc2/browserify-chartjs/node_modules/esrecurse/esrecurse.js:104:34)
    at Visitor.visitChildren (/home/ile/src/sc2/browserify-chartjs/node_modules/esrecurse/esrecurse.js:88:26)
    at Visitor.visit (/home/ile/src/sc2/browserify-chartjs/node_modules/esrecurse/esrecurse.js:107:14)
    at Visitor.visitChildren (/home/ile/src/sc2/browserify-chartjs/node_modules/esrecurse/esrecurse.js:83:38)
    at Visitor.visit (/home/ile/src/sc2/browserify-chartjs/node_modules/esrecurse/esrecurse.js:107:14)
    at Visitor.visitChildren (/home/ile/src/sc2/browserify-chartjs/node_modules/esrecurse/esrecurse.js:88:26)
    at Visitor.visit (/home/ile/src/sc2/browserify-chartjs/node_modules/esrecurse/esrecurse.js:107:14)
    at Visitor.visitChildren (/home/ile/src/sc2/browserify-chartjs/node_modules/esrecurse/esrecurse.js:83:38)

Node.js v20.5.1

Reproducible sample

https://github.com/ile/browserify-chartjs

Optional extra steps/info to reproduce

No response

Possible solution

No response

Context

No response

chart.js version

v4.4.0

Browser name and version

No response

Link to your project

https://github.com/ile/browserify-chartjs

Recommend Projects

  • React photo React

    A declarative, efficient, and flexible JavaScript library for building user interfaces.

  • Vue.js photo Vue.js

    🖖 Vue.js is a progressive, incrementally-adoptable JavaScript framework for building UI on the web.

  • Typescript photo Typescript

    TypeScript is a superset of JavaScript that compiles to clean JavaScript output.

  • TensorFlow photo TensorFlow

    An Open Source Machine Learning Framework for Everyone

  • Django photo Django

    The Web framework for perfectionists with deadlines.

  • D3 photo D3

    Bring data to life with SVG, Canvas and HTML. 📊📈🎉

Recommend Topics

  • javascript

    JavaScript (JS) is a lightweight interpreted programming language with first-class functions.

  • web

    Some thing interesting about web. New door for the world.

  • server

    A server is a program made to process requests and deliver data to clients.

  • Machine learning

    Machine learning is a way of modeling and interpreting data that allows a piece of software to respond intelligently.

  • Game

    Some thing interesting about game, make everyone happy.

Recommend Org

  • Facebook photo Facebook

    We are working to build community through open source technology. NB: members must have two-factor auth.

  • Microsoft photo Microsoft

    Open source projects and samples from Microsoft.

  • Google photo Google

    Google ❤️ Open Source for everyone.

  • D3 photo D3

    Data-Driven Documents codes.