How to deploy an generate a static site on Nuxt 3 - deployment

Hello I'm creating website on Nuxt and i have created a new app on Nuxt 3. But I have an probleme for the deployement, there is no 'normal' build for 'normal server' as Nuxt 2.x.
I'm using 'Lamdba' preset.
https://v3.nuxtjs.org/docs/deployment/presets/lambda
// nuxt.config.ts
import { defineNuxtConfig } from 'nuxt3'
// https://v3.nuxtjs.org/docs/directory-structure/nuxt.config
export default defineNuxtConfig({
// Global page headers: https://go.nuxtjs.dev/config-head
nitro: {
preset: 'lambda'
},
head: {
title: 'Title',
meta: [
{ charset: 'utf-8' },
{ name: 'viewport', content: 'width=device-width, initial-scale=1' }
],
link: [
{ rel: 'icon', type: 'image/png', href: '/favicon.png' }
],
script: [
{
type: 'text/javascript',
src: '/mana.js',
}
]
},
})
And on Nuxt 2.x I used this :
// nuxt.config.js
export default {
// Disable server-side rendering: https://go.nuxtjs.dev/ssr-mode
ssr: false,
// Target: https://go.nuxtjs.dev/config-target
target: 'static'
}
What configuration i should to use on Nuxt 3 to have 'normal' export with an index.html file at the root for all server ?

Please use generate script like yarn generate this will create the .output/public and output will depend on ssr: boolean property in nuxt.config.ts.
if ssr is true which is by default, then there will be individual html for each dynamic route and that means dynamic routes are rendered at build time and whenever there is change in data or number of dynamic routes then you will need to run this command again.
if ssr is false then rendering will be done at client side, like SPA app and dynamic routes will have only one file that will do client side rendering and data will be fetched at client side that way site will show latest data.
Check static-hosting

Static deployment is not currently available for Nuxt 3

Besides adding target: 'static' in your nuxt.config.ts
export default defineNuxtConfig({
target: 'static' // default is 'server'
})
You also need to update your build script to be nuxi generate in your package.json (which was nuxi build originally)
{
"scripts": {
"build": "nuxi generate"
}
}
References: https://v3.nuxtjs.org/bridge/overview#static-target

I managed to deploy my nuxt3 project static to gh-pages. I had to overcome two obstacles.
yarn generate did not generate static routes until I explicitly forced it by setting
generate: {routes: ['/','all','my','other','routes']} ....
in nuxt.config.js as target:"static" did not work for me.
gh-pages need an empty .nojekyll file which seems currently not being generated by nuxt generate nor gh-pages. I entered the following into my package.json:
"deploy": "touch .output/.nojekyll && gh-pages --dotfiles -d .output"
This seems ugly but works for me.

Related

How to pass options to babel plugin transform-modules-commonjs?

I create a Vue 2 project by Vue-Cli 5, then I want to remove "use strick" in the complied code.
As I Know, the #babel/plugin-transform-strick-mode may be enabled via #babel/plugin-transform-modules-commonjs, and the plugin is included in #babel/preset-env under the modules option.
But the Vue-Cli used a preset #vue/babel-preset-app by a plugin #vue/cli-plugin-babel for babel.
So my question is How pass strictMode: false as an option to the transform-modules-commonjs by #vue/babel-preset-app which preset is in the #vue/cli-plugin-babel ?
module.exports = {
presets: [["#vue/cli-plugin-babel/preset", { modules: "auto" }]],
plugins: [
// I tried this way, but it throw many errors like:
/**
ERROR in ./node_modules/axios/dist/node/axios.cjs 11:15-32
Module not found: Error: Can't resolve 'stream' in 'D:\workspace\cqset_offical_website\node_modules\axios\dist\node'
BREAKING CHANGE: webpack < 5 used to include polyfills for node.js core modules by default.
This is no longer the case. Verify if you need this module and configure a polyfill for it.
If you want to include a polyfill, you need to:
- add a fallback 'resolve.fallback: { "stream": require.resolve("stream-browserify") }'
- install 'stream-browserify'
If you don't want to include a polyfill, you can use an empty module like this:
resolve.fallback: { "stream": false }
*/
["#babel/plugin-transform-modules-commonjs", {}],
[
"component",
{
libraryName: "element-ui",
styleLibraryName: "theme-chalk",
},
],
],
};

