docx
docx copied to clipboard
docx 7: does not work example of basic usage when using ES modules format in Node.js
Example of Basic Usage does not work on docx v7 (works on v6.0.3)
import * as fs from "fs";
import { Document, Packer, Paragraph, TextRun } from "docx";
// Documents contain sections, you can have multiple sections per document, go here to learn more about sections
// This simple example will only contain one section
const doc = new Document({
sections: [{
properties: {},
children: [
new Paragraph({
children: [
new TextRun("Hello World"),
new TextRun({
text: "Foo Bar",
bold: true,
}),
new TextRun({
text: "\tGithub is the best",
bold: true,
}),
],
}),
],
}],
});
// Used to export the file into a .docx file
Packer.toBuffer(doc).then((buffer) => {
fs.writeFileSync("My Document.docx", buffer);
});
// Done! A file called 'My Document.docx' will be in your file system.
import { Document, Packer, Paragraph, TextRun } from 'docx'; ^^^^^^ SyntaxError: Named export 'Packer' not found. The requested module 'docx' is a CommonJS module, which may not support all module.exports as named exports. CommonJS modules can always be imported via the default export, for example using:
import pkg from 'docx'; const { Document, Packer, Paragraph, TextRun } = pkg;
at ModuleJob._instantiate (internal/modules/esm/module_job.js:124:21)
at async ModuleJob.run (internal/modules/esm/module_job.js:179:5)
at async Loader.import (internal/modules/esm/loader.js:178:24)
at async Object.loadESM (internal/process/esm_loader.js:68:5)
Try 7.1.0 I have fixed the issue there I think
problem remains on version 7.1.0
on v 7.1.1 error:
import { Document, Packer, Paragraph, TextRun } from 'docx'; ^^^^^^^^ SyntaxError: Named export 'Document' not found. The requested module 'docx' is a CommonJS module, which may not support all module.exports as named exports. CommonJS modules can always be imported via the default export, for example using:
import pkg from 'docx'; const { Document, Packer, Paragraph, TextRun } = pkg;
Strange I republished this as a ES6 module, and I tried this on Angular with npm link, and it worked fine
I will investigate later
It works for me just fine, I am using 7.1.1 right now in Angular, downloaded fresh from npm
Could you double check?

