vite js build file loaded but empty screen - reactjs

I am building react app using vite.
I run the following command, the preview show everything is working.
npm run build
npm run preview
But when I transfer to the IIS or tomcat server, it show blank page without any error.
Not sure what is happen?
The only different when I deploy to web server I put it into a folder example C:\inetpub\wwwroot\example
Below is my vite.config.ts:
import { defineConfig } from 'vite';
import react from '#vitejs/plugin-react';
import viteTsconfigPaths from 'vite-tsconfig-paths';
import svgrPlugin from 'vite-plugin-svgr';
import { fileURLToPath, URL } from 'url';
// https://vitejs.dev/config/
export default defineConfig({
server: {
port: 3000
},
plugins: [
react(), viteTsconfigPaths(), svgrPlugin()
],
define: {
"global": {},
},
resolve: {
alias: {
'#': fileURLToPath(new URL('./src', import.meta.url)),
},
mainFields: [],
},
css: {
preprocessorOptions: {
scss: {
// example : additionalData: `#import "./src/styles/variables";`
// There is need to include the .scss file extensions.
// additionalData: `#import "./src/styles/variables";`,
},
},
},
base: './',
});

It sounds like your server doesn't know where to find the .html file. Did you configure it to use /wwwroot/example/public as the root?
Try placing the contents of /public (the .js, .css, .html that the build process created) directly inside the /wwwroot folder. So then it would just look like /wwwroot/index.html.

Related

Vitest config doesn't detect jsdom environment