VitePWA plugin not updating generated icons in manifest

I have a site with PWA img assets in
img/icons/imagename.png
I am trying to build the site with vite and vite-plugin-pwa to use it as a pwa.
The vite.config.js and the index.html are in the project root directory. Images are in img directory.
The problem is that when I run the build file places the imgs in the folder assets/imageName###.png
For example chrome192.png is placed in assets/chrome192.f25426fd.png
However, the manifest file generated upon build manifest.webmanifest still contains
src: 'img/icons/chrome192.png',
The application tab for dev tools in chrome shows {rootURL}/img/icon/chrome192.png not found. Which is expected since the bundling with vite build places it in a different folder (assets).
Why does it not update the path of the images in the generated manifest.webmanifest?
Isn't that the whole point of the vite-plugin-pwa to keep track of the filenames that change upon build.
Another issue is that I have different routes eg: html/about
Inside the about.html generated on build, the web manifest path is given as:
<link rel="manifest" href="./manifest.webmanifest">
It uses this path instead of using ../manifest.webmanifest or maybe a path from the root without the ./ such as href="./manifest.webmanifest"
My vite.config.js is shown below
import { resolve } from 'path';
import { defineConfig } from 'vite';
import { VitePWA } from 'vite-plugin-pwa'
// import legacy from '#vitejs/plugin-legacy';
export default defineConfig({
plugins: [
VitePWA({
includeAssets: ['img/icons/favicon.png', 'img/icons/maskable_icon.png' ],
manifest: {
name: 'Final Countdown',
start_url: "/",
short_name: 'Final Countdown',
description: 'Awesome countdown App',
theme_color: '#031c36',
icons: [
{
src: 'img/icons/chrome192.png',
sizes: '192x192',
type: 'image/png'
},
{
src: 'img/icons/chrome512.png',
sizes: '512x512',
type: 'image/png'
},
{
src: 'img/icons/chrome512.png',
sizes: '512x512',
type: 'image/png',
purpose: 'any maskable'
}
]
}
})
],
build: {
rollupOptions: {
input: {
main: resolve(__dirname, 'index.html'),
about: resolve(__dirname, 'html/about.html'),
countdownList: resolve(__dirname, 'html/countdown-list.html'),
fallback: resolve(__dirname, 'html/fallback.html'),
today: resolve(__dirname, 'html/today.html'),
formupload: resolve(__dirname, 'html/form-upload.html'),
},
},
},
});
The code is hosted at this branch if you need to take a look at the full folder
https://github.com/RDjarbeng/countdown/tree/vitePWA
I have removed the previous manifest.json file that used to work before I started using the vite-plugin-pwa, because when it was included there were two manifest files in the build instead.
Have also tried using /img/icons/... for the paths and resolve(__dirname, img/icons/chrome192.png)
How do I get the PWA manifest and icons to sync with the image build files generated by the viteJS bundler and satisfy the PWA conditions?
How do I get the paths of html files not in the root folder to use the correct path to the manifest.webmanifest?
If the icon is only being used in the webmanifest icons, those icons should go to public folder.
Create a folder named public in the root directory and move the icons for the manifest there. Vite will add these to the build without changing the file names.
Find full solution here.
https://github.com/vite-pwa/vite-plugin-pwa/issues/396
You do not need to add public/ to the names of the images in the manifest.json.
In the end the vite config, vitePWA contained
...
includeAssets: ["**/*.{png}"],
manifest: {
name: 'Final Countdown',
start_url: "/",
id: "/",
short_name: 'Final Countdown',
description: 'Awesome countdown App',
theme_color: '#031c36',
icons: [
{
src: '/img/icons/chrome192.png',
sizes: '192x192',
type: 'image/png'
},
{
src: '/img/icons/chrome512.png',
sizes: '512x512',
type: 'image/png'
},
]
},
Full path to the image:
{rootURL}/public/img/icons/chrome192.png
where {rootURL} is the root url from which the site is served

