source: frontend/node_modules/workbox-build/src/inject-manifest.ts

Last change on this file was 9af201e, checked in by MBK <marija.karapandzova@…>, 12 days ago

Fix frontend appearance

  • Property mode set to 100644
File size: 5.2 KB
Line 
1/*
2 Copyright 2018 Google LLC
3
4 Use of this source code is governed by an MIT-style
5 license that can be found in the LICENSE file or at
6 https://opensource.org/licenses/MIT.
7*/
8
9import {RawSourceMap} from 'source-map';
10import assert from 'assert';
11import fse from 'fs-extra';
12import stringify from 'fast-json-stable-stringify';
13import upath from 'upath';
14
15import {BuildResult, InjectManifestOptions} from './types';
16import {errors} from './lib/errors';
17import {escapeRegExp} from './lib/escape-regexp';
18import {getFileManifestEntries} from './lib/get-file-manifest-entries';
19import {getSourceMapURL} from './lib/get-source-map-url';
20import {rebasePath} from './lib/rebase-path';
21import {replaceAndUpdateSourceMap} from './lib/replace-and-update-source-map';
22import {translateURLToSourcemapPaths} from './lib/translate-url-to-sourcemap-paths';
23import {validateInjectManifestOptions} from './lib/validate-options';
24
25/**
26 * This method creates a list of URLs to precache, referred to as a "precache
27 * manifest", based on the options you provide.
28 *
29 * The manifest is injected into the `swSrc` file, and the placeholder string
30 * `injectionPoint` determines where in the file the manifest should go.
31 *
32 * The final service worker file, with the manifest injected, is written to
33 * disk at `swDest`.
34 *
35 * This method will not compile or bundle your `swSrc` file; it just handles
36 * injecting the manifest.
37 *
38 * ```
39 * // The following lists some common options; see the rest of the documentation
40 * // for the full set of options and defaults.
41 * const {count, size, warnings} = await injectManifest({
42 * dontCacheBustURLsMatching: [new RegExp('...')],
43 * globDirectory: '...',
44 * globPatterns: ['...', '...'],
45 * maximumFileSizeToCacheInBytes: ...,
46 * swDest: '...',
47 * swSrc: '...',
48 * });
49 * ```
50 *
51 * @memberof workbox-build
52 */
53export async function injectManifest(
54 config: InjectManifestOptions,
55): Promise<BuildResult> {
56 const options = validateInjectManifestOptions(config);
57
58 // Make sure we leave swSrc and swDest out of the precache manifest.
59 for (const file of [options.swSrc, options.swDest]) {
60 options.globIgnores!.push(
61 rebasePath({
62 file,
63 baseDirectory: options.globDirectory,
64 }),
65 );
66 }
67
68 const globalRegexp = new RegExp(escapeRegExp(options.injectionPoint!), 'g');
69
70 const {count, size, manifestEntries, warnings} = await getFileManifestEntries(
71 options,
72 );
73 let swFileContents: string;
74 try {
75 swFileContents = await fse.readFile(options.swSrc, 'utf8');
76 } catch (error) {
77 throw new Error(
78 `${errors['invalid-sw-src']} ${
79 error instanceof Error && error.message ? error.message : ''
80 }`,
81 );
82 }
83
84 const injectionResults = swFileContents.match(globalRegexp);
85 // See https://github.com/GoogleChrome/workbox/issues/2230
86 const injectionPoint = options.injectionPoint ? options.injectionPoint : '';
87 if (!injectionResults) {
88 if (upath.resolve(options.swSrc) === upath.resolve(options.swDest)) {
89 throw new Error(`${errors['same-src-and-dest']} ${injectionPoint}`);
90 }
91 throw new Error(`${errors['injection-point-not-found']} ${injectionPoint}`);
92 }
93
94 assert(
95 injectionResults.length === 1,
96 `${errors['multiple-injection-points']} ${injectionPoint}`,
97 );
98
99 const manifestString = stringify(manifestEntries);
100 const filesToWrite: {[key: string]: string} = {};
101
102 const url = getSourceMapURL(swFileContents);
103 // See https://github.com/GoogleChrome/workbox/issues/2957
104 const {destPath, srcPath, warning} = translateURLToSourcemapPaths(
105 url,
106 options.swSrc,
107 options.swDest,
108 );
109 if (warning) {
110 warnings.push(warning);
111 }
112
113 // If our swSrc file contains a sourcemap, we would invalidate that
114 // mapping if we just replaced injectionPoint with the stringified manifest.
115 // Instead, we need to update the swDest contents as well as the sourcemap
116 // (assuming it's a real file, not a data: URL) at the same time.
117 // See https://github.com/GoogleChrome/workbox/issues/2235
118 // and https://github.com/GoogleChrome/workbox/issues/2648
119 if (srcPath && destPath) {
120 const originalMap = (await fse.readJSON(srcPath, {
121 encoding: 'utf8',
122 })) as RawSourceMap;
123
124 const {map, source} = await replaceAndUpdateSourceMap({
125 originalMap,
126 jsFilename: upath.basename(options.swDest),
127 originalSource: swFileContents,
128 replaceString: manifestString,
129 searchString: options.injectionPoint!,
130 });
131
132 filesToWrite[options.swDest] = source;
133 filesToWrite[destPath] = map;
134 } else {
135 // If there's no sourcemap associated with swSrc, a simple string
136 // replacement will suffice.
137 filesToWrite[options.swDest] = swFileContents.replace(
138 globalRegexp,
139 manifestString,
140 );
141 }
142
143 for (const [file, contents] of Object.entries(filesToWrite)) {
144 try {
145 await fse.mkdirp(upath.dirname(file));
146 } catch (error: unknown) {
147 throw new Error(
148 errors['unable-to-make-sw-directory'] +
149 ` '${error instanceof Error && error.message ? error.message : ''}'`,
150 );
151 }
152
153 await fse.writeFile(file, contents);
154 }
155
156 return {
157 count,
158 size,
159 warnings,
160 // Use upath.resolve() to make all the paths absolute.
161 filePaths: Object.keys(filesToWrite).map((f) => upath.resolve(f)),
162 };
163}
Note: See TracBrowser for help on using the repository browser.