html-webpack-plugin 4.0.2 → 4.2.0
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- package/CHANGELOG.md +37 -0
- package/README.md +66 -28
- package/index.js +64 -72
- package/lib/cached-child-compiler.js +379 -0
- package/lib/child-compiler.js +183 -0
- package/lib/file-watcher-api.js +14 -0
- package/lib/html-tags.js +24 -0
- package/lib/webpack4/file-watcher-api.js +64 -0
- package/lib/webpack5/file-watcher-api.js +71 -0
- package/package.json +8 -7
- package/typings.d.ts +1 -0
- package/lib/compiler.js +0 -356
package/CHANGELOG.md
CHANGED
|
@@ -2,6 +2,43 @@
|
|
|
2
2
|
|
|
3
3
|
All notable changes to this project will be documented in this file. See [standard-version](https://github.com/conventional-changelog/standard-version) for commit guidelines.
|
|
4
4
|
|
|
5
|
+
# [4.2.0](https://github.com/jantimon/html-webpack-plugin/compare/v4.1.0...v4.2.0) (2020-04-09)
|
|
6
|
+
|
|
7
|
+
|
|
8
|
+
### Features
|
|
9
|
+
|
|
10
|
+
* Add template content ([#1401](https://github.com/jantimon/html-webpack-plugin/issues/1401)) ([4740bf7](https://github.com/jantimon/html-webpack-plugin/commit/4740bf7))
|
|
11
|
+
|
|
12
|
+
|
|
13
|
+
|
|
14
|
+
# [4.1.0](https://github.com/jantimon/html-webpack-plugin/compare/v4.0.4...v4.1.0) (2020-04-09)
|
|
15
|
+
|
|
16
|
+
|
|
17
|
+
### Features
|
|
18
|
+
|
|
19
|
+
* Add webpack 5 support ([39c38a4](https://github.com/jantimon/html-webpack-plugin/commit/39c38a4))
|
|
20
|
+
* Allow webpack 5 as peer dependency ([9c571e2](https://github.com/jantimon/html-webpack-plugin/commit/9c571e2))
|
|
21
|
+
|
|
22
|
+
|
|
23
|
+
|
|
24
|
+
## [4.0.4](https://github.com/jantimon/html-webpack-plugin/compare/v4.0.3...v4.0.4) (2020-04-01)
|
|
25
|
+
|
|
26
|
+
|
|
27
|
+
### Bug Fixes
|
|
28
|
+
|
|
29
|
+
* Fix querystring encoding ([#1386](https://github.com/jantimon/html-webpack-plugin/issues/1386)) ([4f48a39](https://github.com/jantimon/html-webpack-plugin/commit/4f48a39e5738a5d431be2bec39c1b1f0de800d57)), closes [#1355](https://github.com/jantimon/html-webpack-plugin/issues/1355)
|
|
30
|
+
|
|
31
|
+
|
|
32
|
+
|
|
33
|
+
## [4.0.3](https://github.com/jantimon/html-webpack-plugin/compare/v4.0.2...v4.0.3) (2020-03-28)
|
|
34
|
+
|
|
35
|
+
|
|
36
|
+
### Bug Fixes
|
|
37
|
+
|
|
38
|
+
* add webpack, tapable and html-minifier-terser as dependencies because of types.d.ts ([238da81](https://github.com/jantimon/html-webpack-plugin/commit/238da8123950f87267954fd448f3e6b0fb1ead17))
|
|
39
|
+
|
|
40
|
+
|
|
41
|
+
|
|
5
42
|
## [4.0.2](https://github.com/jantimon/html-webpack-plugin/compare/v4.0.1...v4.0.2) (2020-03-26)
|
|
6
43
|
|
|
7
44
|
|
package/README.md
CHANGED
|
@@ -134,6 +134,7 @@ Allowed values are as follows
|
|
|
134
134
|
|**`title`**|`{String}`|`Webpack App`|The title to use for the generated HTML document|
|
|
135
135
|
|**`filename`**|`{String}`|`'index.html'`|The file to write the HTML to. Defaults to `index.html`. You can specify a subdirectory here too (eg: `assets/admin.html`)|
|
|
136
136
|
|**`template`**|`{String}`|``|`webpack` relative or absolute path to the template. By default it will use `src/index.ejs` if it exists. Please see the [docs](https://github.com/jantimon/html-webpack-plugin/blob/master/docs/template-option.md) for details|
|
|
137
|
+
|**`templateContent`**|`{string\|Function|false}`|false| Can be used instead of `template` to provide an inline template - please read the [Writing Your Own Templates](https://github.com/jantimon/html-webpack-plugin#writing-your-own-templates) section |
|
|
137
138
|
|**`templateParameters`**|`{Boolean\|Object\|Function}`|``| Allows to overwrite the parameters used in the template - see [example](https://github.com/jantimon/html-webpack-plugin/tree/master/examples/template-parameters) |
|
|
138
139
|
|**`inject`**|`{Boolean\|String}`|`true`|`true \|\| 'head' \|\| 'body' \|\| false` Inject all assets into the given `template` or `templateContent`. When passing `true` or `'body'` all javascript resources will be placed at the bottom of the body element. `'head'` will place the scripts in the head element - see the [inject:false example](https://github.com/jantimon/html-webpack-plugin/tree/master/examples/custom-insertion-position)|
|
|
139
140
|
|**`scriptLoading`**|`{'blocking'\|'defer'}`|`'blocking'`| Modern browsers support non blocking javascript loading (`'defer'`) to improve the page startup performance. |
|
|
@@ -243,40 +244,40 @@ plugins: [
|
|
|
243
244
|
|
|
244
245
|
You can use the `lodash` syntax out of the box. If the `inject` feature doesn't fit your needs and you want full control over the asset placement use the [default template](https://github.com/jaketrent/html-webpack-template/blob/86f285d5c790a6c15263f5cc50fd666d51f974fd/index.html) of the [html-webpack-template project](https://github.com/jaketrent/html-webpack-template) as a starting point for writing your own.
|
|
245
246
|
|
|
246
|
-
The following variables are available in the template:
|
|
247
|
+
The following variables are available in the template by default (you can extend them using the `templateParameters` option):
|
|
248
|
+
|
|
247
249
|
- `htmlWebpackPlugin`: data specific to this plugin
|
|
248
|
-
- `htmlWebpackPlugin.files`: a massaged representation of the
|
|
249
|
-
`assetsByChunkName` attribute of webpack's [stats](https://github.com/webpack/docs/wiki/node.js-api#stats)
|
|
250
|
-
object. It contains a mapping from entry point name to the bundle filename, eg:
|
|
251
|
-
```json
|
|
252
|
-
"htmlWebpackPlugin": {
|
|
253
|
-
"files": {
|
|
254
|
-
"css": [ "main.css" ],
|
|
255
|
-
"js": [ "assets/head_bundle.js", "assets/main_bundle.js"],
|
|
256
|
-
"chunks": {
|
|
257
|
-
"head": {
|
|
258
|
-
"entry": "assets/head_bundle.js",
|
|
259
|
-
"css": [ "main.css" ]
|
|
260
|
-
},
|
|
261
|
-
"main": {
|
|
262
|
-
"entry": "assets/main_bundle.js",
|
|
263
|
-
"css": []
|
|
264
|
-
},
|
|
265
|
-
}
|
|
266
|
-
}
|
|
267
|
-
}
|
|
268
|
-
```
|
|
269
|
-
If you've set a publicPath in your webpack config this will be reflected
|
|
270
|
-
correctly in this assets hash.
|
|
271
250
|
|
|
272
251
|
- `htmlWebpackPlugin.options`: the options hash that was passed to
|
|
273
252
|
the plugin. In addition to the options actually used by this plugin,
|
|
274
253
|
you can use this hash to pass arbitrary data through to your template.
|
|
275
254
|
|
|
276
|
-
- `
|
|
277
|
-
|
|
278
|
-
|
|
279
|
-
|
|
255
|
+
- `htmlWebpackPlugin.tags`: the prepared `headTags` and `bodyTags` Array to render the `<base>`, `<meta>`, `<script>` and `<link>` tags.
|
|
256
|
+
Can be used directly in templates and literals. For example:
|
|
257
|
+
```html
|
|
258
|
+
<html>
|
|
259
|
+
<head>
|
|
260
|
+
<%= htmlWebpackPlugin.tags.headTags %>
|
|
261
|
+
</head>
|
|
262
|
+
<body>
|
|
263
|
+
<%= htmlWebpackPlugin.tags.bodyTags %>
|
|
264
|
+
</body>
|
|
265
|
+
</html>
|
|
266
|
+
```
|
|
267
|
+
|
|
268
|
+
- `htmlWebpackPlugin.files`: direct access to the files used during the compilation.
|
|
269
|
+
|
|
270
|
+
```typescript
|
|
271
|
+
publicPath: string;
|
|
272
|
+
js: string[];
|
|
273
|
+
css: string[];
|
|
274
|
+
manifest?: string;
|
|
275
|
+
favicon?: string;
|
|
276
|
+
```
|
|
277
|
+
|
|
278
|
+
- `htmlWebpackPlugin.options`: the options hash that was passed to
|
|
279
|
+
the plugin. In addition to the options actually used by this plugin,
|
|
280
|
+
you can use this hash to pass arbitrary data through to your template.
|
|
280
281
|
|
|
281
282
|
- `webpackConfig`: the webpack configuration that was used for this compilation. This
|
|
282
283
|
can be used, for example, to get the `publicPath` (`webpackConfig.output.publicPath`).
|
|
@@ -287,6 +288,43 @@ The following variables are available in the template:
|
|
|
287
288
|
(see [the inline template example](examples/inline/template.pug)).
|
|
288
289
|
|
|
289
290
|
|
|
291
|
+
The template can also be directly inlined directly into the options object.
|
|
292
|
+
⚠️ **This approach does not allow to use weboack loaders for your template and will not update the template on changes**
|
|
293
|
+
|
|
294
|
+
**webpack.config.js**
|
|
295
|
+
```js
|
|
296
|
+
new HtmlWebpackPlugin({
|
|
297
|
+
templateContent: `
|
|
298
|
+
<html>
|
|
299
|
+
<body>
|
|
300
|
+
<h1>Hello World</h1>
|
|
301
|
+
</body>
|
|
302
|
+
</html>
|
|
303
|
+
`
|
|
304
|
+
})
|
|
305
|
+
```
|
|
306
|
+
|
|
307
|
+
The `templateContent` can also access all `templateParameters` values.
|
|
308
|
+
⚠️ **This approach does not allow to use weboack loaders for your template and will not update the template on changes**
|
|
309
|
+
|
|
310
|
+
**webpack.config.js**
|
|
311
|
+
```js
|
|
312
|
+
new HtmlWebpackPlugin({
|
|
313
|
+
injext: false
|
|
314
|
+
templateContent: ({htmlWebpackPlugin}) => `
|
|
315
|
+
<html>
|
|
316
|
+
<head>
|
|
317
|
+
${htmlWebpackPlugin.tags.headTags}
|
|
318
|
+
</head>
|
|
319
|
+
<body>
|
|
320
|
+
<h1>Hello World</h1>
|
|
321
|
+
${htmlWebpackPlugin.tags.bodyTags}
|
|
322
|
+
</body>
|
|
323
|
+
</html>
|
|
324
|
+
`
|
|
325
|
+
})
|
|
326
|
+
```
|
|
327
|
+
|
|
290
328
|
### Filtering Chunks
|
|
291
329
|
|
|
292
330
|
To include only certain chunks you can limit the chunks being used
|
package/index.js
CHANGED
|
@@ -16,10 +16,10 @@ const fs = require('fs');
|
|
|
16
16
|
const _ = require('lodash');
|
|
17
17
|
const path = require('path');
|
|
18
18
|
const loaderUtils = require('loader-utils');
|
|
19
|
+
const { CachedChildCompilation } = require('./lib/cached-child-compiler');
|
|
19
20
|
|
|
20
|
-
const { createHtmlTagObject, htmlTagObjectToString } = require('./lib/html-tags');
|
|
21
|
+
const { createHtmlTagObject, htmlTagObjectToString, HtmlTagArray } = require('./lib/html-tags');
|
|
21
22
|
|
|
22
|
-
const childCompiler = require('./lib/compiler.js');
|
|
23
23
|
const prettyError = require('./lib/errors.js');
|
|
24
24
|
const chunkSorter = require('./lib/chunksorter.js');
|
|
25
25
|
const getHtmlWebpackPluginHooks = require('./lib/hooks.js').getHtmlWebpackPluginHooks;
|
|
@@ -74,10 +74,6 @@ class HtmlWebpackPlugin {
|
|
|
74
74
|
// Instance variables to keep caching information
|
|
75
75
|
// for multiple builds
|
|
76
76
|
this.childCompilerHash = undefined;
|
|
77
|
-
/**
|
|
78
|
-
* @type {string | undefined}
|
|
79
|
-
*/
|
|
80
|
-
this.childCompilationOutputName = undefined;
|
|
81
77
|
this.assetJson = undefined;
|
|
82
78
|
this.hash = undefined;
|
|
83
79
|
this.version = HtmlWebpackPlugin.version;
|
|
@@ -89,12 +85,15 @@ class HtmlWebpackPlugin {
|
|
|
89
85
|
*/
|
|
90
86
|
apply (compiler) {
|
|
91
87
|
const self = this;
|
|
92
|
-
let isCompilationCached = false;
|
|
93
|
-
/** @type Promise<string> */
|
|
94
|
-
let compilationPromise;
|
|
95
88
|
|
|
96
89
|
this.options.template = this.getFullTemplatePath(this.options.template, compiler.context);
|
|
97
90
|
|
|
91
|
+
// Inject child compiler plugin
|
|
92
|
+
const childCompilerPlugin = new CachedChildCompilation(compiler);
|
|
93
|
+
if (!this.options.templateContent) {
|
|
94
|
+
childCompilerPlugin.addEntry(this.options.template);
|
|
95
|
+
}
|
|
96
|
+
|
|
98
97
|
// convert absolute filename into relative so that webpack can
|
|
99
98
|
// generate it at correct location
|
|
100
99
|
const filename = this.options.filename;
|
|
@@ -128,75 +127,42 @@ class HtmlWebpackPlugin {
|
|
|
128
127
|
};
|
|
129
128
|
}
|
|
130
129
|
|
|
131
|
-
// Clear the cache once a new HtmlWebpackPlugin is added
|
|
132
|
-
childCompiler.clearCache(compiler);
|
|
133
|
-
|
|
134
|
-
// Register all HtmlWebpackPlugins instances at the child compiler
|
|
135
|
-
compiler.hooks.thisCompilation.tap('HtmlWebpackPlugin', (compilation) => {
|
|
136
|
-
// Clear the cache if the child compiler is outdated
|
|
137
|
-
if (childCompiler.hasOutDatedTemplateCache(compilation)) {
|
|
138
|
-
childCompiler.clearCache(compiler);
|
|
139
|
-
}
|
|
140
|
-
// Add this instances template to the child compiler
|
|
141
|
-
childCompiler.addTemplateToCompiler(compiler, this.options.template);
|
|
142
|
-
// Add file dependencies of child compiler to parent compiler
|
|
143
|
-
// to keep them watched even if we get the result from the cache
|
|
144
|
-
compilation.hooks.additionalChunkAssets.tap('HtmlWebpackPlugin', () => {
|
|
145
|
-
const childCompilerDependencies = childCompiler.getFileDependencies(compiler);
|
|
146
|
-
childCompilerDependencies.forEach(fileDependency => {
|
|
147
|
-
compilation.compilationDependencies.add(fileDependency);
|
|
148
|
-
});
|
|
149
|
-
});
|
|
150
|
-
});
|
|
151
|
-
|
|
152
|
-
compiler.hooks.make.tapAsync('HtmlWebpackPlugin', (compilation, callback) => {
|
|
153
|
-
// Compile the template (queued)
|
|
154
|
-
compilationPromise = childCompiler.compileTemplate(self.options.template, self.options.filename, compilation)
|
|
155
|
-
.catch(err => {
|
|
156
|
-
compilation.errors.push(prettyError(err, compiler.context).toString());
|
|
157
|
-
return {
|
|
158
|
-
content: self.options.showErrors ? prettyError(err, compiler.context).toJsonHtml() : 'ERROR',
|
|
159
|
-
outputName: self.options.filename,
|
|
160
|
-
hash: ''
|
|
161
|
-
};
|
|
162
|
-
})
|
|
163
|
-
.then(compilationResult => {
|
|
164
|
-
// If the compilation change didnt change the cache is valid
|
|
165
|
-
isCompilationCached = Boolean(compilationResult.hash) && self.childCompilerHash === compilationResult.hash;
|
|
166
|
-
self.childCompilerHash = compilationResult.hash;
|
|
167
|
-
self.childCompilationOutputName = compilationResult.outputName;
|
|
168
|
-
callback();
|
|
169
|
-
return compilationResult.content;
|
|
170
|
-
});
|
|
171
|
-
});
|
|
172
|
-
|
|
173
130
|
compiler.hooks.emit.tapAsync('HtmlWebpackPlugin',
|
|
174
131
|
/**
|
|
175
132
|
* Hook into the webpack emit phase
|
|
176
133
|
* @param {WebpackCompilation} compilation
|
|
177
|
-
* @param {() => void} callback
|
|
134
|
+
* @param {(err?: Error) => void} callback
|
|
178
135
|
*/
|
|
179
136
|
(compilation, callback) => {
|
|
180
137
|
// Get all entry point names for this html file
|
|
181
138
|
const entryNames = Array.from(compilation.entrypoints.keys());
|
|
182
139
|
const filteredEntryNames = self.filterChunks(entryNames, self.options.chunks, self.options.excludeChunks);
|
|
183
140
|
const sortedEntryNames = self.sortEntryChunks(filteredEntryNames, this.options.chunksSortMode, compilation);
|
|
184
|
-
const childCompilationOutputName = self.childCompilationOutputName;
|
|
185
141
|
|
|
186
|
-
|
|
187
|
-
|
|
142
|
+
const templateResult = this.options.templateContent
|
|
143
|
+
? { mainCompilationHash: compilation.hash }
|
|
144
|
+
: childCompilerPlugin.getCompilationEntryResult(this.options.template);
|
|
145
|
+
|
|
146
|
+
this.childCompilerHash = templateResult.mainCompilationHash;
|
|
147
|
+
|
|
148
|
+
if ('error' in templateResult) {
|
|
149
|
+
compilation.errors.push(prettyError(templateResult.error, compiler.context).toString());
|
|
188
150
|
}
|
|
189
151
|
|
|
152
|
+
const childCompilationOutputName = compilation.mainTemplate.getAssetPath(this.options.filename, 'compiledEntry' in templateResult ? {
|
|
153
|
+
hash: templateResult.compiledEntry.hash,
|
|
154
|
+
chunk: templateResult.compiledEntry.entry
|
|
155
|
+
} : {
|
|
156
|
+
hash: templateResult.mainCompilationHash
|
|
157
|
+
});
|
|
158
|
+
|
|
159
|
+
// If the child compilation was not executed during a previous main compile run
|
|
160
|
+
// it is a cached result
|
|
161
|
+
const isCompilationCached = templateResult.mainCompilationHash !== compilation.hash;
|
|
162
|
+
|
|
190
163
|
// Turn the entry point names into file paths
|
|
191
164
|
const assets = self.htmlWebpackPluginAssets(compilation, childCompilationOutputName, sortedEntryNames);
|
|
192
165
|
|
|
193
|
-
// If this is a hot update compilation, move on!
|
|
194
|
-
// This solves a problem where an `index.html` file is generated for hot-update js files
|
|
195
|
-
// It only happens in Webpack 2, where hot updates are emitted separately before the full bundle
|
|
196
|
-
if (self.isHotUpdateCompilation(assets)) {
|
|
197
|
-
return callback();
|
|
198
|
-
}
|
|
199
|
-
|
|
200
166
|
// If the template and the assets did not change we don't have to emit the html
|
|
201
167
|
const assetJson = JSON.stringify(self.getAssetFiles(assets));
|
|
202
168
|
if (isCompilationCached && self.options.cache && assetJson === self.assetJson) {
|
|
@@ -249,15 +215,20 @@ class HtmlWebpackPlugin {
|
|
|
249
215
|
});
|
|
250
216
|
|
|
251
217
|
// Turn the compiled tempalte into a nodejs function or into a nodejs string
|
|
252
|
-
const templateEvaluationPromise =
|
|
253
|
-
.then(
|
|
218
|
+
const templateEvaluationPromise = Promise.resolve()
|
|
219
|
+
.then(() => {
|
|
220
|
+
if ('error' in templateResult) {
|
|
221
|
+
return self.options.showErrors ? prettyError(templateResult.error, compiler.context).toHtml() : 'ERROR';
|
|
222
|
+
}
|
|
254
223
|
// Allow to use a custom function / string instead
|
|
255
224
|
if (self.options.templateContent !== false) {
|
|
256
225
|
return self.options.templateContent;
|
|
257
226
|
}
|
|
258
227
|
// Once everything is compiled evaluate the html factory
|
|
259
228
|
// and replace it with its content
|
|
260
|
-
return
|
|
229
|
+
return ('compiledEntry' in templateResult)
|
|
230
|
+
? self.evaluateCompilationResult(compilation, templateResult.compiledEntry.content)
|
|
231
|
+
: Promise.reject(new Error('Child compilation contained no compiledEntry'));
|
|
261
232
|
});
|
|
262
233
|
|
|
263
234
|
const templateExectutionPromise = Promise.all([assetsPromise, assetTagGroupsPromise, templateEvaluationPromise])
|
|
@@ -851,17 +822,13 @@ class HtmlWebpackPlugin {
|
|
|
851
822
|
*/
|
|
852
823
|
prepareAssetTagGroupForRendering (assetTagGroup) {
|
|
853
824
|
const xhtml = this.options.xhtml;
|
|
854
|
-
|
|
825
|
+
return HtmlTagArray.from(assetTagGroup.map((assetTag) => {
|
|
855
826
|
const copiedAssetTag = Object.assign({}, assetTag);
|
|
856
827
|
copiedAssetTag.toString = function () {
|
|
857
828
|
return htmlTagObjectToString(this, xhtml);
|
|
858
829
|
};
|
|
859
830
|
return copiedAssetTag;
|
|
860
|
-
});
|
|
861
|
-
preparedTags.toString = function () {
|
|
862
|
-
return this.join('');
|
|
863
|
-
};
|
|
864
|
-
return preparedTags;
|
|
831
|
+
}));
|
|
865
832
|
}
|
|
866
833
|
|
|
867
834
|
/**
|
|
@@ -939,10 +906,35 @@ class HtmlWebpackPlugin {
|
|
|
939
906
|
* Encode each path component using `encodeURIComponent` as files can contain characters
|
|
940
907
|
* which needs special encoding in URLs like `+ `.
|
|
941
908
|
*
|
|
909
|
+
* Valid filesystem characters which need to be encoded for urls:
|
|
910
|
+
*
|
|
911
|
+
* # pound, % percent, & ampersand, { left curly bracket, } right curly bracket,
|
|
912
|
+
* \ back slash, < left angle bracket, > right angle bracket, * asterisk, ? question mark,
|
|
913
|
+
* blank spaces, $ dollar sign, ! exclamation point, ' single quotes, " double quotes,
|
|
914
|
+
* : colon, @ at sign, + plus sign, ` backtick, | pipe, = equal sign
|
|
915
|
+
*
|
|
916
|
+
* However the query string must not be encoded:
|
|
917
|
+
*
|
|
918
|
+
* fo:demonstration-path/very fancy+name.js?path=/home?value=abc&value=def#zzz
|
|
919
|
+
* ^ ^ ^ ^ ^ ^ ^ ^^ ^ ^ ^ ^ ^
|
|
920
|
+
* | | | | | | | || | | | | |
|
|
921
|
+
* encoded | | encoded | | || | | | | |
|
|
922
|
+
* ignored ignored ignored ignored ignored
|
|
923
|
+
*
|
|
942
924
|
* @param {string} filePath
|
|
943
925
|
*/
|
|
944
926
|
urlencodePath (filePath) {
|
|
945
|
-
|
|
927
|
+
// People use the filepath in quite unexpected ways.
|
|
928
|
+
// Try to extract the first querystring of the url:
|
|
929
|
+
//
|
|
930
|
+
// some+path/demo.html?value=abc?def
|
|
931
|
+
//
|
|
932
|
+
const queryStringStart = filePath.indexOf('?');
|
|
933
|
+
const urlPath = queryStringStart === -1 ? filePath : filePath.substr(0, queryStringStart);
|
|
934
|
+
const queryString = filePath.substr(urlPath.length);
|
|
935
|
+
// Encode all parts except '/' which are not part of the querystring:
|
|
936
|
+
const encodedUrlPath = urlPath.split('/').map(encodeURIComponent).join('/');
|
|
937
|
+
return encodedUrlPath + queryString;
|
|
946
938
|
}
|
|
947
939
|
|
|
948
940
|
/**
|