Disable es5 transpilation while developing in nextjs - next.js

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"
]
}

Related

Identifier 'module' has already been declared - amplify and nuxt 3

I am getting an error in nuxt3 then setting up this amplify plugin. I am trying to add auth to nuxt3 via plugins
plugins/amplify.js
import Amplify, {withSSRContext} from 'aws-amplify';
export default defineNuxtPlugin((ctx) => {
const awsConfig = {
Auth: {
region: "ap-south-1",
userPoolId: "ap-south-1_#########",
userPoolWebClientId: "#####################",
authenticationFlowType: "USER_SRP_AUTH",
},
};
Amplify.configure({ ...awsConfig, ssr: true });
if (process.server) {
const { Auth } = withSSRContext(ctx.req);
return {
provide: {
auth: Auth,
},
};
}
return {
provide: {
auth: Auth,
},
};
}
[nuxt] [request error] Identifier 'module' has already been declared
at Loader.moduleStrategy (internal/modules/esm/translators.js:145:18)
at async link (internal/modules/esm/module_job.js:67:21)
Does anyone know what's going on?
Been facing this myself... I don't think its a nuxt problem but rather Vite.
I gave up on running the app on dev mode and just resorted to building the app and launching it. Also, in order to use aws-amplify with vite you need to apply some workarounds:
https://ui.docs.amplify.aws/vue/getting-started/troubleshooting
For the window statement (which only makes sense on the browser) you'll need to wrap that with an if statement. Added this to my plugin file
if (process.client) {
window.global = window;
var exports = {};
}
This will let you build the project and run it with npm run build . Far from ideal but unless someone knows how to fix that issue with dev in vite...
BTW, you can also just switch to webpack builder on nuxt settings and the issue goes away.
// https://v3.nuxtjs.org/api/configuration/nuxt.config
export default defineNuxtConfig({
builder: "webpack"
});
I think this might be a problem with auto imports of nuxt.
I added a ~/composables/useBucket.ts file which I used in ~/api. Same error started popping up the next day. After I moved ~/composables/useBucket.ts to ~/composablesServer/useBucket.ts issue disappeared.

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)

Alerts in bootstrap & pug

I would like to know whether i have understood the workings of connect-flash/bootstrap/sessions. I do see the flash messages appear as expected. My question is to do with the colors related to the 'success' and 'danger'. While the messages appear as expected i am not seeing the associated colors,
Below are bits of package.json,
{
"dependencies": {
"body-parser": "^1.18.3",
"bootstrap": "^4.1.3",
"connect-flash": "^0.1.1",
"cookie-parser": "^1.4.3",
"express": "^4.16.4",
"express-messages": "^1.0.1",
"express-session": "^1.15.6",
"express-validator": "^5.3.0",
"mongoose": "^5.3.15",
"pug": "^2.0.3"
},
"devDependencies": {
"nodemon": "^1.18.7"
}
}
In my app.js,
const express = require('express');
const path = require('path');
const mongoose = require('mongoose');
const bodyParser = require('body-parser');
const cookieParser = require('cookie-parser');
const expressValidator = require('express-validator');
const flash = require('connect-flash');
const session = require('express-session');
// express session middleware
app.use(session({
secret: 'keyboard cat',
resave: true,
saveUninitialized: true
}));
// express messages middleware
app.use(require('connect-flash')());
app.use(function (req, res, next) {
res.locals.messages = require('express-messages')(req, res);
next();
});
app.use(flash());
// my routes
let quotes = require('./routes/quotes');
let subscribers = require('./routes/subscribers');
app.use('/quotes', quotes);
app.use('/subscribers', subscribers);
// In my subscribers route,
router.post('/subscribe', function (req, res)
{
// logic to save to my database here
req.flash('success', 'Subscription confirmed.');
res.redirect('back');
});
In my services.pug file i have,
link(rel='stylesheet', href='/css/style.css')
link(rel='stylesheet' href='/node_modules/bootstrap/dist/css/bootstrap.css')
// other code in here
.container
h1 Subscribe to our newsletter
//- include subscribe.pug
form(method='POST', action= '/subscribe')
input(name = 'email',type='email', placeholder='Enter email')
button.button1(type='submit') Subscribe
!= messages('message',locals)
// at the bottom
script(src='/node_modules/jquery/dist/jquery.js')
script(src='/node_modules/bootstrap/dist/js/bootstrap.js')
In my message.pug i have,
.messages
each type in Object.keys(messages)
each message in messages[type]
div(class = "alert alert-"+ type) #{message}
Like i mentioned above the messages appear as expected. But i do not see the green color associated with success and the red for danger as i have seen in a tutorial i followed. I just see the message blended with the background color of the page. I would like to know what i am missing.
UPDATE
On checking the console on chrome i found the attached error messages. I have included the directory structure of the project as well. The bootstrap.css and jquery.js are not being found by the app.
This is where i set my public folder in app.js,
// set public folder
app.use(express.static(path.join(__dirname, 'public')));
The node_modules folder is available as well.
Thank you
You also need to serve bootstrap and jquery dist folders beside the public one:
// set public folder
app.use(express.static(path.join(__dirname, 'public')));
// serve bootstrap and jquery
app.use(express.static(path.join(__dirname, 'node_modules', 'bootstrap', 'dist')));
app.use(express.static(path.join(__dirname, 'node_modules', 'jquery', 'dist')));
and use them ( make sure styles are in head tag ):
link(rel='stylesheet' href='/css/bootstrap.css')
link(rel='stylesheet' href='/css/style.css')
and:
script(src='jquery.js')
script(src='/js/bootstrap.js')
of course in production you should use minified versions ( i.e: bootstrap.min.js ) or simply a CDN ( or both: when CDN is not available fall back to local ones )

Get which program is generated in meteor by babel

How can I know in babel plugin whether files currently transpiled by babel are transpiled for server or client/browser package?
Meteor recently implemented option caller available in babel 7. To use it and access information in plugin, one can access Babel.caller poperty like this:
let caller;
module.exports = function(Babel) {
Babel.caller(function(c) {
caller = { ...c };
});
return {
visitor: {
BlockStatement(){
console.log(caller); // logs e.g. {name: "meteor", arch: "web.browser.legacy"}
}
}
};
};

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