Gatsby not working paths deployed on the github pages (adding repo name in the url)

I deployed a gatsby website with the Github pages and I'm having errors like that:
Locally everything works perfectly, errors occur only on the server.
Seems like the server can not resolve paths correctly.
I'm adding unnecessary repository name after domain. How to remove that?
I tried changing some host options and deploying app again and once it worked properly, IDK why, then I made another deploy and it crushed again.
My gatsby.config:
const path = require("path");
const { title, keywords, description, author, defaultLang, trackingId } = require("./config/site");
module.exports = {
pathPrefix: "/lbearthworks",
siteMetadata: {
title,
keywords,
description,
author,
},
plugins: [
{
resolve: "gatsby-plugin-google-analytics",
options: {
trackingId,
},
},
{
resolve: "gatsby-plugin-manifest",
options: {
name: title,
short_name: "Lb",
start_url: "/",
background_color: "#212121",
theme_color: "#fed136",
display: "minimal-ui",
icon: "content/assets/gatsby-icon.png",
},
},
"gatsby-transformer-remark",
{
resolve: "gatsby-source-filesystem",
options: {
name: "markdown",
path: `${__dirname}/content`,
},
},
{
resolve: "gatsby-source-filesystem",
options: {
name: "images",
path: `${__dirname}/content/assets/images`,
},
},
"gatsby-plugin-eslint",
"gatsby-plugin-react-helmet",
"gatsby-transformer-sharp",
"gatsby-plugin-sharp",
"gatsby-plugin-offline",
{
resolve: "gatsby-plugin-sass",
options: {
data: `#import "core.scss";`,
includePaths: [path.resolve(__dirname, "src/style")],
},
},
...
],
};
Live version
Github Reository
When dealing with GitHub Pages you need to add an extra configuration to your build command, since you are adding a pathPrefix variable, you need to allow Netlify how to prefix those paths. Ideally, the build command should look like:
"deploy": "gatsby build --prefix-paths && gh-pages -d public"
In your case, because you are adding a file-based configuration (netlify.toml), your build command is:
[build]
command = "yarn && yarn testbuild"
publish = "public"
Note that testbuild is yarn test && yarn build, according to your repository.
So, one workaround is changing your package.json command to:
"testbuild": "yarn test && yarn build --prefix-paths && gh-pages -d public",
In addition, you should be in gh-pages branch as it shows the Gatsby's documentation:
When you run npm run deploy all contents of the public folder will be
moved to your repository’s gh-pages branch. Make sure that your
repository’s settings has the gh-pages branch set as the source to
deploy from.

Troubles combining bundling Svelte Material UI with custom SCSS using Rollup