Using Docx v7.1.1 I run code from Example of basic usage on nodejs in VS code without frameworks:
import * as fs from 'fs';
import { Document, Packer, Paragraph, TextRun } from 'docx';
// Documents contain sections, you can have multiple sections per document, go here to learn more about sections
// This simple example will only contain one section
const doc = new Document({
sections: [
{
properties: {},
children: [
new Paragraph({
children: [
new TextRun('Hello World'),
new TextRun({
text: 'Foo Bar',
bold: true,
}),
new TextRun({
text: '\tGithub is the best',
bold: true,
}),
],
}),
],
},
],
});
// Used to export the file into a .docx file
Packer.toBuffer(doc).then((buffer) => {
fs.writeFileSync('My Document.docx', buffer);
});
// Done! A file called 'My Document.docx' will be in your file system.
and catch the error:
import { Document, Packer, Paragraph, TextRun } from 'docx'; ^^^^^^^^ SyntaxError: Named export 'Document' not found. The requested module 'docx' is a CommonJS module, which may not support all module.exports as named exports. CommonJS modules can always be imported via the default export, for example using:
import pkg from 'docx'; const { Document, Packer, Paragraph, TextRun } = pkg;
at ModuleJob._instantiate (node:internal/modules/esm/module_job:124:21) at async ModuleJob.run (node:internal/modules/esm/module_job:179:5) at async Loader.import (node:internal/modules/esm/loader:178:24) at async Object.loadESM (node:internal/process/esm_loader:68:5) at async handleMainPromise (node:internal/modules/run_main:63:12)
package.json
{
"name": "test",
"version": "1.0.0",
"description": "",
"main": "index.js",
"type": "module",
"scripts": {
"test": "echo \"Error: no test specified\" && exit 1"
},
"author": "",
"license": "ISC",
"dependencies": {
"docx": "^7.1.1"
}
}
it looks like somewhere in the source code Docx.js starting from version 7.0.0 mixed up ES6 modules (import, export) with CommonJS (require/module.exports).
can you reproduce it on CodePen or StackBlitz? I can't seem to find the problem for me
How does it work in v6, do you know?
Does this mean v6 is both commonjs and esm?
I have been researching, and it all points to this:
https://www.sensedeep.com/blog/posts/2021/how-to-create-single-source-npm-module.html
I wasn't doing any Hybrid magic before, so I am unsure why it needs to be done now?
there was no such problem on version 6.0.3
maybe the problem arose because of the move from Webpack 3 to Webpack 5
maybe yes, maybe Webpack 3 did a hybrid but Webpack 5 dropped it?
When I get time, ill turn it hybrid commonJS and ESM
If you want to pick up this task, you could create a PR too
@dolanmiu any progress in that? Sorry, I'm not skilled enough to try to solve it on my own
@smolendawid I'm not too well versed in webpack either actually, i am using out of the box content
Wanted to updated to 7.2, but I am facing this issue too
Getting the same error with 7.3.0 after pasting and trying to run "Basic Usage"
import { Document, Packer, Paragraph, TextRun } from "docx" ^^^^^^^^ SyntaxError: Named export 'Document' not found. The requested module 'docx' is a CommonJS module, which may not support all module.exports as named exports. CommonJS modules can always be imported via the default export, for example using:
import pkg from 'docx'; const { Document, Packer, Paragraph, TextRun } = pkg;
at ModuleJob._instantiate (node:internal/modules/esm/module_job:127:21)
at async ModuleJob.run (node:internal/modules/esm/module_job:191:5)
at async Promise.all (index 0)
at async ESMLoader.import (node:internal/modules/esm/loader:337:24)
at async loadESM (node:internal/process/esm_loader:88:5)
at async handleMainPromise (node:internal/modules/run_main:61:12)
Can you do this?
import { Document as DocxDocument } from "docx";
export const document = options => new DocxDocument(options);
I am on 7.3.0 and have no issues doing the above
My theory is that there is ambiguity between the DOM Document and docx Document
You still get the nice hinting too

You can import like this:
import docx from "docx";
const {Document, Packer, Paragraph, TextRun} = docx;
@dolanmiu, ESM and CommonJS works if build with changed webpack.config.ts:
...
const configuration = { ...
output: { path: path.resolve("build"), filename: "index.js", ~~libraryTarget: "umd",~~ library: ~~"docx"~~ { type: "commonjs-static" }, globalObject: "globalThis", }
...
But would this work as an iife? Like a standard <script src="..."></script> tag?
Need to test
But would this work as an iife? Like a standard
<script src="..."></script>tag?
Does not work
Ah I see. Yes, this would be a requirement
As variant to build 2 entry points:
changes in a webpack.config.ts:
const configuration = { ... entry: { index: { import: "./src/index.ts", library: { name: "docx", type: "umd" } }, node: { import: "./src/index.ts", library: { type: "commonjs-static" } }, },
output: { path: path.resolve("build"), filename: "[name].js", // libraryTarget: "umd", // library: "docx", globalObject: "globalThis", }, ...

Who need docx.js in node.js through the ESM:
import { Document, Packer, Paragraph, Tab, TextRun, } from './node_modules/docx/build/node.js';
The only thing I don't know is how to automatically duplicate index.d.ts with the name node.d.ts for types.
Version 8.0.4 and Basic usage example still doesn't work in Node with ESM. Is it possible to at least update a documentation accordingly?
Doesn't work for me with Angular. Neither the old way, nor the above suggestions:
Error: export 'default' (imported as 'docx') was not found in 'docx' (module has no exports)