I'm in a Vite/React/TypeScript application and I'm configuring my first test with Vitest.
When I run my Button test (yarn vitest), I get this error:
packages/frontend/src/components/Generic/Button/Button.test.tsx > Button > should render the button
ReferenceError: document is not defined
I understand that Vitest does not work with JSDom. I have tried several things:
KO: Specifying in the vite.config.ts file to use JSDom
OK: Adding a vitest.config.ts file specifying to use JSDom
OK: Adding an annotation (#vitest-environment jsdom) at the top of the test file
I would prefere use the first option (use vite.config.ts) to share only one configuration. Is it possible ?
Note 1 : JSdom i already installed has "devDependencies".
Note 2 : to use vitest.config.ts i should update the script in package.json like that :
"test": "vitest --config ./packages/frontend/vitest.config.ts"
Here are my files:
// vite.config.ts
import { defineConfig } from 'vite'
import react from '#vitejs/plugin-react'
import viteTsConfigPaths from 'vite-tsconfig-paths'
import tailwindcss from 'tailwindcss'
export default defineConfig({
server: {
port: 4200,
host: 'localhost',
},
rollupOption: {
external: ['#internals/components/index']
},
define: {
global: {},
},
plugins: [
react(),
tailwindcss(),
viteTsConfigPaths({
root: '../../',
}),
],
resolve: {
alias: {
// runtimeConfig is a special alias that is used to import the correct config file
'./runtimeConfig': './runtimeConfig.browser',
// public alias
'#publics': `${__dirname}/public`,
// only internals (private) aliases are allowed here
'#internals/components': `${__dirname}/src/components`,
'#internals/features': `${__dirname}/src/features`,
'#internals/hooks': `${__dirname}/src/hooks`,
'#internals/models': `${__dirname}/src/models`,
'#internals/utils': `${__dirname}/src/utils`,
'#internals/types': `${__dirname}/src/types`,
'#internals/styles': `${__dirname}/src/styles`,
'#internals/assets': `${__dirname}/src/assets`,
'#internals/store': `${__dirname}/src/store`,
'#internals/config': `${__dirname}/src/config`,
'#internals/services': `${__dirname}/src/services`,
},
},
test: {
globals: true,
cache: {
dir: '../../node_modules/.vitest',
},
environment: 'jsdom',
include: ['*.tsx', '*.ts', '*.jsx', '*.js'],
},
})
I tried to add a like this vitest.config.ts :
import { defineConfig } from 'vitest/config'
export default defineConfig({
test: {
include: ['*.ts', '*.tsx'], // FIXME
environment: 'jsdom',
},
})

vitejs build with jsx returning MIME error on aws amplify

So I am using Vitejs with a react project.
I am using the jsx extension for all the react files in the appplication.
When using the npm build, then npm run preview the applicaiton is working fine on my computer locally
however when I am using aws amplify, the page is giving me a MIME error:
Failed to load module script: Expected a JavaScript module script but the server responded with a MIME type of "text/jsx". Strict MIME type checking is enforced for module scripts per HTML spec.
Now I tried many configurations for Vite, yet nothing is working, here is my config file
import { defineConfig } from 'vite';
import react from '#vitejs/plugin-react';
import fs from 'fs/promises';
// https://vitejs.dev/config/
export default defineConfig({
plugins: [react()],
esbuild: {
loader: 'jsx',
},
resolve: {
alias: {
'./runtimeConfig': './runtimeConfig.browser',
},
},
optimizeDeps: {
esbuildOptions: {
loader: {
'.js': 'jsx',
},
},
},
})
for anyone that is facing the same issue, what I did is went to AWS build settings, and added:
baseDirectory: /dist
That was it ๐Ÿ˜Š

How do I get HMR (Hot Module Replacement) working with a TypeScript React Monorepo in Vite

I've got a React monorepo (build in TypeScript) and I've recently been switching over from Webpack to Vite. However I'm having real difficult in getting HMR working correctly within Vite (I believe because we separately build our packages).
I'm open to options to get this working (although I think I still need to be able to build my packages, for Jest/ESLint performance).
Project Structure
\apps
\main
\packages
\domainA
\foo
\package.json
\build
\src
At the moment each package gets build using tsc "tsc --project tsconfig.lib.json" into the build directory. The package.json defines the following:
"name": "#ig/foo",
"main": "./build/index.js",
"types": "./build/index.d.ts",
"files": [
"/build"
],
I can spin up the main application and if I make a change in /packages/domainA/foo/src/index.ts then it'll build (currently using a watcher) and I get a full page reload.
I'd like to eliminate the page reload and instead use HMR. I don't think changing the entry point to "main": "./src/index.ts" will work for my use-case due to the slowness in the other tools unfortunately. However I'm happy to try and bypass this and re-point Vite to the source files if necessary.
I've tried all sorts of permutations, having looked at a few sample repos. But not managed to get anything working, e.g.
resolve: {
alias: [{
find: '#ig/foo',
replacement: '../packages/domainA/foo/src/index.ts',
},
}
Here is my current Vite config:
import react from '#vitejs/plugin-react';
import fs from 'fs';
import path, { resolve } from 'path';
import { defineConfig } from 'vite';
import mkcert from 'vite-plugin-mkcert';
import svgrPlugin from 'vite-plugin-svgr';
export default defineConfig({
// optimizeDeps: {
// include: ['#infogrid/solution-views-occupancy'],
// },
build: {
outDir: 'build/public',
sourcemap: true,
rollupOptions: {
input: {
main: resolve(__dirname, 'index.html'),
base: resolve(__dirname, 'index_base.html'),
},
}
},
server: {
port: Number(process.env.PORT),
// setting to true allows external ip
host: true,
},
plugins: [
react({ fastRefresh: true }), // Primarily used for HMR
svgrPlugin({ svgrOptions: { icon: true } }), // Turns svgs into react components
mkcert(), // Allows for HTTPS during local development
]
}

Build problem with React viteJS and was amplify

my question is quite simple to explain. I've initialized a React project with ViteJS and then added aws-amplify for the backend. I developed the project and everything works in my local environment running npm run dev. The problem is that I cannot build it.
You can see the error in the text below. Do you have any idea?
'request' is not exported by __vite-browser-external, imported by node_modules/#aws-sdk/credential-provider-imds/dist/es/remoteProvider/httpRequest.js
Error logs
In vite.config.js add:
resolve: {
alias: {
'./runtimeConfig': './runtimeConfig.browser',
},
}
in define field
Working config for React polyfilled for AWS SDK and Amplify
import { defineConfig } from "vite";
import react from "#vitejs/plugin-react";
import rollupNodePolyFill from "rollup-plugin-node-polyfills";
// https://vitejs.dev/config/
export default defineConfig({
plugins: [react()],
optimizeDeps: {
esbuildOptions: {
// Node.js global to browser globalThis
define: {
global: "globalThis", //<-- AWS SDK
},
},
},
build: {
rollupOptions: {
plugins: [
// Enable rollup polyfills plugin
// used during production bundling
rollupNodePolyFill(),
],
},
},
resolve: {
alias: {
'./runtimeConfig': './runtimeConfig.browser', // <-- Fix from above
},
}
});
when using an array of aliases.
resolve: {
alias: [
{
find: '#', replacement: path.resolve(__dirname, './src'),
},
{
find: './runtimeConfig', replacement: './runtimeConfig.browser',
}
]
}
For the issue "'request' is not exported by __vite-browser-external", just install the http package (e.g 'npm i http')
It appears root cause of this type of issue is that aws-amplify JS lib is relying on Node specific features. There is a two part workaround:
To solve errors like 'xxxxx' is not exported by __vite-browser-external add additional alias for ./runtimeConfig to the vite.config.ts file. So it will look something like:
alias: {
"#": fileURLToPath(new URL("./src", import.meta.url)),
'./runtimeConfig': './runtimeConfig.browser',
},
To solve error like Uncaught ReferenceError: global is not defined, declare corresponding global variable in your topmost html file (index.html)
<script>
var global = global || window;
var Buffer = Buffer || [];
var process = process || {
env: { DEBUG: undefined },
version: []
};
</script>
There is github issue open for more than a year now: https://github.com/aws-amplify/amplify-js/issues/9639

Absolute path not working in Vite project React TS

I'm struggling to get absolute path to work in a Vite react-ts project.
Here's how I created the project
npm init #vitejs/app
npx: installed 6 in 1.883s
โˆš Project name: ... test-vite
โˆš Select a framework: ยป react
โˆš Select a variant: ยป react-ts
Then I added baseUrl to tsconfig.json
based on the TS official doc:
{
"compilerOptions": {
"baseUrl": "./src",
...
followed by adding a simple component (T:\test-vite\src\components\Test.tsx)
import React from "react";
const Test = () => <h1>This is a Test.</h1>;
export default Test;
Finally I import the Test component in App.tsx
but it won't let me use absolute path:
import Test from "components/Test";
I get this error
whereas if I use relative path, the app works in dev & build mode without any error:
import Test from "./components/Test";
How can I make absolute path work in the project?
There are two problems here:
Tell typescript how to resolve import path
Tell vite how to build import path
You only tell typescript how to resolve, but vite don't konw how to build. So refer to the official document resolve.alias, maybe this is what you want:
// vite.config.ts
{
resolve: {
alias: [
{ find: '#', replacement: path.resolve(__dirname, 'src') },
],
},
// ...
}
You can import path like this (or any module under ./src):
import Test from "#/components/Test";
import bar from "#/foo/bar"
Moreover, you can use vite plugin vite-tsconfig-paths directly, it makes you don't have to manually configure resolve.alias
Follow the instructions below:
Install vite-tsconfig-paths as dev dependency
Inject vite-tsconfig-paths using the vite.config.ts module
import { defineConfig } from 'vite'
import tsconfigPaths from 'vite-tsconfig-paths'
export default defineConfig({
plugins: [tsconfigPaths()],
})
I came here through search results, I was looking for something different, namely, how to do a simple absolute import like import { foo } from 'src/lib/foo.ts'
So if you have a /src directory that contains all code and want to use an absolute import path.
vite.config.ts
export default defineConfig({
...
resolve: {
alias: {
src: path.resolve('src/'),
},
}
})
tsconfig.json
{
"compilerOptions": {
...
"baseUrl": "./"
}
}
Note that this is a trick: src is an alias, so it appears like the path is absolute in Vite. If you have another directory in the root dir, adjacent to /src, you will need to add another alias for that directory.
#Yuns solutions works, but it shows error in vscode. And it was breaking auto-import in vs code.
To make it work in vscode and vite both, I added alias in both tsconfig and vite.config.
// tsconfig.json
{
"paths": {
"#/*": ["src/*"]
}
// ...
}
// vite.config.ts
{
resolve: {
alias: [{ find: '#', replacement: '/src' }],
},
// ...
}
Then, I could import like below (svelte app is in src directory)
import Header from '#/components/Header.svelte
Looking for import {...} from "src/foo/bar";?
I also came here through search results like user Maciej Krawczyk, but the # part also wasn't what I was interested in. That user's answer helped me, but I had trouble with the path.resolve part (ReferenceError because path wasn't defined), so I used a slightly different approach:
vite.config.ts
export default defineConfig({
...
resolve: {
alias: {
src: "/src",
},
},
...
})
Vite's resolver considers the absolute path /src to be from where the server is serving (see GH issue). So if you're running/building from the root of your project with src as a top level directory -- which is pretty common -- this alias points Vite in the right direction.
tsconfig.json
{
"compilerOptions": {
...
"baseUrl": "./",
"paths": {
"src/*": [
"./src/*"
]
}
}
}
This is basically blindly following this StackOverflow answer. TypeScript needs to know that we have special resolving going on as well, otherwise TS will be freaked out about your non-existent src package and not know where it should go looking. (Note: After I changed my TS config, VSCode didn't immediately pick up the change, so I was still getting warnings. I quit, re-opened, and had to wait ~15sec for the warnings to go away.)
1) You need to install these packages:
npm i path
yarn add path
npm i #types/node
yarn add #types/node
npm i vite-tsconfig-paths
yarn add vite-tsconfig-paths
2) Then in the vite.config file:
import { defineConfig } from 'vite';
import react from '#vitejs/plugin-react';
import tsconfigPaths from 'vite-tsconfig-paths';
import path from 'path';
export default defineConfig({
base: './',
resolve: {
alias: {
Components: path.resolve(__dirname, './src/components'),
Assets: path.resolve(__dirname, './src/assets'),
},
},
plugins: [react(), tsconfigPaths()],
});
3) And now we have to tell TS those same paths that we defined in the alias:
{
"compilerOptions": {
...,
"baseUrl": "./",
"paths": {
"src/*": [ "./src/*" ],
// We define this path for all files/folders inside
// components folder:
"Components/*": [ "./src/components/*" ],
// We define this path for the index.ts file inside the
// components folder:
"Components": [ "./src/components" ],
"Assets/*": [ "./src/assets/*" ],
"Assets": [ "./src/assets" ]
}
},
...
}
4) reload vscode: As the comment above said, press Fn1 and type "reload with extensions disabled", re-enabling extensions from the popup.
Now try to import
import Test from "components/Test";
it should work.
For anyone looking specifically to add the nice import "#/something-in-src" syntax like Vue has with the latest (as of posting this answer) version of Vite + React + TypeScript, here's how I did it:
Make sure #types/node is installed as a dev dependency. This didn't come with the latest version of Vite for me, and it will make "path" and __dirname throw an undefined error.
vite.config.ts
import { defineConfig } from "vite";
import react from "#vitejs/plugin-react";
import path from "path";
// https://vitejs.dev/config/
export default defineConfig({
resolve: {
alias: [{ find: "#", replacement: path.resolve(__dirname, "src") }],
},
plugins: [react()],
});
tsconfig.json
Add:
{
"compilerOptions": {
"paths": {
"#/*": ["./src/*"]
}
}
}
For anyone who stucks after all required changes, you need to reload vscode.
My config files:
tsconfig.json
"baseUrl": "./",
"paths": {
"#/*": ["src/*"]
}
vite.config.ts
import { defineConfig } from 'vite';
import react from '#vitejs/plugin-react';
import path from 'path';
// https://vitejs.dev/config/
export default defineConfig({
resolve: {
alias: { '#': path.resolve(__dirname, './src') },
},
plugins: [react()],
});
In above code you need to have 2 libraries installed:
'path': npm i path
'#types/node': npm i #types/node
After configure your project files you need to reload vscode. To do that press ctrl + P and type ">reload with extensions disabled", after that you will get popUp to activate extensions again click it, and your absoulte path should work
If someone installed vite-tsconfig-paths library, you also need to reload the vscode, remember to import given library to vite.config.ts
export default defineConfig({ plugins: [react(), tsconfigPaths()] });
With package you get default 'components/File' import instead of '#components/File' import.

Resources