I have Svelte 3.x (with TS enabled) and a pretty standard Rollup config for bundling my SCSS files with this file structure:
| src
| styles.scss
| etc.
rollup.config.js:
export default {
input: 'src/main.ts',
output: {
sourcemap: true,
format: 'iife',
name: 'myapp',
file: 'public/build/bundle.js'
},
plugins: [
svelte({
// enable run-time checks when not in production
dev: !production,
// we'll extract any component CSS out into
// a separate file - better for performance
css: css => {
css.write('bundle.css');
},
preprocess: autoPreprocess(),
}),
// If you have external dependencies installed from
// npm, you'll most likely need these plugins. In
// some cases you'll need additional configuration -
// consult the documentation for details:
// https://github.com/rollup/plugins/tree/master/packages/commonjs
resolve({
browser: true,
dedupe: ['svelte']
}),
commonjs(),
typescript({ sourceMap: !production }),
// In dev mode, call `npm run start` once
// the bundle has been generated
!production && serve(),
// Watch the `public` directory and refresh the
// browser on changes when not in production
!production && livereload('public'),
// If we're building for production (npm run build
// instead of npm run dev), minify
production && terser()
],
watch: {
clearScreen: false
}
};
This works fine. Now I'm struggling getting Svelte Material UI running.
After installing postcss, rollup-plugin-postcss, rollup-plugin-sass, svelte-material-uiand svelte-preprocess-sass and reading through here and there and there I added this to the plugins array in rollup.config.js:
postcss({
extract: true,
minimize: true,
use: [
['sass', {
includePaths: [
'./src/theme',
'./node_modules'
]
}]
]
})
When I test it in my app using a #smui/button the button (with a default styling and the default ripple effect) works, but none of my SCSS gets compiled (or get overwritten during bundling).
I'm searching the needle in the haystack and appreciate any hint.
Got it, I just missed adding emitCss: true in the Svelte plugin config. So my working rollup.config.js is this:
export default {
input: 'src/main.ts',
output: {
sourcemap: true,
format: 'iife',
name: 'myapp',
file: 'public/build/bundle.js'
},
plugins: [
svelte({
// enable run-time checks when not in production
dev: !production,
// we'll extract any component CSS out into
// a separate file - better for performance
css: css => {
css.write('bundle.css');
},
emitCss: true,
preprocess: autoPreprocess()
}),
// If you have external dependencies installed from
// npm, you'll most likely need these plugins. In
// some cases you'll need additional configuration -
// consult the documentation for details:
// https://github.com/rollup/plugins/tree/master/packages/commonjs
resolve({
browser: true,
dedupe: ['svelte']
}),
commonjs(),
typescript({ sourceMap: !production }),
// In dev mode, call `npm run start` once
// the bundle has been generated
!production && serve(),
// Watch the `public` directory and refresh the
// browser on changes when not in production
!production && livereload('public'),
// If we're building for production (npm run build
// instead of npm run dev), minify
production && terser()
],
watch: {
clearScreen: false
}
};
This also has been answered here.

Swagger Tools Production Build Node js

We implemented the swagger in our nodeJs application. As of now we are created production build using webpack and remove the controller and services file.
bin/www.js
const YAML = require('yamljs');
const swaggerTools = require('swagger-tools');
const swaggerDoc = YAML.safeLoad('./swagger.yaml');
// swaggerRouter configuration
const swaggerOptions = {
controllers: path.join(__dirname, '../public/javascripts/controllers'),
useStubs: true, // Conditionally turn on stubs (mock mode)
};
// Initialize the Swagger middleware
swaggerTools.initializeMiddleware(swaggerDoc, (middleware) => {
// Interpret Swagger resources and attach metadata to request - must be first in swagger-tools middleware chain
app.use(middleware.swaggerMetadata());
// validate the security using JWT token
app.use(middleware.swaggerSecurity({
Bearer: auth.verifyToken
}));
// Validate Swagger requests
app.use(middleware.swaggerValidator({
validateResponse: true
}));
// Route validated requests to appropriate controller
app.use(middleware.swaggerRouter(swaggerOptions));
// Serve the Swagger documents and Swagger UI
app.use(middleware.swaggerUi());
});
If we did the same in production build and the swagger middleware expecting the same path to resolve. after build we delete the public folder.
Webpack code
const path = require('path');
const nodeExternals = require('webpack-node-externals');
module.exports = {
entry: {
server: './bin/www',
},
output: {
path: path.join(__dirname, 'dist'),
publicPath: '/',
filename: 'server.build.js',
},
target: 'node',
node: {
// Need this when working with express, otherwise the build fails
__dirname: false, // if you don't put this is, __dirname
__filename: false, // and __filename return blank or /
},
externals: [nodeExternals()],
module: {
rules: [
{
// Transpiles ES6-8 into ES5
test: /\.js$/,
exclude: /node_modules/,
use: {
loader: 'babel-loader',
},
},
],
},
};
Pleas help us to create a build using swagger middleware
Thanks in advance
Swagger tools is not a package bundler like webpack. So you will still need to provide it the controller files. Since you are deleting /public from prod then there is no way for swagger tools middleware to get the files it needs. Webpack in this case is basically building a dist from your code which is why it's ok to delete the controller and services.