pkginfo breaks webpack build
See original GitHub issueDescription
I’m having this issue when importing slack client.
It crashes on the line:
const { WebClient } = require('@slack/client');
I’m using react-webpack-node@3.4.1
Might be the same as: #445 ?
2018-02-08T17:04:15.485548+00:00 app[web.1]: TypeError [ERR_INVALID_ARG_TYPE]: The “path” argument must be of type string 2018-02-08T17:04:15.485567+00:00 app[web.1]: at assertPath (path.js:28:11) 2018-02-08T17:04:15.485569+00:00 app[web.1]: at Object.dirname (path.js:1347:5) 2018-02-08T17:04:15.485571+00:00 app[web.1]: at Function.pkginfo.find (/app/node_modules/pkginfo/lib/pkginfo.js:91:16) 2018-02-08T17:04:15.485572+00:00 app[web.1]: at Function.pkginfo.read (/app/node_modules/pkginfo/lib/pkginfo.js:122:22) 2018-02-08T17:04:15.485574+00:00 app[web.1]: at module.exports (/app/node_modules/pkginfo/lib/pkginfo.js:68:21) 2018-02-08T17:04:15.485576+00:00 app[web.1]: at Object.<anonymous> (/app/compiled/server.js:6:104666) 2018-02-08T17:04:15.485578+00:00 app[web.1]: at Object.<anonymous> (/app/compiled/server.js:6:105120) 2018-02-08T17:04:15.485579+00:00 app[web.1]: at t (/app/compiled/server.js:1:155) 2018-02-08T17:04:15.485581+00:00 app[web.1]: at Object.<anonymous> (/app/compiled/server.js:20:3298) 2018-02-08T17:04:15.485583+00:00 app[web.1]: at t (/app/compiled/server.js:1:155) 2018-02-08T17:04:15.485584+00:00 app[web.1]: at Object.<anonymous> (/app/compiled/server.js:20:125024) 2018-02-08T17:04:15.485586+00:00 app[web.1]: at t (/app/compiled/server.js:1:155) 2018-02-08T17:04:15.485590+00:00 app[web.1]: at Object.<anonymous> (/app/compiled/server.js:20:120942) 2018-02-08T17:04:15.485592+00:00 app[web.1]: at t (/app/compiled/server.js:1:155) 2018-02-08T17:04:15.485594+00:00 app[web.1]: at /app/compiled/server.js:20:455159 2018-02-08T17:04:15.485596+00:00 app[web.1]: at model.Query.<anonymous> (/app/node_modules/mongoose/lib/model.js:4074:16) 2018-02-08T17:04:15.485598+00:00 app[web.1]: at /app/node_modules/kareem/index.js:273:21 2018-02-08T17:04:15.485600+00:00 app[web.1]: at /app/node_modules/kareem/index.js:131:16 2018-02-08T17:04:15.485602+00:00 app[web.1]: at process._tickCallback (internal/process/next_tick.js:150:11)
Issue Analytics
- State:
- Created 6 years ago
- Reactions:1
- Comments:8 (7 by maintainers)
@clavin thanks for digging into this!
in my development branch of v4 with TypeScript, i migrated from using
pkginfo
to usingpjson
. that gives me a loose type definition so it resolves one problem i was having, but it works about the same aspkginfo
(depends on__dirname
), so this issue would still exist.the two options i see right now are:
import * as pkg from '../package.json';
. the error in my relatively vanilla project configuration isCannot find module '../package.json'
.these two solutions seem roughly equivalent, so i’m inclined to go with the first.
i do wonder though, is there some conventional behavior of all major bundlers (browserify, webpack, rollup, etc) to “blacklist” a dependency (or transitive dependency) such that the bundler excludes it and replaces it with a stub? i see that browserify uses the package.json field “browser” to accomplish this, but is that respected across bundlers? if so, one very hacky but easy to implement solution is to just wrap a
require('../package.json')
in atry/catch
, and silently fail building the version string. this is used for instrumentation purposes, but would have no functional impact. it still requires this package’s maintainers to implement a fix.Why the Error is Thrown
This entire issue stems from the use of the
pkginfo
module by this SDK. The SDK currently uses pkginfo to get some information from this package’spackage.json
file, namely the version and package name. This information is used as part of theUser-Agent
header when accessing the Slack API.In this issue, the SDK is being imported in a browser environment.
pkginfo
works by using the nativepath
module to locate the parent module’s (the SDK’s)package.json
, then reads it usingrequire
as an attempt to be bundler-friendly.pkginfo
attempts to locate the directory of the SDK by using thefilename
andid
fields of themodule
object for the SDK (likemodule.exports
).The problem arises when the bundler used by the user does not provide these fields on the module object. This means that
undefined
is ultimately passed topath.dirname
, which ends up throwing.How to Fix It
As a user of the SDK, there’s really no way to fix this as of right now, other than finding a different bundler or to configuring yours current one differently.
As for the maintainers and contributors for this repository, something can be done: drop the use of
pkginfo
in favor of a build task that generates a file containing the data used in theUser-Agent
header. This is a viable solution because the SDK is already planned for TypeScript migration, and since that requires the library to be “built” before publishing, adding an extra build step is very appropriate—though a workaround should be found for testing (implementing an option?).Alternatively, an
options
object can be passed as the second argument topkginfo
with thedir
option set to the directory of the file using pkginfo or the root directory of the SDK package (either works). I’d advise against this because this can really only be done using some variation of__dirname
, which can cause the same problem showcased in this issue.Edit: as another solution, I don’t see why we can’t just import the
package.json
directly from its relative path to whatever file needs that info. After all,pkginfo
does just that in a more convoluted (with the goal of convenience, mind you) fashion currently.