Failed to compile error during creating PWA with next.js - next.js

I run the command : npm run build
Error :
info - Creating an optimized production build
Failed to compile.
Please check your GenerateSW plugin configuration:
[WebpackGenerateSW] 'reactStrictMode' property is not expected to be here. Did you mean property 'exclude'?
Build failed because of webpack errors

If your version of next-pwa is 5.6 and your next.config.js is like this:
const withPWA = require('next-pwa')
const runtimeCaching = require('next-pwa/cache')
module.exports = withPWA({
pwa: {
dest: 'public',
runtimeCaching,
},
})
Then you should consider changing it as written in the README.md file:
const withPWA = require('next-pwa')({
dest: 'public'
})
module.exports = withPWA({
// next.js config
})
I encountered this issue when I followed the pwa example of nextjs. My next-pwa version is 5.6 and the example's version is 5.5.4, so it dosen't work.

this worked for me
const runtimeCaching = require("next-pwa/cache");
const withPWA = require("next-pwa")({
dest: "public",
register: true,
skipWaiting: true,
runtimeCaching,
buildExcludes: [/middleware-manifest.json$/],
});
const nextConfig = withPWA({
// next config
});
module.exports = nextConfig;

Related

How can I get Vite env variables?

I am using Quasar, Vue 3, Vite, Cypress in my project. I don't know how to get .env variables (e.g. VITE_API_URL) and to set in cypress.env.json. Before Vite I used webpack and I know how to do it.
I don't want to define twice same variable, first in .env then in cypress.env.json.
You can use the dotenv package directly, merging the result in with the env section of your cypress config.
.env
VITE_API_URL: "http://example.com"
cypress.config.js
const { defineConfig } = require("cypress");
const dotenv = require('dotenv')
const env = dotenv.config('./.env').parsed
module.exports = defineConfig({
'component': {
// component config here
},
env: {
login_url: '/login',
...env, // merge here with spread operator
},
});
Settings page in the Cypress runner
env: {
login_url: '/login',
VITE_API_URL: 'http://example.com',
},
There is a plugin called cypress-dotenv for this very purpose. It allows you to share your .env file variables between your app and cypress tests.
Install
npm install --save-dev cypress-dotenv
# For typescript
npm install --save-dev #types/cypress-dotenv
Example
Example .env file
VITE_API_URL=https://vite-api-url.com
In your cypress.config.js, run the plugin dotenvCypress() under setupNodeEvents():
import { defineConfig } from "cypress";
import dotenvCypress from 'cypress-dotenv';
export default defineConfig({
component: {
devServer: {
framework: "vue",
bundler: "vite",
},
setupNodeEvents(on, config) {
return dotenvCypress(config, undefined, true);
},
},
});
Then in your test:
it('works', () => {
cy.log(Cypress.env('VITE_API_URL'));
});
Notes
dotenvCypress() must be returned in setupNodeEvents()
To get all the env variables from your .env file, you have to pass true as the third argument to dotenvCypress(). Otherwise, only vars prefixed with CYPRESS_ will be available.
https://www.npmjs.com/package/cypress-dotenv

Can not install NextJS successfully. Getting ./app/page.module.css.webpack[javascript/auto]!=!./node_modules/next... error

I just tried to install NextJS 13.1.5 using npx create-next-app#latest, but when I tried to run it npm run dev I got an Error:
./app/page.module.css.webpack[javascript/auto]!=!./node_modules/next/dist/build/webpack/loaders/css-loader/src/index.js??ruleSet[1].rules[3].oneOf[7].use[2]!./node_modules/next/dist/build/webpack/loaders/postcss-loader/src/index.js??ruleSet[1].rules[3].oneOf[7].use[3]!./app/page.module.css
TypeError: Cannot read properties of undefined (reading 'config')
at runMicrotasks (<anonymous>)
I don't know why it happened so, before it was no such errors with previous versions.
I tried different configuration with app/ directory and without but got the same error.
Configuration example:
next.config.js :
/** #type {import('next').NextConfig} */
const nextConfig = {
experimental: {
appDir: true,
},
}
module.exports = nextConfig

Disable es5 transpilation while developing in nextjs

Is there a way to disable transpilation of es5 code (such as async functions) while in next dev?
Setting the babel preset-env does not work, and this previous answer no longer works either.
Setting the browserlist target within package.json still transpiles the code as well
As of Jan 2023 I found a few flags that help get you most of the way there.
const isProd = process.env.NODE_ENV === "production";
const nextConfig = {
webpack: (config, { dev }) => {
if (dev && Array.isArray(config.target) && config.target.includes('web')) {
config.optimization.minimize = false;
delete config.optimization.minimizer;
config.target = ["web", "es2020"];
}
return config;
}
};
if (!isProd) {
nextConfig.experimental = {
legacyBrowsers: false,
};
}
module.exports = nextConfig;
This will disable legacy browser support and use your browser list for swc, and then also changes the targets for webpack. Doesn't completely remove transpilation but it's way better than the default
Also, nextjs now supports browserslist in your package.json - source
Adding the following key to your package.json will enable most features by default:
{
"browserslist": [
"chrome 109"
]
}

