@expo/webpack-config
Version:
The default Webpack configuration used to build Expo apps targeting the web.
118 lines • 5.44 kB
JavaScript
;
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