@elken/next-offline
Version:
<h1 align="center"> next-offline </h1>
97 lines (85 loc) • 3.49 kB
JavaScript
const { GenerateSW, InjectManifest } = require('workbox-webpack-plugin');
const CleanWebpackPlugin = require('clean-webpack-plugin');
const CopyWebpackPlugin = require('copy-webpack-plugin');
const { readFile, writeFile } = require('fs-extra');
const { join } = require('path');
const InlineNextPrecacheManifestPlugin = require('./plugin');
const ExtraCodeApply = require('./extraCodeApply');
const exportSw = require('./export');
module.exports = (nextConfig = {}) => ({
...nextConfig,
exportPathMap: exportSw(nextConfig),
webpack(config, options) {
if (!options.defaultLoaders) {
throw new Error(
'This plugin is not compatible with Next.js versions below 5.0.0 https://err.sh/next-plugins/upgrade',
);
}
const {
assetPrefix,
extraCodePath,
registerOverridePath,
generateSw = true,
dontAutoRegisterSw = false,
devSwSrc = join(__dirname, 'service-worker.js'),
registerSwPrefix = '',
scope = '/',
generateInDevMode = false,
workboxOpts = {
globPatterns: ['static/**/*'],
globDirectory: '.',
runtimeCaching: [{ urlPattern: /^https?.*/, handler: 'networkFirst' }],
},
} = nextConfig;
const skipDuringDevelopment = options.dev && !generateInDevMode
// Generate SW
if (skipDuringDevelopment) {
// Simply copy development service worker.
config.plugins.push(new CopyWebpackPlugin([devSwSrc]));
} else if (!options.isServer) {
// Only run once for the client build.
config.plugins.push(
new CleanWebpackPlugin(['precache-manifest.*.js'], { root: config.output.path, verbose: false }),
generateSw ? new GenerateSW({ ...workboxOpts }) : new InjectManifest({ ...workboxOpts }),
new InlineNextPrecacheManifestPlugin({
outputPath: config.output.path,
urlPrefix: assetPrefix,
swDest: workboxOpts.swDest || 'service-worker.js',
}),
new ExtraCodeApply({
outputPath: config.output.path,
baseDir: config.context,
urlPrefix: assetPrefix,
swDest: workboxOpts.swDest || 'service-worker.js',
extraCodePath,
})
);
}
if (!skipDuringDevelopment) {
// Register SW
const originalEntry = config.entry;
config.entry = async () => {
const entries = await originalEntry();
const swCompiledPath = join(__dirname, 'register-sw-compiled.js')
// See https://github.com/zeit/next.js/blob/canary/examples/with-polyfills/next.config.js for a reference on how to add new entrypoints
if (
entries['main.js'] &&
!entries['main.js'].includes(swCompiledPath) &&
!dontAutoRegisterSw
) {
const contentPath = (registerOverridePath && join(config.context, registerOverridePath)) || './register-sw.js';
let content = await readFile(require.resolve(contentPath), 'utf8');
content = content.replace('{REGISTER_SW_PREFIX}', registerSwPrefix);
content = content.replace('{SW_SCOPE}', scope);
await writeFile(swCompiledPath, content, 'utf8');
entries['main.js'].unshift(swCompiledPath);
}
return entries;
};
}
if (typeof nextConfig.webpack === 'function') {
return nextConfig.webpack(config, options);
}
return config;
},
});