UNPKG

@expo/webpack-config

Version:

The default Webpack configuration used to build Expo apps targeting the web.

118 lines 5.44 kB
"use strict"; var __awaiter = (this && this.__awaiter) || function (thisArg, _arguments, P, generator) { function adopt(value) { return value instanceof P ? value : new P(function (resolve) { resolve(value); }); } return new (P || (P = Promise))(function (resolve, reject) { function fulfilled(value) { try { step(generator.next(value)); } catch (e) { reject(e); } } function rejected(value) { try { step(generator["throw"](value)); } catch (e) { reject(e); } } function step(result) { result.done ? resolve(result.value) : adopt(result.value).then(fulfilled, rejected); } step((generator = generator.apply(thisArg, _arguments || [])).next()); }); }; var __importDefault = (this && this.__importDefault) || function (mod) { return (mod && mod.__esModule) ? mod : { "default": mod }; }; Object.defineProperty(exports, "__esModule", { value: true }); const paths_1 = require("@expo/config/paths"); const copy_webpack_plugin_1 = __importDefault(require("copy-webpack-plugin")); const fs_extra_1 = require("fs-extra"); const path_1 = require("path"); const workbox_webpack_plugin_1 = require("workbox-webpack-plugin"); const env_1 = require("../env"); const utils_1 = require("../utils"); const defaultInjectManifestOptions = { exclude: [ /\.LICENSE$/, /\.map$/, /asset-manifest\.json$/, /\.js\.gz$/, ], }; const runtimeCache = { handler: 'networkFirst', urlPattern: /^https?.*/, options: { cacheName: 'offlineCache', expiration: { maxEntries: 200, }, }, }; const defaultGenerateSWOptions = Object.assign(Object.assign({}, defaultInjectManifestOptions), { clientsClaim: true, skipWaiting: true, navigateFallbackBlacklist: [ // Exclude URLs starting with /_, as they're likely an API call new RegExp('^/_'), // Exclude URLs containing a dot, as they're likely a resource in // public/ and not a SPA route new RegExp('/[^/]+\\.[^/]+$'), ], // @ts-ignore: Webpack throws if `NetworkFirst` is not `networkFirst` runtimeCaching: [runtimeCache] }); /** * Add offline support to the provided Webpack config. * * @param webpackConfig Existing Webpack config to modify. * @param options configure the service worker. * @category addons */ function withWorkbox(webpackConfig, options = {}) { if (!webpackConfig.plugins) webpackConfig.plugins = []; const { projectRoot, autoRegister = true, publicUrl = '', scope, useServiceWorker = true, generateSWOptions = {}, injectManifestOptions = {}, } = options; const locations = env_1.getPaths(projectRoot); webpackConfig.plugins.push(new copy_webpack_plugin_1.default([ { from: locations.template.registerServiceWorker, to: locations.production.registerServiceWorker, transform(content) { return content .toString() .replace('SW_PUBLIC_URL', publicUrl) .replace('SW_PUBLIC_SCOPE', paths_1.ensureSlash(scope || publicUrl, true)); }, }, ])); // Always register general service worker const expoEntry = webpackConfig.entry; webpackConfig.entry = () => __awaiter(this, void 0, void 0, function* () { const entries = yield utils_1.resolveEntryAsync(expoEntry); const swPath = path_1.join(locations.production.registerServiceWorker); if (entries.app && !entries.app.includes(swPath) && autoRegister) { let content = fs_extra_1.readFileSync(require.resolve(locations.template.registerServiceWorker), 'utf8'); if (content) { content = content .replace('SW_PUBLIC_URL', publicUrl) .replace('SW_PUBLIC_SCOPE', paths_1.ensureSlash(scope || publicUrl, true)); fs_extra_1.ensureDirSync(locations.production.folder); } else { content = ` console.warn("failed to load service-worker in @expo/webpack-config -> withWorkbox(). This can be due to the environment the project was built in. Please try again with a globally installed instance of expo-cli. If you continue to run into problems open an issue in https://github.com/expo/expo-cli") `; } fs_extra_1.writeFileSync(swPath, content, 'utf8'); if (!Array.isArray(entries.app)) { entries.app = [entries.app]; } entries.app.unshift(swPath); } return entries; }); // ... but do not register Workbox in development if (webpackConfig.mode !== 'production') { return webpackConfig; } const customManifestProps = { navigateFallback: path_1.join(publicUrl, 'index.html'), }; if (useServiceWorker) { webpackConfig.plugins.push(new workbox_webpack_plugin_1.GenerateSW(Object.assign(Object.assign(Object.assign({}, defaultGenerateSWOptions), customManifestProps), generateSWOptions))); } else { const props = Object.assign(Object.assign(Object.assign({}, defaultInjectManifestOptions), customManifestProps), injectManifestOptions); webpackConfig.plugins.push( // @ts-ignore: unused swSrc new workbox_webpack_plugin_1.InjectManifest(props)); } return webpackConfig; } exports.default = withWorkbox; //# sourceMappingURL=withWorkbox.js.map