NextJS Site Still Broken On Gh-Pages With basePath and assetPrefix - css

I built a website with next.js that works locally (code: https://github.com/xpress-smoke-shop/website).
I am now trying to deploy a static html version of the site to the domain: https://xpress-smoke-shop.github.io/website/
I can clone the repo and run these commands:
nvm use
yarn install
yarn build
yarn export
yarn deploy-gh
And I have changed the next.config.js file to reflect the repository that I'm using:
/* eslint-disable import/no-extraneous-dependencies */
const withBundleAnalyzer = require('#next/bundle-analyzer')({
enabled: process.env.ANALYZE === 'true',
});
module.exports = withBundleAnalyzer({
poweredByHeader: false,
trailingSlash: true,
basePath: '/website',
assetPrefix: '/website/',
reactStrictMode: true,
});
But my deployed site still looks wrong and has all these file-not-found errors...
How do I get this to deploy properly??

Related

Nextjs 13 exportPathMap uses pages dir instead of app dir to generate

I want to export my build to a different folder for reasons but it doesn't properly work. I'm using Next.js 13 and use the experimental app directory feature.
This is my next.config.js file and it doesn't include an exportPathMap.
/** #type {import('next').NextConfig} */
const nextConfig = {
reactStrictMode: true,
swcMinify: true,
experimental: {
appDir: true,
},
images: {
unoptimized: true,
}
};
module.exports = nextConfig;
And this is the error I'm getting.
info - using build directory: /home/foxy/programming/tauri/tauri-app/.next
info - Copying "static build" directory
info - No "exportPathMap" found in "pathToRootOfProject/next.config.js". Generating map from "./pages"
info - Launching 31 workers
info - Exporting (2/2)
PageNotFoundError: Cannot find module for page: /
at Object.getPagePath (pathToRootOfProject/node_modules/next/dist/server/require.js:77:15)
at pathToRootOfProject/node_modules/next/dist/export/index.js:376:48
at Array.map (<anonymous>)
at pathToRootOfProject/node_modules/next/dist/export/index.js:367:69
at process.processTicksAndRejections (node:internal/process/task_queues:95:5)
at async Span.traceAsyncFn (pathToRootOfProject/node_modules/next/dist/trace/trace.js:79:20) {
code: 'ENOENT'
}
error Command failed with exit code 1.
I already tried to redownload node_modules and that didn't work either.

NextJs code works after yarn run dev but not after yarn run build + yarn run start

I have the code below in my nextJs app. The code works when I run yarn run dev but when I run yarn run build then yarn run start the page just loads without redirecting. How can I solve this? What might be causing this?
import nextConnect from 'next-connect'
import authMiddlware from '../middleware/auth'
import passport from '../lib/passport'
const handler = nextConnect() export default handler.use(auth).get(
passport.authenticate('google',
{
successRedirect: 'http://localhost:3000/dashboard',
failureRedirect: "http://localhost:3000/?a=auth_fail"
}),
function(req, res, next) {
console.log('/redirect-google', req.user)
res.redirect("http://localhost:3000/dashboard");
next();
},
);

Cannot load Pinia in Nuxt3

I am trying to set up Nuxt3 to work with Pinia.
Steps Taken:
Started with an active nuxt3 project
ran npm install #pinia/nuxt
this failed, with a dependency error, so re-ran with npm install #pinia/nuxt --legacy-peer-deps, which worked fine
added pinia to my nuxt.config.ts, which now looks like:
import { defineNuxtConfig } from 'nuxt'
// https://v3.nuxtjs.org/api/configuration/nuxt.config
export default defineNuxtConfig({
meta: {
link: [
{
rel: "stylesheet",
href:"https://cdn.jsdelivr.net/npm/bootstrap#5.2.0-beta1/dist/css/bootstrap.min.css"
}
],
script: [
{ src: 'https://cdn.jsdelivr.net/npm/bootstrap#5.2.0-beta1/dist/js/bootstrap.bundle.min.js', integrity: 'sha384-pprn3073KE6tl6bjs2QrFaJGz5/SUsLqktiwsUTF55Jfv3qYSDhgCecCxMW52nD2', crossorigin: 'anonymous' }
]
},
ssr: false,
buildModules: ['#pinia/nuxt'],
base: '/',
})
restarted the server
got the following error:
GET http://localhost:3000/_nuxt/#id/pinia/dist/pinia.mjs net::ERR_ABORTED 404 (Not Found)
I've been googling around, and can't figure out what's broken here... I tried taking out the 'base' argument in nuxt.config.ts, and that didn't help either. If I take out the pinia declaration everything works fine.
Resolved by running:
npm install pinia #pinia/nuxt #nuxtjs/composition-api --legacy-peer-deps
I guess I was missing the actual pinia library
i had a same problem and solve it install with
yarn add #pinia/nuxt
instead npm

Why is eslint not working after migrating from CRA to Next.js?

I am currently working on migrating an app from CRA to Next.js. Eslint was working beautifully when using CRA (eslint works out-of-the-box).
I want to use the same CRA linting rules in the Next.js app so I installed eslint-config-react-app. I followed the instructions as provided on the NPM page: https://www.npmjs.com/package/eslint-config-react-app:
npm install --save-dev eslint-config-react-app #typescript-eslint/eslint-plugin#^4.0.0 #typescript-eslint/parser#^4.0.0 babel-eslint#^10.0.0 eslint#^7.5.0 eslint-plugin-flowtype#^5.2.0 eslint-plugin-import#^2.22.0 eslint-plugin-jsx-a11y#^6.3.1 eslint-plugin-react#^7.20.3 eslint-plugin-react-hooks#^4.0.8
create the .eslintrc.json file with the following content:
{ "extends": "react-app" }
However, the linting is not showing up neither in the development console nor in the browser console.
Thanks!
Ok so I found the solution.
I wanted the eslint output to show up in the console when saving edits to a file directly (just like with CRA). Initially, I did not realize that Next.js has no eslint plugin/loader specified in their webpack config so I extended theirs by adding my own. Now everything works as expected, just like it did when using CRA.
I actually used (although slightly modified) CRA's config for the eslint-webpack-plugin plugin. If anyone else wants to have an eslint setup in Next.js similar to CRA, add the following to your next.config.js file:
const path = require('path');
const fs = require('fs');
const ESLintPlugin = require('eslint-webpack-plugin')
const appDirectory = fs.realpathSync(process.cwd());
const resolveApp = relativePath => path.resolve(appDirectory, relativePath);
module.exports = {
webpack(config) {
config.plugins.push(new ESLintPlugin({
// Plugin options
extensions: ['js', 'mjs', 'jsx', 'ts', 'tsx'],
eslintPath: require.resolve('eslint'),
context: resolveApp('src'),
cache: true,
cacheLocation: path.resolve(
resolveApp('node_modules'),
'.cache/.eslintcache'
),
// ESLint class options
cwd: resolveApp('.'),
resolvePluginsRelativeTo: __dirname,
baseConfig: {
extends: [require.resolve('eslint-config-react-app/base')],
rules: {},
},
}))
return config
}
}
Note, that when using the above you will need to install eslint-config-react-app and its dependencies (see: https://www.npmjs.com/package/eslint-config-react-app).
Finally, note that since Next.js only renders (compiles) a page when it is needed in development, eslint will only run on a page when it is displayed in the browser as pointed out here: https://github.com/vercel/next.js/issues/9904. This makes adding the following script to package.json as suggested by Roman very useful if you want to do a "full-scan" of your project.
"lint": "eslint ."
You can add a command like this in the scripts section of your package.json:
"lint": "eslint ."
And then you can check your eslint results by running:
npm run lint

Webpack dev server watches Twig

I'm using Symfony 4 with Symfony Encore to handle assets, and some useful features, such as HMR.
Currently, I can handle Sass files, CSS files, JS, etc, and it works fine with HMR.
Now I would like to be able to make Weback dev server watch *.twig files for changes and trigger a live reload (as hot reload wouldn't be an option for server-side rendered templates).
I've seen things about --watchContentBase and contentBase options, but it doesn't do anything in my case:
WDS CLI :
./node_modules/.bin/encore dev-server --hot --disable-host-check --watchContentBase --contentBase ./templates/ --reload
webpack.config.js :
const Encore = require('#symfony/webpack-encore');
const MiniCssExtractPlugin = require('mini-css-extract-plugin');
Encore
.setOutputPath('public/build/')
.setPublicPath('/build')
.cleanupOutputBeforeBuild()
.autoProvidejQuery()
.addPlugin(new MiniCssExtractPlugin('[name].css'))
.enableSourceMaps(!Encore.isProduction())
.addLoader({
test: /\.(sc|sa|c)ss$/,
use: ['css-hot-loader'].concat(
MiniCssExtractPlugin.loader,
{
loader: 'css-loader'
},
{
loader: 'postcss-loader'
},
// {
// loader: 'postcss-loader'
// },
{
loader: 'sass-loader'
}
),
},)
.addLoader({
test: /\.twig$/,
loader: 'raw-loader'
},)
.enableVersioning(Encore.isProduction())
.addEntry('autocall-main', './assets/js/index.js')
// .addStyleEntry('autocall-main', ['./assets/scss/index.scss'])
.splitEntryChunks()
.enableSingleRuntimeChunk()
;
const config = Encore.getWebpackConfig();
module.exports = config;
My project files / folders follows the classic Symfony 4 structure: https://github.com/symfony/demo
What do I miss there?
Today, the year 2020, i have two solutions:
Webpack config solution
As you had said: I've seen things about --watchContentBase and contentBase options..., this has nothing to do with encore. Its a default webpack configurations and you can learn more from webpack doc here
According to Advanced Webpack Config docs here you can extend webpack configs by calling var config = Encore.getWebpackConfig();
I have implemented as shown in the code below. For my case its working fine.
// webpack.config.js
var Encore = require('#symfony/webpack-encore');
var path = require('path');
// Manually configure the runtime environment if not already configured yet by the "encore" command.
// It's useful when you use tools that rely on webpack.config.js file.
if (!Encore.isRuntimeEnvironmentConfigured()) {
Encore.configureRuntimeEnvironment(process.env.NODE_ENV || 'dev');
}
Encore
// directory where compiled assets will be stored
.setOutputPath('public/build/')
.setPublicPath('/build')
.addEntry('global', './assets/app.js')
// ... Your other encore code
// EXTEND/OVERRIDE THE WEBPACK CONFIG
const fullConfig = Encore.getWebpackConfig();
fullConfig.name = 'full';
// watch options poll is used to reload the site after specific set time
// polling is useful when running Encore inside a Virtual Machine
// more: https://webpack.js.org/configuration/watch/
fullConfig.watchOptions = {
poll: true,
ignored: /node_modules/
};
fullConfig.devServer = {
public: 'http://localhost:3000',
allowedHosts: ['0.0.0.0'],
// extend folder to watch in a symfony project
// use of content base
// customize the paths below as per your needs, for this simple
//example i will leave them as they are for now.
contentBase: [
path.join(__dirname, 'templates/'), // watch twig templates folder
path.join(__dirname, 'src/') // watch the src php folder
],
// enable watching them
watchContentBase: true,
compress: true,
open: true,
disableHostCheck: true,
progress: true,
watchOptions: {
watch: true,
poll: true
}
};
// export it
module.exports = fullConfig;
Another solution
If you need a simple implementation you can use: webpack-watch-files-plugin. I prefer this, by the time you are reading this answer it might be abandoned but there many others with same functionality. In Symfony docs here you can implement Custom Loaders & Plugins as below. Using the above mentioned plugin we can implent it as follow:
// webpack.config.js
const WatchExternalFilesPlugin = require('webpack-watch-files-plugin').default;
Encore
// ...your code
.addPlugin(new WatchExternalFilesPlugin({
files: [
'/templates', // watch files in templates folder
'/src', // watch files in src folder
'!../var', // don't watch files in var folder (exclude)
],
verbose: true
}))
//...your code
;
Cheers. Happy coding!
With Symfony 5.4 and Encore 1.0.0 you can configure devServer mannualy in webpack.config.js
...
.configureDevServerOptions((options) => {
options.liveReload = true;
options.hot = true;
options.watchFiles = [
'./templates/**/*',
'./src/**/*'
]
})
...
The loader needs to know also the location of the .twig files, which in Symfony 4 are in /templates directory. Considering the default structure, this should make it work for you:
...
.addLoader({
test: /\.twig$/,
loader: 'raw-loader',
include: [
path.resolve(__dirname, "templates")
],
},)
...
It seems that there is no way to do that (read more on this). As the questioner mentions you can do it with BrowserSync. My preferred Symfony setup is to have two terminals running:
Prerequisites
Install BrowserSync:
npm install -g browser-sync
First terminal
Start the Symfony server on https://127.0.0.1:8000/ and build the assets on https://localhost:8010/:
symfony server:start -d ; yarn encore dev-server --https --port 8010
Second terminal
Reload your browser's request for https://localhost:3000/ every time a Twig file gets changed:
browser-sync start --proxy "https://127.0.0.1:8000/" --files "templates"
If you need only browser-sync you can create bs-config.js:
module.exports = {
"files": [
"templates/**/*.twig",
"src/**/*.php"
],
"proxy": "https://localhost:8000",
};
and then run
browser-sync start --config bs-config.js
remember to accept the "dangerous site" at startup

Resources