Skip to content

Commit ab21994

Browse files
authored
fix "dependency is an expression" issue (#2865)
* fix "dependency is an expression" issue - inline loadOptionalLibrary code - remove "browser" field in pacakge.json so tools will prefer the es variant - update Optional Dependencies section in readme - fix rollup config fix #2846 * add missing file extensions to imports
1 parent c3a379d commit ab21994

File tree

6 files changed

+144
-63
lines changed

6 files changed

+144
-63
lines changed

README.md

Lines changed: 24 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -122,13 +122,33 @@ doc.save("a4.pdf");
122122
### Optional dependencies
123123

124124
Some functions of jsPDF require optional dependencies. E.g. the `html` method, which depends on `html2canvas` and,
125-
when supplied with a string HTML document, `dompurify`. You need to install them explicitly, e.g.:
125+
when supplied with a string HTML document, `dompurify`. JsPDF loads them dynamically when required
126+
(using the respective module format, e.g. dynamic imports). Build tools like Webpack will automatically create separate
127+
chunks for each of the optional dependencies. If your application does not use any of the optional dependencies, you
128+
can prevent Webpack from generating the chunks by defining them as external dependencies:
126129

127-
```sh
128-
npm install --save html2canvas dompurify
130+
```js
131+
// webpack.config.js
132+
module.exports = {
133+
// ...
134+
externals: {
135+
// only define the dependencies you are NOT using as externals!
136+
canvg: "canvg",
137+
html2canvas: "html2canvas",
138+
dompurify: "dompurify"
139+
}
140+
};
129141
```
130142

131-
jsPDF will then dynamically load them when required (using the respective module format, e.g. dynamic imports).
143+
In **Vue CLI** projects, externals can be defined via the [configureWebpack](https://cli.vuejs.org/config/#configurewebpack)
144+
or [chainWebpack](https://cli.vuejs.org/config/#chainwebpack) properties of the `vue.config.js` file
145+
(needs to be created, first, in fresh projects).
146+
147+
In **Angular** projects, externals can be defined using
148+
[custom webpack builders](https://github.com/just-jeb/angular-builders/tree/master/packages/custom-webpack).
149+
150+
In **React** (`create-react-app`) projects, externals can be defined by either using
151+
[react-app-rewired](https://github.com/timarney/react-app-rewired) or ejecting.
132152

133153
### TypeScript/Angular/Webpack/React/etc. Configuration:
134154

package.json

Lines changed: 0 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -5,7 +5,6 @@
55
"description": "PDF Document creation from JavaScript",
66
"main": "dist/jspdf.node.min.js",
77
"module": "dist/jspdf.es.min.js",
8-
"browser": "dist/jspdf.umd.min.js",
98
"files": [
109
"dist",
1110
"types/index.d.ts",

rollup.config.js

Lines changed: 3 additions & 5 deletions
Original file line numberDiff line numberDiff line change
@@ -38,10 +38,8 @@ const umdExternals = matchSubmodules([
3838
]);
3939
const externals = matchSubmodules([
4040
...Object.keys(pkg.dependencies || {}),
41-
...[
42-
...Object.keys(pkg.peerDependencies || {}),
43-
...Object.keys(pkg.optionalDependencies || {})
44-
]
41+
...Object.keys(pkg.peerDependencies || {}),
42+
...Object.keys(pkg.optionalDependencies || {})
4543
]);
4644

4745
const umd = {
@@ -162,7 +160,7 @@ const esPolyfills = {
162160
};
163161

164162
function matchSubmodules(externals) {
165-
return externals.map(e => new RegExp(`^${e}[/\\\\]`));
163+
return externals.map(e => new RegExp(`^${e}(?:[/\\\\]|$)`));
166164
}
167165

168166
export default [umd, es, node, umdPolyfills, esPolyfills];

src/libs/loadOptionalLibrary.js

Lines changed: 0 additions & 44 deletions
This file was deleted.

src/modules/html.js

Lines changed: 75 additions & 7 deletions
Original file line numberDiff line numberDiff line change
@@ -8,7 +8,7 @@
88
*/
99

1010
import { jsPDF } from "../jspdf.js";
11-
import { loadOptionalLibrary } from "../libs/loadOptionalLibrary.js";
11+
import { globalObject } from "../libs/globalObject.js";
1212

1313
/**
1414
* jsPDF html PlugIn
@@ -20,15 +20,83 @@ import { loadOptionalLibrary } from "../libs/loadOptionalLibrary.js";
2020
"use strict";
2121

2222
function loadHtml2Canvas() {
23-
return loadOptionalLibrary("html2canvas").catch(function(e) {
24-
return Promise.reject(new Error("Could not load html2canvas: " + e));
25-
});
23+
return (function() {
24+
if (globalObject["html2canvas"]) {
25+
return Promise.resolve(globalObject["html2canvas"]);
26+
}
27+
28+
// @if MODULE_FORMAT='es'
29+
return import("html2canvas");
30+
// @endif
31+
32+
// @if MODULE_FORMAT!='es'
33+
if (typeof exports === "object" && typeof module !== "undefined") {
34+
return new Promise(function(resolve, reject) {
35+
try {
36+
resolve(require("html2canvas"));
37+
} catch (e) {
38+
reject(e);
39+
}
40+
});
41+
}
42+
if (typeof define === "function" && define.amd) {
43+
return new Promise(function(resolve, reject) {
44+
try {
45+
require(["html2canvas"], resolve);
46+
} catch (e) {
47+
reject(e);
48+
}
49+
});
50+
}
51+
return Promise.reject(new Error("Could not load " + name));
52+
// @endif
53+
})()
54+
.catch(function(e) {
55+
return Promise.reject(new Error("Could not load dompurify: " + e));
56+
})
57+
.then(function(html2canvas) {
58+
return html2canvas.default ? html2canvas.default : html2canvas;
59+
});
2660
}
2761

2862
function loadDomPurify() {
29-
return loadOptionalLibrary("dompurify", "DOMPurify").catch(function(e) {
30-
return Promise.reject(new Error("Could not load dompurify: " + e));
31-
});
63+
return (function() {
64+
if (globalObject["DOMPurify"]) {
65+
return Promise.resolve(globalObject["DOMPurify"]);
66+
}
67+
68+
// @if MODULE_FORMAT='es'
69+
return import("dompurify");
70+
// @endif
71+
72+
// @if MODULE_FORMAT!='es'
73+
if (typeof exports === "object" && typeof module !== "undefined") {
74+
return new Promise(function(resolve, reject) {
75+
try {
76+
resolve(require("dompurify"));
77+
} catch (e) {
78+
reject(e);
79+
}
80+
});
81+
}
82+
if (typeof define === "function" && define.amd) {
83+
return new Promise(function(resolve, reject) {
84+
try {
85+
require(["dompurify"], resolve);
86+
} catch (e) {
87+
reject(e);
88+
}
89+
});
90+
}
91+
return Promise.reject(new Error("Could not load " + name));
92+
// @endif
93+
})()
94+
.catch(function(e) {
95+
return Promise.reject(new Error("Could not load dompurify: " + e));
96+
})
97+
.then(function(dompurify) {
98+
return dompurify.default ? dompurify.default : dompurify;
99+
});
32100
}
33101

34102
/**

src/modules/svg.js

Lines changed: 42 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -23,8 +23,8 @@
2323
*/
2424

2525
import { jsPDF } from "../jspdf.js";
26-
import { loadOptionalLibrary } from "../libs/loadOptionalLibrary.js";
2726
import { console } from "../libs/console.js";
27+
import { globalObject } from "../libs/globalObject.js";
2828

2929
/**
3030
* jsPDF SVG plugin
@@ -35,6 +35,46 @@ import { console } from "../libs/console.js";
3535
(function(jsPDFAPI) {
3636
"use strict";
3737

38+
function loadCanvg() {
39+
return (function() {
40+
if (globalObject["canvg"]) {
41+
return Promise.resolve(globalObject["canvg"]);
42+
}
43+
44+
// @if MODULE_FORMAT='es'
45+
return import("canvg");
46+
// @endif
47+
48+
// @if MODULE_FORMAT!='es'
49+
if (typeof exports === "object" && typeof module !== "undefined") {
50+
return new Promise(function(resolve, reject) {
51+
try {
52+
resolve(require("canvg"));
53+
} catch (e) {
54+
reject(e);
55+
}
56+
});
57+
}
58+
if (typeof define === "function" && define.amd) {
59+
return new Promise(function(resolve, reject) {
60+
try {
61+
require(["canvg"], resolve);
62+
} catch (e) {
63+
reject(e);
64+
}
65+
});
66+
}
67+
return Promise.reject(new Error("Could not load " + name));
68+
// @endif
69+
})()
70+
.catch(function(e) {
71+
return Promise.reject(new Error("Could not load dompurify: " + e));
72+
})
73+
.then(function(canvg) {
74+
return canvg.default ? canvg.default : canvg;
75+
});
76+
}
77+
3878
/**
3979
* Parses SVG XML and saves it as image into the PDF.
4080
*
@@ -89,7 +129,7 @@ import { console } from "../libs/console.js";
89129
ignoreDimensions: true
90130
};
91131
var doc = this;
92-
return loadOptionalLibrary("canvg")
132+
return loadCanvg()
93133
.then(
94134
function(canvg) {
95135
return canvg.Canvg.fromString(ctx, svg, options);

0 commit comments

Comments
 (0)