-
Notifications
You must be signed in to change notification settings - Fork 149
New issue
Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.
By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.
Already on GitHub? Sign in to your account
Improve packaging to better support module bundlers #414
Conversation
Removed copied source of the text-encoding library and added a regular npm dependency instead.
Improved feature detection and tweaked package.json in order to make Webpack not load NodeJS modules. Feature detection is also changed to account for possibly empty Node modules, like net ot dns. Previous packaging was the same for Node and browser and feature detection happened at runtime. Webpack, however, tried to resolve modules at compile time and failed. New "browser" entry in package.json tells bundlers to return empty objects for Node modules.
This makes it easier to override Node modules in browser environment.
This commit separates components that depend on browser environment from components that use Node features. No separation was previously needed because code used runtime feature detection. Such feature detection made it impossible for bundlers, like Webpack, to strip away Node-specific code. Presence of it caused failures at build time and made it hard to use the driver package. Driver contains couple env-dependent components: * network channel (`WebSocket` in browser, `net.Socket` in Node) * byte buffer (`ArrayBuffer` in browser, `buffer.Buffer` in Node) * host name resolver (no-op in browser, `dns` lookup in Node) * UTF8 encoding & decoding (`text-encoding` library in browser, `StringDecoder` in Node) Implementations of these components now live in separate folders `src/internal/node` and `src/internal/browser`. Both contain `index.js` files that export the same set of components and follow the same "interface". Env-dependent tests are also split into separate folders. All sources import/require `node/index.js` by default. `package.json` now contains a "browser" field which instructs bundlers to replace all imports/require of `node/index.js` with `browser/index.js` for client-side apps. This way code that depends on Node APIs will not even be included in the resulting bundle. Gulp build for UMD `neo4j-web.js` and `neo4j-web.test.js` bundles excludes `node` folders and only includes `browser`. It also replaces all require calls of "/node" to "/browser". Dedicated browserify transformation is added for this to the bundling process. Resulting bundles no longer contain code that depends on Node APIs.
Removed ignores of "external" folder because it no longer exists. Keep babel config in one place.
It requires `TlsSocket.getPeerCertificate()` function to work, which is available since Node v0.11.4.
Test bundle for browser environment `neo4j-web.test.js` is generated at build time and contains driver code and test code to execute. It was added to `lib/browser` directory and ended up included in the npm package. This commit makes build process generate the test bundle in `build/browser` which is excluded from package. Also removed gulp file from package.
To verify that driver can be used in a browser app. This makes sure no NodeJS APIs are used unconditionally. Webpack build fails for such APIs at compile time. Webpack uses "browser" field from package.json to replace Node components with browser components. All environment-dependent code should only be exposed from `node/index.js` and `browser/index.js`.
It depends on Webpack which can't be included in a browser test UMD bundle.
0f199a4
to
aeedec1
Compare
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
LGTM, I've also verified it with a very dumb test drive with create-react-app
.
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Much appreciated change!
This looks good to me, thank you.
I've tried it in neo4j-browser which is using webpack 3 and the browser
field overrides in package.json works fine. After this change we can remove our (neo4j-browser) webpack alias workaround:
'neo4j-driver': 'neo4j-driver/lib/browser/neo4j-web.min.js',
which in turn should make the bundled code for neo4j-browser better structured.
So 👍
Previous version of the check failed in strict mode with error "window is not defined". Strict mode is default in Webpack.
src/v1/internal/node/index.js
andsrc/v1/internal/browser/index.js
node/index.js
by defaulttest/internal/node
andtest/internal/browser
test/node
test/browser
require('./node')
withrequire('./browser')
when building UMD modulesneo4j-web.test.js
from the npm packageDummyChannel
to test scopeResolves #396