I'm trying to require and use Quill in a node.js project and having trouble with it. Here's what's happening:
Steps for Reproduction
Expected behavior:
returns the Quill object
Actual behavior:
throws an exception
Platforms:
Version:
Example:
$ npm install quill
[email protected] /Users/patrickminton/src/exm-admin-tool
├── UNMET PEER DEPENDENCY [email protected]
└── [email protected]
$ node
> var Quill = require('quill')
ReferenceError: document is not defined
at Object.<anonymous> (/Users/patrickminton/src/exm-admin-tool/node_modules/quill/dist/quill.js:2330:22)
at __webpack_require__ (/Users/patrickminton/src/exm-admin-tool/node_modules/quill/dist/quill.js:36:30)
at Object.<anonymous> (/Users/patrickminton/src/exm-admin-tool/node_modules/quill/dist/quill.js:1656:2)
at __webpack_require__ (/Users/patrickminton/src/exm-admin-tool/node_modules/quill/dist/quill.js:36:30)
at Object.<anonymous> (/Users/patrickminton/src/exm-admin-tool/node_modules/quill/dist/quill.js:76:15)
at __webpack_require__ (/Users/patrickminton/src/exm-admin-tool/node_modules/quill/dist/quill.js:36:30)
at Object.defineProperty.value (/Users/patrickminton/src/exm-admin-tool/node_modules/quill/dist/quill.js:7726:14)
at __webpack_require__ (/Users/patrickminton/src/exm-admin-tool/node_modules/quill/dist/quill.js:36:30)
at Object.<anonymous> (/Users/patrickminton/src/exm-admin-tool/node_modules/quill/dist/quill.js:63:19)
at __webpack_require__ (/Users/patrickminton/src/exm-admin-tool/node_modules/quill/dist/quill.js:36:30)
I used testdom to eliminate the document problem, but it still barfs:
$ node
> require('testdom')('<html><body></body></html>', {})
undefined
> var Quill = require('quill')
ReferenceError: Node is not defined
at Object.defineProperty.value (/Users/patrickminton/src/exm-admin-tool/node_modules/quill/dist/quill.js:6560:27)
at __webpack_require__ (/Users/patrickminton/src/exm-admin-tool/node_modules/quill/dist/quill.js:36:30)
at Object.<anonymous> (/Users/patrickminton/src/exm-admin-tool/node_modules/quill/dist/quill.js:112:19)
at __webpack_require__ (/Users/patrickminton/src/exm-admin-tool/node_modules/quill/dist/quill.js:36:30)
at Object.defineProperty.value (/Users/patrickminton/src/exm-admin-tool/node_modules/quill/dist/quill.js:7726:14)
at __webpack_require__ (/Users/patrickminton/src/exm-admin-tool/node_modules/quill/dist/quill.js:36:30)
at Object.<anonymous> (/Users/patrickminton/src/exm-admin-tool/node_modules/quill/dist/quill.js:63:19)
at __webpack_require__ (/Users/patrickminton/src/exm-admin-tool/node_modules/quill/dist/quill.js:36:30)
at /Users/patrickminton/src/exm-admin-tool/node_modules/quill/dist/quill.js:56:18
at /Users/patrickminton/src/exm-admin-tool/node_modules/quill/dist/quill.js:59:10
My node/npm:
$ node -v
v6.9.0
$ npm -v
3.10.8
Any ideas? Am I using it wrong?
Quill assumes it is being used in a real browser since that is its target platform. It uses Node for building assets and NPM as a package manager but it is not a back end tool. That's not to say you cannot use it in headless test environments and users have been successful in doing so but that is not officially supported and it does not seem like testdom is doing well enough pretending to be a browser.
Then what is the npm install command for?
Pretty much every application people build nowadays uses Browserify or Webpack to build things before the browser renders it, and if you can't even require() it, then how can you use it?
You can absolutely require Quill for the purposes of building with Webpack or Browserify. You just can't run Quill in the Node.js REPL.
The key to this is exposing Node as global variable as well.
@bilbosan was using testdom which is a wrapper around jsdom - it automatically sets document as global variable, which solved his first error.
Here is a full example using a more recent version of jsdom
import { JSDOM } from 'jsdom';
const dom = new JSDOM('');
global.window = dom.window;
global.document = dom.window.document;
global.Node = dom.window.Node;
// ...
run this code before any other and it will work fine.
I guess one thing Quill could potentially do to play a little nicer is not to depend on a global Node. Most people who run a test setup like the one above will not expose Node - but they are very very likely to expose window - so if Quill is accessing Node from window.Node I for example wouldn't have run into this problem.
The previous code snippet doesn't work any more.
Here's a complete working example with node 10.23.0, jsdom 16.4.0 and quill 1.3.7:
const jsdom = require('jsdom');
const { JSDOM } = jsdom;
const dom = new JSDOM('<div id="editor"></div>');
dom.window.document.getSelection = function() { return { getRangeAt: function() { } }; };
dom.window.document.execCommand = function (command, showUI, value) { try { return document.execCommand(command, showUI, value); } catch(e) {} return false; };
global.window = dom.window;
global.document = dom.window.document;
global.Node = dom.window.Node;
global.navigator = global.window.navigator;
global.Text = dom.window.Text;
global.HTMLElement = window.HTMLElement;
global.MutationObserver = dom.window.MutationObserver;
let Quill = require('quill');
var quill = new Quill('#editor');
quill.setContents([
{ insert: 'Hello ' },
{ insert: 'World!', attributes: { bold: true } },
{ insert: '\n' }
]);
console.log(quill.getText());
Hope it helps!
Most helpful comment
The key to this is exposing
Nodeas global variable as well.@bilbosan was using
testdomwhich is a wrapper aroundjsdom- it automatically setsdocumentas global variable, which solved his first error.Here is a full example using a more recent version of
jsdomrun this code before any other and it will work fine.
I guess one thing Quill could potentially do to play a little nicer is not to depend on a global
Node. Most people who run a test setup like the one above will not exposeNode- but they are very very likely to exposewindow- so if Quill is accessingNodefromwindow.NodeI for example wouldn't have run into this problem.