From 165f4c398ae5f58e6586501db778a0a0ca8ade2c Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Ng=C3=B4=20=C4=90=E1=BB=A9c=20Anh?= <75556609+DuCanhGH@users.noreply.github.com> Date: Tue, 11 Jul 2023 19:39:21 +0700 Subject: [PATCH] feat: use Next's webpack instead of importing a new one (#53) [bump] --- .changeset/friendly-pumas-march.md | 7 + .eslintrc.cjs | 88 ++++++++++-- docs/content/next-pwa/getting-started.mdx | 2 +- docs/src/app/(home)/code-showcase.mdx | 4 +- docs/src/app/(home)/constants.ts | 2 +- examples/basic/package.json | 3 +- examples/custom-server/package.json | 3 +- examples/custom-worker/package.json | 3 +- examples/lifecycle/package.json | 3 +- examples/next-i18next/package.json | 3 +- examples/next-image/package.json | 3 +- examples/offline-fallback-v2/package.json | 3 +- examples/web-push/package.json | 3 +- package.json | 4 +- packages/constants/package.json | 2 +- packages/next-pwa/README.md | 2 +- packages/next-pwa/package.json | 7 +- packages/next-pwa/rollup.config.js | 3 +- packages/next-pwa/src/index.ts | 9 +- .../next-pwa/src/resolve-runtime-caching.ts | 2 +- packages/next-pwa/src/swc-loader.ts | 2 +- .../webpack-builders/build-custom-worker.ts | 7 +- .../webpack-builders/build-fallback-worker.ts | 6 +- .../webpack-builders/build-sw-entry-worker.ts | 6 +- .../get-default-document-page.ts | 2 +- .../src/webpack-builders/get-fallback-envs.ts | 2 +- .../next-pwa/src/webpack-builders/utils.ts | 2 +- packages/next-sw/package.json | 4 +- packages/next-sw/rollup.config.js | 9 +- .../src/build/generate-sw/core-utils.ts | 2 +- .../next-sw/src/build/generate-sw/core.ts | 2 +- .../get-manifest-entries-from-compilation.ts | 15 +- .../src/build/generate-sw/webpack-plugin.ts | 9 +- packages/next-sw/src/index.ts | 2 +- packages/next-sw/src/swc-loader.ts | 2 +- packages/test-utils/package.json | 3 +- packages/test-utils/src/next-instance-base.ts | 6 +- packages/utils/package.json | 4 +- packages/utils/rollup.config.js | 2 +- pnpm-lock.yaml | 134 ++++-------------- pnpm-workspace.yaml | 1 + 41 files changed, 189 insertions(+), 189 deletions(-) create mode 100644 .changeset/friendly-pumas-march.md diff --git a/.changeset/friendly-pumas-march.md b/.changeset/friendly-pumas-march.md new file mode 100644 index 00000000..f2252a1d --- /dev/null +++ b/.changeset/friendly-pumas-march.md @@ -0,0 +1,7 @@ +--- +"@ducanh2912/next-pwa": minor +--- + +feat: use Next's webpack instead of importing a new one + +- `next-pwa` should now use Next's webpack instance to avoid having multiple webpack copies. diff --git a/.eslintrc.cjs b/.eslintrc.cjs index 535bb53a..09677d7b 100644 --- a/.eslintrc.cjs +++ b/.eslintrc.cjs @@ -1,4 +1,24 @@ // @ts-check +const path = require("node:path"); + +const fg = require("fast-glob"); + +const TSCONFIG_SOURCES = /** @type {const} */ ([ + "tsconfig.json", + "tsconfig.eslint.json", + "docs/tsconfig.json", + "packages/*/tsconfig.json", + "packages/*/__tests__/tsconfig.json", + "examples/*/tsconfig.json", +]); + +let packageDirs = fg + .sync("packages/*", { + cwd: __dirname, + onlyDirectories: true, + }) + .map((dir) => path.join(__dirname, dir)); + /** @type {import("eslint").Linter.BaseConfig} */ module.exports = { parser: "@typescript-eslint/parser", @@ -11,21 +31,17 @@ module.exports = { "next/core-web-vitals", "eslint:recommended", "plugin:@typescript-eslint/recommended", + "plugin:import/recommended", + "plugin:import/typescript", "turbo", "prettier", ], parserOptions: { tsconfigRootDir: __dirname, - project: [ - "tsconfig.json", - "tsconfig.eslint.json", - "docs/tsconfig.json", - "packages/*/tsconfig.json", - "packages/*/__tests__/tsconfig.json", - "examples/*/tsconfig.json", - ], + project: TSCONFIG_SOURCES, ecmaVersion: "latest", sourceType: "module", + warnOnUnsupportedTypeScriptVersion: false, }, plugins: ["@typescript-eslint", "simple-import-sort"], rules: { @@ -33,7 +49,19 @@ module.exports = { "@typescript-eslint/no-explicit-any": "off", "@typescript-eslint/no-var-requires": "off", "@typescript-eslint/consistent-type-imports": "warn", - "@typescript-eslint/no-unused-vars": ["warn", { ignoreRestSiblings: true }], + "@typescript-eslint/no-unused-vars": [ + "warn", + { + ignoreRestSiblings: true, + varsIgnorePattern: "^_", + argsIgnorePattern: "^_", + }, + ], + "import/no-extraneous-dependencies": "off", + // Doesn't really work with VSCode... + "import/no-unresolved": "off", + "import/no-named-as-default": "off", + "import/no-named-as-default-member": "off", "no-unused-vars": "off", "no-extra-boolean-cast": "off", "simple-import-sort/imports": "warn", @@ -45,4 +73,46 @@ module.exports = { }, ], }, + settings: { + "import/parsers": { + "@typescript-eslint/parser": [".ts", ".tsx", ".mjs", ".cjs", ".js"], + }, + "import/resolver": { + typescript: { + alwaysTryTypes: true, + project: TSCONFIG_SOURCES, + }, + }, + "import/internal-regex": "^@ducanh2912/", + "import/external-module-folders": [ + "packages/next-pwa", + "packages/next-sw", + "packages/utils", + "packages/constants", + "node_modules", + ], + next: { + rootDir: ["./docs/", "./examples/*/"], + }, + }, + overrides: [ + { + files: ["packages/*/__tests__/**"], + env: { + jest: true, + }, + }, + { + files: ["packages/**"], + rules: { + "import/no-extraneous-dependencies": [ + "error", + { + devDependencies: ["__tests__/**", "**/*.config.{cjs,mjs,js,ts}"], + packageDir: [__dirname, ...packageDirs], + }, + ], + }, + }, + ], }; diff --git a/docs/content/next-pwa/getting-started.mdx b/docs/content/next-pwa/getting-started.mdx index f4ef6e39..394f619d 100644 --- a/docs/content/next-pwa/getting-started.mdx +++ b/docs/content/next-pwa/getting-started.mdx @@ -123,7 +123,7 @@ export default nextConfigFunction; - **Note**: This plugin is written in Typescript and supports JSDoc. It is + **Note**: This plugin is written in TypeScript and supports JSDoc. It is recommended to add `// @ts-check` to the top of your `next.config.js` file to leverage typechecking. This is especially useful when you use `PluginOptions.workboxOptions`, as you may unknowningly mix diff --git a/docs/src/app/(home)/code-showcase.mdx b/docs/src/app/(home)/code-showcase.mdx index f127cf0d..91b3530d 100644 --- a/docs/src/app/(home)/code-showcase.mdx +++ b/docs/src/app/(home)/code-showcase.mdx @@ -35,9 +35,9 @@ module.exports = withPWA({ }); ``` -## Typescript support +## TypeScript support -`next-pwa` is built with Typescript. As you configure `next-pwa`, you will get type hints and detailed description of its options. If you directly wrap your +`next-pwa` is built with TypeScript. As you configure `next-pwa`, you will get type hints and detailed description of its options. If you directly wrap your Next config with `withPWA`, it will automatically be typed with `NextConfig`! diff --git a/docs/src/app/(home)/constants.ts b/docs/src/app/(home)/constants.ts index a13c0b24..b12d44cd 100644 --- a/docs/src/app/(home)/constants.ts +++ b/docs/src/app/(home)/constants.ts @@ -30,6 +30,6 @@ export const FEATURES_LIST: Feature[] = [ icon: "🚀", label: "Developer experience", description: - "Built-in Typescript definitions and JSDoc to enable the best DX.", + "Built-in TypeScript definitions and JSDoc to enable the best DX.", }, ]; diff --git a/examples/basic/package.json b/examples/basic/package.json index ce1eb6cd..40723db4 100644 --- a/examples/basic/package.json +++ b/examples/basic/package.json @@ -19,7 +19,6 @@ "@types/node": "20.3.2", "@types/react": "18.2.14", "@types/react-dom": "18.2.6", - "typescript": "5.1.6", - "webpack": "5.88.1" + "typescript": "5.1.6" } } diff --git a/examples/custom-server/package.json b/examples/custom-server/package.json index 7d815882..d1a245e9 100644 --- a/examples/custom-server/package.json +++ b/examples/custom-server/package.json @@ -26,7 +26,6 @@ "nodemon": "2.0.22", "rimraf": "5.0.1", "ts-node": "10.9.1", - "typescript": "5.1.6", - "webpack": "5.88.1" + "typescript": "5.1.6" } } diff --git a/examples/custom-worker/package.json b/examples/custom-worker/package.json index ce94d524..8048df29 100644 --- a/examples/custom-worker/package.json +++ b/examples/custom-worker/package.json @@ -19,7 +19,6 @@ "@types/node": "20.3.2", "@types/react": "18.2.14", "@types/react-dom": "18.2.6", - "typescript": "5.1.6", - "webpack": "5.88.1" + "typescript": "5.1.6" } } diff --git a/examples/lifecycle/package.json b/examples/lifecycle/package.json index 2ba95c00..9cd91e67 100644 --- a/examples/lifecycle/package.json +++ b/examples/lifecycle/package.json @@ -19,7 +19,6 @@ "@types/node": "20.3.2", "@types/react": "18.2.14", "@types/react-dom": "18.2.6", - "typescript": "5.1.6", - "webpack": "5.88.1" + "typescript": "5.1.6" } } diff --git a/examples/next-i18next/package.json b/examples/next-i18next/package.json index afd47a1b..8f345107 100644 --- a/examples/next-i18next/package.json +++ b/examples/next-i18next/package.json @@ -25,7 +25,6 @@ "@types/node": "20.3.2", "@types/react": "18.2.14", "@types/react-dom": "18.2.6", - "typescript": "5.1.6", - "webpack": "5.88.1" + "typescript": "5.1.6" } } diff --git a/examples/next-image/package.json b/examples/next-image/package.json index c738a2a7..b02dc65e 100644 --- a/examples/next-image/package.json +++ b/examples/next-image/package.json @@ -19,7 +19,6 @@ "@types/node": "20.3.2", "@types/react": "18.2.14", "@types/react-dom": "18.2.6", - "typescript": "5.1.6", - "webpack": "5.88.1" + "typescript": "5.1.6" } } diff --git a/examples/offline-fallback-v2/package.json b/examples/offline-fallback-v2/package.json index f1e6adfe..097d6b64 100644 --- a/examples/offline-fallback-v2/package.json +++ b/examples/offline-fallback-v2/package.json @@ -20,7 +20,6 @@ "@types/node": "20.3.2", "@types/react": "18.2.14", "@types/react-dom": "18.2.6", - "typescript": "5.1.6", - "webpack": "5.88.1" + "typescript": "5.1.6" } } diff --git a/examples/web-push/package.json b/examples/web-push/package.json index f1c6f3aa..8f9aa11a 100644 --- a/examples/web-push/package.json +++ b/examples/web-push/package.json @@ -22,7 +22,6 @@ "@types/react": "18.2.14", "@types/react-dom": "18.2.6", "@types/web-push": "3.3.2", - "typescript": "5.1.6", - "webpack": "5.88.1" + "typescript": "5.1.6" } } diff --git a/package.json b/package.json index 7eec6ee6..ef5c4ba2 100644 --- a/package.json +++ b/package.json @@ -43,6 +43,7 @@ "eslint-config-next": "13.4.7", "eslint-config-prettier": "8.8.0", "eslint-config-turbo": "1.10.6", + "eslint-plugin-import": "2.27.5", "eslint-plugin-simple-import-sort": "10.0.0", "fast-glob": "3.2.12", "husky": "8.0.3", @@ -55,8 +56,7 @@ "shell-quote": "1.8.1", "tslib": "2.6.0", "turbo": "1.10.3", - "typescript": "5.2.0-dev.20230628", - "webpack": "5.88.1" + "typescript": "5.2.0-dev.20230628" }, "packageManager": "pnpm@8.6.2" } diff --git a/packages/constants/package.json b/packages/constants/package.json index f740b2a8..fec473c7 100644 --- a/packages/constants/package.json +++ b/packages/constants/package.json @@ -1,5 +1,5 @@ { - "name": "constants", + "name": "@ducanh2912/constants", "version": "0.0.0", "private": true, "license": "MIT", diff --git a/packages/next-pwa/README.md b/packages/next-pwa/README.md index e9717f50..f02e1ae8 100644 --- a/packages/next-pwa/README.md +++ b/packages/next-pwa/README.md @@ -13,7 +13,7 @@ This plugin is powered by [Workbox](https://developer.chrome.com/docs/workbox/) - 🎈 Easy-to-understand examples. - 📴 Offline support [(you can also provide fallbacks for when fetching fails)](/examples/offline-fallback-v2). - 🔉 Default range requests for audios and videos. -- 📐 [Custom worker to run your own code (also supports path aliases, Typescript and code splitting!).](/examples/custom-worker) +- 📐 [Custom worker to run your own code (also supports path aliases, TypeScript and code splitting!).](/examples/custom-worker) - 📜 [Public environment variables](https://nextjs.org/docs/app/building-your-application/configuring/environment-variables) are available in custom workers. - 🐞 Debug service worker in development mode. - 🌏 [Internationalization support with `next-i18next`.](/examples/next-i18next) diff --git a/packages/next-pwa/package.json b/packages/next-pwa/package.json index f737e623..ee6bb2d3 100644 --- a/packages/next-pwa/package.json +++ b/packages/next-pwa/package.json @@ -67,6 +67,8 @@ "workbox-window": "7.0.0" }, "devDependencies": { + "@ducanh2912/constants": "workspace:*", + "@ducanh2912/utils": "workspace:*", "@rollup/plugin-alias": "5.0.0", "@rollup/plugin-json": "6.0.0", "@rollup/plugin-node-resolve": "15.1.0", @@ -75,7 +77,6 @@ "@types/node": "20.3.2", "@types/semver": "7.5.0", "chalk": "5.2.0", - "constants": "workspace:*", "next": "13.4.7", "react": "18.2.0", "react-dom": "18.2.0", @@ -83,11 +84,9 @@ "rollup-plugin-dts": "5.3.0", "type-fest": "3.12.0", "typescript": "5.2.0-dev.20230628", - "utils": "workspace:*", "webpack": "5.88.1" }, "peerDependencies": { - "next": ">=11.0.0", - "webpack": ">=5.9.0" + "next": ">=11.0.0" } } diff --git a/packages/next-pwa/rollup.config.js b/packages/next-pwa/rollup.config.js index 9a24b238..a10fae78 100644 --- a/packages/next-pwa/rollup.config.js +++ b/packages/next-pwa/rollup.config.js @@ -5,12 +5,12 @@ * "input" | "output" | "external" | "plugins" * >} FileEntry */ +import { swcConfig } from "@ducanh2912/constants/swc-config"; import alias from "@rollup/plugin-alias"; import json from "@rollup/plugin-json"; import nodeResolve from "@rollup/plugin-node-resolve"; import swc from "@rollup/plugin-swc"; import typescript from "@rollup/plugin-typescript"; -import { swcConfig } from "constants/swc-config"; import { defineConfig } from "rollup"; import dts from "rollup-plugin-dts"; @@ -39,7 +39,6 @@ const files = [ "terser-webpack-plugin", "workbox-webpack-plugin", "typescript", - "webpack", "crypto", "fs", "path", diff --git a/packages/next-pwa/src/index.ts b/packages/next-pwa/src/index.ts index 8889c50c..1db150de 100644 --- a/packages/next-pwa/src/index.ts +++ b/packages/next-pwa/src/index.ts @@ -3,12 +3,12 @@ import fs from "node:fs"; import path from "node:path"; import { fileURLToPath } from "node:url"; +import { loadTSConfig, logger } from "@ducanh2912/utils"; import { CleanWebpackPlugin } from "clean-webpack-plugin"; import fg from "fast-glob"; import type { NextConfig } from "next"; import type NextConfigShared from "next/dist/server/config-shared.js"; -import { loadTSConfig, logger } from "utils"; -import type { Configuration, default as WebpackType } from "webpack"; +import type { Configuration, default as Webpack } from "webpack"; import type { RuntimeCaching } from "workbox-build"; import WorkboxPlugin from "workbox-webpack-plugin"; @@ -51,7 +51,7 @@ const withPWAInit = ( nextDefConfig?.experimental?.appDir ?? true; - const webpack: typeof WebpackType = options.webpack; + const webpack: typeof Webpack = options.webpack; const { buildId, dev, @@ -176,6 +176,7 @@ const withPWAInit = ( const _dest = path.join(options.dir, dest); const sweWorkerName = buildSWEntryWorker({ + webpack, id: buildId, destDir: _dest, shouldGenSWEWorker: cacheOnFrontEndNav, @@ -188,6 +189,7 @@ const withPWAInit = ( ); const customWorkerScriptName = buildCustomWorker({ + webpack, id: buildId, baseDir: options.dir, customWorkerDir, @@ -288,6 +290,7 @@ const withPWAInit = ( ); } const res = buildFallbackWorker({ + webpack, id: buildId, fallbacks, destDir: _dest, diff --git a/packages/next-pwa/src/resolve-runtime-caching.ts b/packages/next-pwa/src/resolve-runtime-caching.ts index 449d40ac..baec69fe 100644 --- a/packages/next-pwa/src/resolve-runtime-caching.ts +++ b/packages/next-pwa/src/resolve-runtime-caching.ts @@ -1,4 +1,4 @@ -import { logger } from "utils"; +import { logger } from "@ducanh2912/utils"; import type { RuntimeCaching } from "workbox-build"; import defaultCache from "./cache.js"; diff --git a/packages/next-pwa/src/swc-loader.ts b/packages/next-pwa/src/swc-loader.ts index fd5e3a49..56f1d326 100644 --- a/packages/next-pwa/src/swc-loader.ts +++ b/packages/next-pwa/src/swc-loader.ts @@ -1 +1 @@ -export { swcLoader as default } from "utils"; +export { swcLoader as default } from "@ducanh2912/utils"; diff --git a/packages/next-pwa/src/webpack-builders/build-custom-worker.ts b/packages/next-pwa/src/webpack-builders/build-custom-worker.ts index 2fb3b2fe..c12bb90e 100644 --- a/packages/next-pwa/src/webpack-builders/build-custom-worker.ts +++ b/packages/next-pwa/src/webpack-builders/build-custom-worker.ts @@ -1,17 +1,17 @@ import fs from "node:fs"; import path from "node:path"; +import { addPathAliasesToSWC, logger } from "@ducanh2912/utils"; import { CleanWebpackPlugin } from "clean-webpack-plugin"; import type { TsConfigJson as TSConfigJSON } from "type-fest"; -import { addPathAliasesToSWC, logger } from "utils"; -import type { Configuration } from "webpack"; -import webpack from "webpack"; +import type { Configuration, default as Webpack } from "webpack"; import defaultSwcRc from "../.swcrc.json"; import { NextPWAContext } from "./context.js"; import { getSharedWebpackConfig } from "./utils.js"; export const buildCustomWorker = ({ + webpack, id, baseDir, customWorkerDir, @@ -19,6 +19,7 @@ export const buildCustomWorker = ({ plugins = [], tsconfig, }: { + webpack: typeof Webpack; id: string; baseDir: string; customWorkerDir: string; diff --git a/packages/next-pwa/src/webpack-builders/build-fallback-worker.ts b/packages/next-pwa/src/webpack-builders/build-fallback-worker.ts index e68527a9..7aa5dbb6 100644 --- a/packages/next-pwa/src/webpack-builders/build-fallback-worker.ts +++ b/packages/next-pwa/src/webpack-builders/build-fallback-worker.ts @@ -1,9 +1,9 @@ import path from "node:path"; import { fileURLToPath } from "node:url"; +import { logger } from "@ducanh2912/utils"; import { CleanWebpackPlugin } from "clean-webpack-plugin"; -import { logger } from "utils"; -import webpack from "webpack"; +import type Webpack from "webpack"; import type { FallbackRoutes } from "../types.js"; import { NextPWAContext } from "./context.js"; @@ -13,10 +13,12 @@ import { getSharedWebpackConfig } from "./utils.js"; const __dirname = fileURLToPath(new URL(".", import.meta.url)); export const buildFallbackWorker = ({ + webpack, id, fallbacks, destDir, }: { + webpack: typeof Webpack; id: string; fallbacks: FallbackRoutes; destDir: string; diff --git a/packages/next-pwa/src/webpack-builders/build-sw-entry-worker.ts b/packages/next-pwa/src/webpack-builders/build-sw-entry-worker.ts index a7997b0b..49eb9bf3 100644 --- a/packages/next-pwa/src/webpack-builders/build-sw-entry-worker.ts +++ b/packages/next-pwa/src/webpack-builders/build-sw-entry-worker.ts @@ -1,9 +1,9 @@ import path from "node:path"; import { fileURLToPath } from "node:url"; +import { logger } from "@ducanh2912/utils"; import { CleanWebpackPlugin } from "clean-webpack-plugin"; -import { logger } from "utils"; -import webpack from "webpack"; +import type Webpack from "webpack"; import { NextPWAContext } from "./context.js"; import { getSharedWebpackConfig } from "./utils.js"; @@ -11,10 +11,12 @@ import { getSharedWebpackConfig } from "./utils.js"; const __dirname = fileURLToPath(new URL(".", import.meta.url)); export const buildSWEntryWorker = ({ + webpack, id, destDir, shouldGenSWEWorker, }: { + webpack: typeof Webpack; id: string; destDir: string; shouldGenSWEWorker: boolean; diff --git a/packages/next-pwa/src/webpack-builders/get-default-document-page.ts b/packages/next-pwa/src/webpack-builders/get-default-document-page.ts index 3b11ab63..6052fc46 100644 --- a/packages/next-pwa/src/webpack-builders/get-default-document-page.ts +++ b/packages/next-pwa/src/webpack-builders/get-default-document-page.ts @@ -1,7 +1,7 @@ import fs from "node:fs"; import path from "node:path"; -import { findFirstTruthy } from "utils"; +import { findFirstTruthy } from "@ducanh2912/utils"; export const getDefaultDocumentPage = ( baseDir: string, diff --git a/packages/next-pwa/src/webpack-builders/get-fallback-envs.ts b/packages/next-pwa/src/webpack-builders/get-fallback-envs.ts index f1dfb7dd..8821772e 100644 --- a/packages/next-pwa/src/webpack-builders/get-fallback-envs.ts +++ b/packages/next-pwa/src/webpack-builders/get-fallback-envs.ts @@ -1,6 +1,6 @@ import path from "node:path"; -import { logger } from "utils"; +import { logger } from "@ducanh2912/utils"; import type { FallbackRoutes } from "../types.js"; diff --git a/packages/next-pwa/src/webpack-builders/utils.ts b/packages/next-pwa/src/webpack-builders/utils.ts index ae9f22f8..a49b1117 100644 --- a/packages/next-pwa/src/webpack-builders/utils.ts +++ b/packages/next-pwa/src/webpack-builders/utils.ts @@ -1,9 +1,9 @@ import path from "node:path"; import { fileURLToPath } from "node:url"; +import { resolveSwc, terserMinify } from "@ducanh2912/utils"; import type { MinimizerOptions, TerserOptions } from "terser-webpack-plugin"; import TerserPlugin from "terser-webpack-plugin"; -import { resolveSwc, terserMinify } from "utils"; import type { Configuration } from "webpack"; import defaultSwcRc from "../.swcrc.json"; diff --git a/packages/next-sw/package.json b/packages/next-sw/package.json index 450f1652..f81706fe 100644 --- a/packages/next-sw/package.json +++ b/packages/next-sw/package.json @@ -43,20 +43,20 @@ "terser-webpack-plugin": "5.3.9" }, "devDependencies": { + "@ducanh2912/constants": "workspace:*", + "@ducanh2912/utils": "workspace:*", "@rollup/plugin-json": "6.0.0", "@rollup/plugin-node-resolve": "15.1.0", "@rollup/plugin-swc": "0.1.1", "@rollup/plugin-typescript": "11.1.2", "@types/node": "20.3.2", "chalk": "5.2.0", - "constants": "workspace:*", "next": "13.4.7", "react": "18.2.0", "react-dom": "18.2.0", "rollup": "3.25.3", "rollup-plugin-dts": "5.3.0", "typescript": "5.2.0-dev.20230628", - "utils": "workspace:*", "webpack": "5.88.1" }, "peerDependencies": { diff --git a/packages/next-sw/rollup.config.js b/packages/next-sw/rollup.config.js index e94b9a55..f39cdfe0 100644 --- a/packages/next-sw/rollup.config.js +++ b/packages/next-sw/rollup.config.js @@ -5,11 +5,11 @@ * "input" | "output" | "external" | "plugins" * >} FileEntry */ +import { swcConfig } from "@ducanh2912/constants/swc-config"; import json from "@rollup/plugin-json"; import nodeResolve from "@rollup/plugin-node-resolve"; import swc from "@rollup/plugin-swc"; import typescript from "@rollup/plugin-typescript"; -import { swcConfig } from "constants/swc-config"; import { defineConfig } from "rollup"; import dts from "rollup-plugin-dts"; @@ -32,12 +32,7 @@ const files = [ }, ], // chalk should be bundled with the package to work with CJS. - external: [ - "clean-webpack-plugin", - "terser-webpack-plugin", - "webpack", - "semver", - ], + external: ["clean-webpack-plugin", "terser-webpack-plugin", "semver"], }, { input: "src/build/generate-sw/base-sw.ts", diff --git a/packages/next-sw/src/build/generate-sw/core-utils.ts b/packages/next-sw/src/build/generate-sw/core-utils.ts index be1c7381..4dd8f2e2 100644 --- a/packages/next-sw/src/build/generate-sw/core-utils.ts +++ b/packages/next-sw/src/build/generate-sw/core-utils.ts @@ -1,8 +1,8 @@ import fs from "node:fs"; import path from "node:path"; +import { findFirstTruthy, logger } from "@ducanh2912/utils"; import type { NextConfig } from "next"; -import { findFirstTruthy, logger } from "utils"; import type { FallbackRoutes } from "../../types.js"; diff --git a/packages/next-sw/src/build/generate-sw/core.ts b/packages/next-sw/src/build/generate-sw/core.ts index 3d708e0a..754ef795 100644 --- a/packages/next-sw/src/build/generate-sw/core.ts +++ b/packages/next-sw/src/build/generate-sw/core.ts @@ -1,9 +1,9 @@ import path from "node:path"; import { fileURLToPath } from "node:url"; +import { logger } from "@ducanh2912/utils"; import type { NextConfig } from "next"; import TerserPlugin from "terser-webpack-plugin"; -import { logger } from "utils"; import type { Configuration, default as Webpack } from "webpack"; import swcRc from "../../.swcrc.json"; diff --git a/packages/next-sw/src/build/generate-sw/get-manifest-entries-from-compilation.ts b/packages/next-sw/src/build/generate-sw/get-manifest-entries-from-compilation.ts index cb9d4668..c34ab25d 100644 --- a/packages/next-sw/src/build/generate-sw/get-manifest-entries-from-compilation.ts +++ b/packages/next-sw/src/build/generate-sw/get-manifest-entries-from-compilation.ts @@ -2,13 +2,14 @@ import crypto from "node:crypto"; import path from "node:path"; import type { Asset, Compilation } from "webpack"; -import { ModuleFilenameHelpers, WebpackError } from "webpack"; +import type Webpack from "webpack"; import type { ManifestEntry } from "../../private-types.js"; import type { FilterEntry } from "../../types.js"; import type { GenerateSWWebpackConfig } from "./webpack-plugin.js"; const checkConditions = ( + webpack: typeof Webpack, asset: Asset, compilation: Compilation, conditions: FilterEntry[] = [] @@ -17,7 +18,7 @@ const checkConditions = ( if (typeof condition === "function") { return condition({ asset, compilation }); } - if (ModuleFilenameHelpers.matchPart(asset.name, condition)) { + if (webpack.ModuleFilenameHelpers.matchPart(asset.name, condition)) { return true; } } @@ -71,6 +72,10 @@ export const getManifestEntriesFromCompilation = async ( compilation: Compilation, config: GenerateSWWebpackConfig ) => { + if (!config.webpackInstance) { + return undefined; + } + const assets = compilation.getAssets(); const { publicPath } = compilation.options.output; @@ -80,12 +85,12 @@ export const getManifestEntriesFromCompilation = async ( })[] = []; for (const asset of assets) { - const isExcluded = checkConditions(asset, compilation, config.exclude); + const isExcluded = checkConditions(config.webpackInstance, asset, compilation, config.exclude); if (isExcluded) { continue; } const isIncluded = - !!config.include && checkConditions(asset, compilation, config.include); + !!config.include && checkConditions(config.webpackInstance, asset, compilation, config.include); if (!isIncluded) { continue; @@ -103,7 +108,7 @@ export const getManifestEntriesFromCompilation = async ( }); for (const warning of warnings) { - compilation.warnings.push(new WebpackError(warning)); + compilation.warnings.push(new config.webpackInstance.WebpackError(warning)); } // Ensure that the entries are properly sorted by URL. diff --git a/packages/next-sw/src/build/generate-sw/webpack-plugin.ts b/packages/next-sw/src/build/generate-sw/webpack-plugin.ts index e5cee00b..3e012a25 100644 --- a/packages/next-sw/src/build/generate-sw/webpack-plugin.ts +++ b/packages/next-sw/src/build/generate-sw/webpack-plugin.ts @@ -15,12 +15,11 @@ const generatedAssetNames = new Set(); export interface GenerateSWWebpackConfig extends GenerateSWConfig { include?: FilterEntry[]; exclude?: FilterEntry[]; + webpackInstance?: typeof Webpack; } export class GenerateSW { - protected config: GenerateSWWebpackConfig & { - webpackInstance?: typeof Webpack; - }; + protected config: GenerateSWWebpackConfig; protected propagateConfigWithCompiler(compiler: Compiler): void { // Properties that are already set take precedence over derived @@ -48,10 +47,10 @@ export class GenerateSW { // instance of this plugin. config.exclude.push(({ asset }) => generatedAssetNames.has(asset.name)); - const { sortedEntries } = await getManifestEntriesFromCompilation( + const { sortedEntries = [] } = await getManifestEntriesFromCompilation( compilation, config - ); + ) ?? {}; config.manifestEntries = sortedEntries; diff --git a/packages/next-sw/src/index.ts b/packages/next-sw/src/index.ts index bd5f0a01..70541e60 100644 --- a/packages/next-sw/src/index.ts +++ b/packages/next-sw/src/index.ts @@ -1,7 +1,7 @@ import path from "node:path"; +import { logger } from "@ducanh2912/utils"; import type { NextConfig } from "next"; -import { logger } from "utils"; import type { Configuration, default as Webpack } from "webpack"; import { getDefaultDocumentPage } from "./build/generate-sw/core-utils.js"; diff --git a/packages/next-sw/src/swc-loader.ts b/packages/next-sw/src/swc-loader.ts index fd5e3a49..56f1d326 100644 --- a/packages/next-sw/src/swc-loader.ts +++ b/packages/next-sw/src/swc-loader.ts @@ -1 +1 @@ -export { swcLoader as default } from "utils"; +export { swcLoader as default } from "@ducanh2912/utils"; diff --git a/packages/test-utils/package.json b/packages/test-utils/package.json index 71d4a302..5447993a 100644 --- a/packages/test-utils/package.json +++ b/packages/test-utils/package.json @@ -13,6 +13,7 @@ "type-fest": "3.12.0" }, "devDependencies": { - "@types/fs-extra": "11.0.1" + "@types/fs-extra": "11.0.1", + "@types/jest": "29.5.3" } } diff --git a/packages/test-utils/src/next-instance-base.ts b/packages/test-utils/src/next-instance-base.ts index ceae72ea..00cb0827 100644 --- a/packages/test-utils/src/next-instance-base.ts +++ b/packages/test-utils/src/next-instance-base.ts @@ -46,7 +46,7 @@ export abstract class NextInstance { tmpDir, `next-pwa-test-${Date.now()}-${(Math.random() * 1000) | 0}` ); - this._appTestDir = path.join(this._testDir, "__tests__"); + this._appTestDir = path.join(this._testDir, "next-pwa-e2e-test"); if (!existsSync(this._testDir)) { await fs.mkdir(this._testDir); @@ -66,6 +66,8 @@ export abstract class NextInstance { } this._dependencies = { + "@ducanh2912/next-pwa": "workspace:*", + "@ducanh2912/next-sw": "workspace:*", next: "latest", react: "latest", "react-dom": "latest", @@ -121,7 +123,7 @@ export abstract class NextInstance { await new Promise((resolve, reject) => { exec( - `pnpm i --no-frozen-lockfile`, + `pnpm i --no-frozen-lockfile --production`, { cwd: this._testDir }, (error, stdout, stderr) => { if (error) { diff --git a/packages/utils/package.json b/packages/utils/package.json index 68e50ed4..34501f08 100644 --- a/packages/utils/package.json +++ b/packages/utils/package.json @@ -1,5 +1,5 @@ { - "name": "utils", + "name": "@ducanh2912/utils", "version": "0.0.0", "private": true, "license": "MIT", @@ -33,11 +33,11 @@ "semver": "7.5.3" }, "devDependencies": { + "@ducanh2912/constants": "workspace:*", "@rollup/plugin-node-resolve": "15.1.0", "@rollup/plugin-swc": "0.1.1", "@swc/core": "1.3.67", "@types/semver": "7.5.0", - "constants": "workspace:*", "rollup": "3.25.3", "terser-webpack-plugin": "5.3.9", "type-fest": "3.12.0", diff --git a/packages/utils/rollup.config.js b/packages/utils/rollup.config.js index 9a953bba..04f49d11 100644 --- a/packages/utils/rollup.config.js +++ b/packages/utils/rollup.config.js @@ -5,9 +5,9 @@ * "input" | "output" | "external" | "plugins" * >} FileEntry */ +import { swcConfig } from "@ducanh2912/constants/swc-config"; import nodeResolve from "@rollup/plugin-node-resolve"; import swc from "@rollup/plugin-swc"; -import { swcConfig } from "constants/swc-config"; import { defineConfig } from "rollup"; /** @type {FileEntry[]} */ diff --git a/pnpm-lock.yaml b/pnpm-lock.yaml index d5e8f0db..e72c1ae7 100644 --- a/pnpm-lock.yaml +++ b/pnpm-lock.yaml @@ -47,6 +47,9 @@ importers: eslint-config-turbo: specifier: 1.10.6 version: 1.10.6(eslint@8.43.0) + eslint-plugin-import: + specifier: 2.27.5 + version: 2.27.5(@typescript-eslint/parser@5.60.1)(eslint-import-resolver-typescript@3.5.3)(eslint@8.43.0) eslint-plugin-simple-import-sort: specifier: 10.0.0 version: 10.0.0(eslint@8.43.0) @@ -86,9 +89,6 @@ importers: typescript: specifier: 5.2.0-dev.20230628 version: 5.2.0-dev.20230628 - webpack: - specifier: 5.88.1 - version: 5.88.1 docs: dependencies: @@ -247,9 +247,6 @@ importers: typescript: specifier: 5.1.6 version: 5.1.6 - webpack: - specifier: 5.88.1 - version: 5.88.1 examples/custom-server: dependencies: @@ -299,9 +296,6 @@ importers: typescript: specifier: 5.1.6 version: 5.1.6 - webpack: - specifier: 5.88.1 - version: 5.88.1(@swc/core@1.3.67) examples/custom-worker: dependencies: @@ -330,9 +324,6 @@ importers: typescript: specifier: 5.1.6 version: 5.1.6 - webpack: - specifier: 5.88.1 - version: 5.88.1 examples/lifecycle: dependencies: @@ -361,9 +352,6 @@ importers: typescript: specifier: 5.1.6 version: 5.1.6 - webpack: - specifier: 5.88.1 - version: 5.88.1 examples/next-i18next: dependencies: @@ -410,9 +398,6 @@ importers: typescript: specifier: 5.1.6 version: 5.1.6 - webpack: - specifier: 5.88.1 - version: 5.88.1 examples/next-image: dependencies: @@ -441,9 +426,6 @@ importers: typescript: specifier: 5.1.6 version: 5.1.6 - webpack: - specifier: 5.88.1 - version: 5.88.1 examples/offline-fallback-v2: dependencies: @@ -475,9 +457,6 @@ importers: typescript: specifier: 5.1.6 version: 5.1.6 - webpack: - specifier: 5.88.1 - version: 5.88.1 examples/web-push: dependencies: @@ -512,9 +491,6 @@ importers: typescript: specifier: 5.1.6 version: 5.1.6 - webpack: - specifier: 5.88.1 - version: 5.88.1 examples/workboxless: dependencies: @@ -577,6 +553,12 @@ importers: specifier: 7.0.0 version: 7.0.0 devDependencies: + '@ducanh2912/constants': + specifier: workspace:* + version: link:../constants + '@ducanh2912/utils': + specifier: workspace:* + version: link:../utils '@rollup/plugin-alias': specifier: 5.0.0 version: 5.0.0(rollup@3.25.3) @@ -601,9 +583,6 @@ importers: chalk: specifier: 5.2.0 version: 5.2.0 - constants: - specifier: workspace:* - version: link:../constants next: specifier: 13.4.7 version: 13.4.7(@babel/core@7.20.5)(@opentelemetry/api@1.4.1)(react-dom@18.2.0)(react@18.2.0) @@ -625,9 +604,6 @@ importers: typescript: specifier: 5.2.0-dev.20230628 version: 5.2.0-dev.20230628 - utils: - specifier: workspace:* - version: link:../utils webpack: specifier: 5.88.1 version: 5.88.1(@swc/core@1.3.67) @@ -653,6 +629,12 @@ importers: specifier: 5.3.9 version: 5.3.9(@swc/core@1.3.67)(webpack@5.88.1) devDependencies: + '@ducanh2912/constants': + specifier: workspace:* + version: link:../constants + '@ducanh2912/utils': + specifier: workspace:* + version: link:../utils '@rollup/plugin-json': specifier: 6.0.0 version: 6.0.0(rollup@3.25.3) @@ -671,9 +653,6 @@ importers: chalk: specifier: 5.2.0 version: 5.2.0 - constants: - specifier: workspace:* - version: link:../constants next: specifier: 13.4.7 version: 13.4.7(@babel/core@7.20.5)(@opentelemetry/api@1.4.1)(react-dom@18.2.0)(react@18.2.0) @@ -692,9 +671,6 @@ importers: typescript: specifier: 5.2.0-dev.20230628 version: 5.2.0-dev.20230628 - utils: - specifier: workspace:* - version: link:../utils webpack: specifier: 5.88.1 version: 5.88.1(@swc/core@1.3.67) @@ -714,6 +690,9 @@ importers: '@types/fs-extra': specifier: 11.0.1 version: 11.0.1 + '@types/jest': + specifier: 29.5.3 + version: 29.5.3 packages/utils: dependencies: @@ -724,6 +703,9 @@ importers: specifier: 7.5.3 version: 7.5.3 devDependencies: + '@ducanh2912/constants': + specifier: workspace:* + version: link:../constants '@rollup/plugin-node-resolve': specifier: 15.1.0 version: 15.1.0(rollup@3.25.3) @@ -736,9 +718,6 @@ importers: '@types/semver': specifier: 7.5.0 version: 7.5.0 - constants: - specifier: workspace:* - version: link:../constants rollup: specifier: 3.25.3 version: 3.25.3 @@ -3888,6 +3867,13 @@ packages: '@types/istanbul-lib-report': 3.0.0 dev: true + /@types/jest@29.5.3: + resolution: {integrity: sha512-1Nq7YrO/vJE/FYnqYyw0FS8LdrjExSgIiHyKg7xPpn+yi8Q4huZryKnkJatN1ZRH89Kw2v33/8ZMB7DuZeSLlA==} + dependencies: + expect: 29.5.0 + pretty-format: 29.5.0 + dev: true + /@types/json-schema@7.0.11: resolution: {integrity: sha512-wOuvG1SN4Us4rez+tylwwwCV1psiNVOkJeM3AUWUNWg/jDQY2+HE/444y5gc+jBmRqASOm2Oeh5c1axHobwRKQ==} @@ -11871,30 +11857,6 @@ packages: terser: 5.17.6 webpack: 5.88.1(@swc/core@1.3.67) - /terser-webpack-plugin@5.3.9(webpack@5.88.1): - resolution: {integrity: sha512-ZuXsqE07EcggTWQjXUj+Aot/OMcD0bMKGgF63f7UxYcu5/AJF53aIpK1YoP5xR9l6s/Hy2b+t1AM0bLNPRuhwA==} - engines: {node: '>= 10.13.0'} - peerDependencies: - '@swc/core': '*' - esbuild: '*' - uglify-js: '*' - webpack: ^5.1.0 - peerDependenciesMeta: - '@swc/core': - optional: true - esbuild: - optional: true - uglify-js: - optional: true - dependencies: - '@jridgewell/trace-mapping': 0.3.17 - jest-worker: 27.5.1 - schema-utils: 3.3.0 - serialize-javascript: 6.0.1 - terser: 5.17.6 - webpack: 5.88.1 - dev: true - /terser@5.17.6: resolution: {integrity: sha512-V8QHcs8YuyLkLHsJO5ucyff1ykrLVsR4dNnS//L5Y3NiSXpbK1J+WMVUs67eI0KTxs9JtHhgEQpXQVHlHI92DQ==} engines: {node: '>=10'} @@ -12615,46 +12577,6 @@ packages: resolution: {integrity: sha512-/DyMEOrDgLKKIG0fmvtz+4dUX/3Ghozwgm6iPp8KRhvn+eQf9+Q7GWxVNMk3+uCPWfdXYC4ExGBckIXdFEfH1w==} engines: {node: '>=10.13.0'} - /webpack@5.88.1: - resolution: {integrity: sha512-FROX3TxQnC/ox4N+3xQoWZzvGXSuscxR32rbzjpXgEzWudJFEJBpdlkkob2ylrv5yzzufD1zph1OoFsLtm6stQ==} - engines: {node: '>=10.13.0'} - hasBin: true - peerDependencies: - webpack-cli: '*' - peerDependenciesMeta: - webpack-cli: - optional: true - dependencies: - '@types/eslint-scope': 3.7.4 - '@types/estree': 1.0.0 - '@webassemblyjs/ast': 1.11.5 - '@webassemblyjs/wasm-edit': 1.11.5 - '@webassemblyjs/wasm-parser': 1.11.5 - acorn: 8.8.1 - acorn-import-assertions: 1.9.0(acorn@8.8.1) - browserslist: 4.21.6 - chrome-trace-event: 1.0.3 - enhanced-resolve: 5.15.0 - es-module-lexer: 1.2.1 - eslint-scope: 5.1.1 - events: 3.3.0 - glob-to-regexp: 0.4.1 - graceful-fs: 4.2.11 - json-parse-even-better-errors: 2.3.1 - loader-runner: 4.3.0 - mime-types: 2.1.35 - neo-async: 2.6.2 - schema-utils: 3.3.0 - tapable: 2.2.1 - terser-webpack-plugin: 5.3.9(webpack@5.88.1) - watchpack: 2.4.0 - webpack-sources: 3.2.3 - transitivePeerDependencies: - - '@swc/core' - - esbuild - - uglify-js - dev: true - /webpack@5.88.1(@swc/core@1.3.67): resolution: {integrity: sha512-FROX3TxQnC/ox4N+3xQoWZzvGXSuscxR32rbzjpXgEzWudJFEJBpdlkkob2ylrv5yzzufD1zph1OoFsLtm6stQ==} engines: {node: '>=10.13.0'} diff --git a/pnpm-workspace.yaml b/pnpm-workspace.yaml index e458359f..0089cc30 100644 --- a/pnpm-workspace.yaml +++ b/pnpm-workspace.yaml @@ -3,3 +3,4 @@ packages: - "packages/**" - "examples/**" - "!examples/**/.next" + - "next-pwa-e2e-test"