How do you shim react-pdf with esbuild?

If you bundle react-pdf for the browser using esbuild today you will run into errors that prompt you to build for platform=node because zlib and stream are not available in the browser environment.
I did find a conversation around how to swap this when using vite but I'm curious if others have created a shim for esbuild that offers something equivalent
process: "process/browser",
stream: "vite-compatible-readable-stream",
zlib: "browserify-zlib"
the version I'm using today: #react-pdf/renderer": "^2.0.21"
edit
It just so happens a node modules polyfill exists for esbuild and you should be able to configure this as a plugin
https://github.com/remorses/esbuild-plugins#readme
npm i -D #esbuild-plugins/node-globals-polyfill
and then w/ esbuild you can pass it in like so
https://esbuild.github.io/plugins/#using-plugins
More after I confirm this is working end to end
I was able to achieve this using esbuild v0.14.10 and 2 plugins
npm i -D #esbuild-plugins/node-modules-polyfill
npm i -D #esbuild-plugins/node-globals-polyfill
With a build configuration like this
const esbuild = require('esbuild')
const globalsPlugin = require('#esbuild-plugins/node-globals-polyfill')
const modulesPlugin = require('#esbuild-plugins/node-modules-polyfill')
const args = process.argv.slice(2)
const deploy = args.includes('--deploy')
const loader = {
// Add loaders for images/fonts/etc, e.g. { '.svg': 'file' }
}
const plugins = [
globalsPlugin.NodeGlobalsPolyfillPlugin({
process: true,
buffer: true,
define: { 'process.env.NODE_ENV': deploy ? '"production"' : '"development"' },
}),
modulesPlugin.NodeModulesPolyfillPlugin(),
]
let opts = {
entryPoints: ['js/app.js'],
bundle: true,
target: 'es2017',
outdir: '../priv/static/assets',
logLevel: 'info',
inject: ['./react-shim.js'],
loader,
plugins
}
if (deploy) {
opts = {
...opts,
minify: true
}
}
const promise = esbuild.build(opts)

HMR in asp.net core with React

I started my project using .net core cli.
dotnet new react -o my app
and for development, I changed my env var
export ASPNETCORE_Environment=Development
I am not very comfortable with Typescript so, I prefer use .jsx files and babel, so I decided to change my webpack.config.js. In module rules, I added:
const BABEL_LOADER_PLUGINS = [
require.resolve("babel-plugin-transform-class-properties"),
require.resolve("babel-plugin-transform-object-rest-spread"),
require.resolve("babel-plugin-transform-regenerator")
];
/*...webpack config code ... */
{
test: /\.jsx$/,
exclude: /node_modules/,
use: [
{
loader: "babel-loader",
options: {
presets: ["env", "react"],
plugins: BABEL_LOADER_PLUGINS
}
}
]
}
I did my new components with .jsx extensions and it works. So my next step is to do HMR work.
In my Startup.cs:
if (env.IsDevelopment())
{
app.UseDeveloperExceptionPage();
app.UseWebpackDevMiddleware(new WebpackDevMiddlewareOptions
{
HotModuleReplacement = true
});
}
In client at root component, using react-hot-loader':
let HotApp;
if (__CONFIGS__.isDevServer) {
const { hot } = require('react-hot-loader');
HotApp = hot(module)(App);
} else {
HotApp = App;
}
const Root = (
<Provider store={store}>
<BrowserRouter>
<HotApp />
</BrowserRouter>
</Provider>
);
hydrate(Root, document.getElementById('react-app'));
And this sometimes works. In the console, I can see [HMR] connected and updates. If I stop the process, it is possible that console shows [HMR] connected but if I do some changes in a component nothing happens. I don't know why sometimes works well.
We can use Create React App Configuration Override (#craco/craco) along with craco-plugin-react-hot-reload CRACO plugin to add HMR without ejecting the CRA application.
Install #craco/craco by following the installation guide
Install craco-plugin-react-hot-reload
npm i -D craco-plugin-react-hot-reload
Add craco-plugin-react-hot-reload into craco.config.js
const reactHotReloadPlugin = require('craco-plugin-react-hot-reload');
module.exports = {
plugins: [{
plugin: reactHotReloadPlugin
}],
webpack: [...]
}
Install #hot-loader/react-dom
npm i #hot-loader/react-dom
Mark your App component as hot-exported (into ClientApp\src\App.js)
import { hot } from 'react-hot-loader/root';
function App() {...}
export default hot(App);
Now HMR will work properly when we start the project using dotnet run.
Tested (on May 2020) using React 16.13.1. We must use the same major and minor versions for react, react-dom and #hot-loader/react-dom (16.13.x).

Resources