Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Could not copy the file "<full path js file>" because it was not found #89

Open
luysantana opened this issue Jan 25, 2024 · 3 comments
Open
Labels
bug Something isn't working

Comments

@luysantana
Copy link

When I try to publish my app to a folder (trying to execute localhost to sure that It will works on production), I have the error in title for every entry file.

It's strange, because when I comment csproj, publish, uncomment csproj and publish, the publish occurs for once, but fail for next ones:

 <!--Build the final assets--> 
<Target Name="PublishBuildAssets" BeforeTargets="Build" Condition=" '$(Configuration)' == 'Release' ">
	 <!--Build the final assets--> 
	<Exec Command="npm run prd" />
</Target>

Analyzing the build log, I see that npm run prd occurs 2 times, one before build and one before publish, I think the files are recreated with another name and msbuild loses the references.

I have try like this:

<Target Name="NpmInstall" Inputs="package.json">
    <Exec Command="npm install" />
</Target>

<Target Name="NpmRunBuild" DependsOnTargets="NpmInstall" BeforeTargets="BeforeBuild" >
    <Exec Command="npm run prd" />
</Target>

But like the first one, It fails after the first time. Another thing is for the first publish, It's doesn't load js and css files.
The console shows that the manifest file doesn't exists, but exists in the folder.

I have this configuration:


/**
 * Name: vite.config.ts
 * Description: Vite configuration file
 */

import { defineConfig } from "vite";
import { spawn } from "child_process";
import fs from "fs";
import path from "path";
import { fileURLToPath } from "url";
import { glob }from "glob";

// Get base folder for certificates.
const baseFolder =
	process.env.APPDATA !== undefined && process.env.APPDATA !== ""
		? `${process.env.APPDATA}/ASP.NET/https`
		: `${process.env.HOME}/.aspnet/https`;

// Generate the certificate name using the NPM package name
const certificateName = process.env.npm_package_name;

// Define certificate filepath
const certFilePath = path.join(baseFolder, `${certificateName}.pem`);
// Define key filepath
const keyFilePath = path.join(baseFolder, `${certificateName}.key`);

// Export Vite configuration
export default defineConfig(async () => {
	// Ensure the certificate and key exist
	if (!fs.existsSync(certFilePath) || !fs.existsSync(keyFilePath)) {
		// Wait for the certificate to be generated
		await new Promise((resolve) => {
			spawn("dotnet", [
				"dev-certs",
				"https",
				"--export-path",
				certFilePath,
				"--format",
				"Pem",
				"--no-password",
			], { stdio: "inherit", })
				.on("exit", (code) => {
					resolve();
					if (code) {
						process.exit(code);
					}
				});
		});
	};

	// Define Vite configuration
	const config = {
		appType: "custom",
		root: "wwwroot/src",
		build: {
			emptyOutDir: true,
			manifest: true, 
			outDir: "../dist",
			assetsDir: "",
			rollupOptions: {
				input: Object.fromEntries(
					glob
						.sync("./wwwroot/src/**/js/[^_]*.js")
						.map(file => [file.split("\\")[file.split("\\").length - 1], fileURLToPath(new URL(file, import.meta.url))]),
				),
			},
		},
		server: {
			strictPort: true,
			https: {
				cert: certFilePath,
				key: keyFilePath
			}
		},
		optimizeDeps: {
			include: []
		}
	}

	return config;
});


Program.cs

var builder = WebApplication.CreateBuilder(args);

builder.Services.AddViteServices(opt =>
{
	opt.Server.AutoRun = true;
	opt.Server.Https = true;
	opt.Manifest = "wwwroot/dist/.vite/manifest.json";
});

//...

var app = builder.Build();

if (app.Environment.IsEnvironment("production"))
{
	app.UseExceptionHandler("/Home/Error");
	app.UseHsts();
}

//...

if (app.Environment.IsEnvironment("DEBUG"))
{
	app.UseViteDevelopmentServer(true);
	app.UseDeveloperExceptionPage();
}

app.Run();


cshtml files (this is layout.cshtml, but the others follow the same)

<link rel="stylesheet" vite-href="~/layout/js/layout.js" asp-append-version="true" />
<script type="module" vite-src="~/layout/js/layout.js" asp-append-version="true"></script>

I try to do what the Wiki says, but I think that doesn't affect the publish process
This is after vite build
image

I'm using VS2022 17.8.5
dotnet 8.0.101
the app uses version 7 of sdk

@luysantana luysantana added the bug Something isn't working label Jan 25, 2024
@Deepfreezed
Copy link

Yes, I experienced this as well. I am not sure if it's related the VS publishing process with npm build or Vite.AspNetCore. It does work if I update the project file like mentioned but fails subsequent tries.

@Eptagone
Copy link
Owner

Eptagone commented Feb 17, 2024

It runs two times because you have the tasks PublishBuildAssets and NpmRunBuild to run the same command, the first one runs before Build and the second runs before BeforeBuild. So, the order is:

  • NpmRunBuild
  • PublishBuildAssets
    Try to change it to something like this:
<!-- Ensure Node environment on Build -->
  <Target Name="DebugEnsureNodeEnv" BeforeTargets="Build;PublishBuildAssets" Condition=" !Exists('Assets\node_modules') ">
    <!-- Install Node packages -->
    <Exec Command="npm install" />
  </Target>

  <!-- Build the final assets -->
  <Target Name="PublishBuildAssets" BeforeTargets="Build" Condition=" '$(Configuration)' == 'Release' ">
    <!-- Build the final assets -->
    <Exec Command="npm run build" />
  </Target>

And also, I can see you are using a base directory. Your base directory should be configured to /dist/ in your vite.config.ts and also in your program.cs file. You can see an example in the Wiki.

I see you have "wwwroot/dist/.vite/manifest.json" as your manifest name. The manifest name is relative to your wwwroot folder and base directory which is dist. Your manifest name is .vite/manifest.json which is the default value, so you can omit it. You should have something like this:

builder.Services.AddViteServices(opt =>
{
	opt.Server.AutoRun = true;
	opt.Base = "/dist/";
	opt.Server.Https = true;
});

I also suggest you move your assets in wwwroot/src to another folder like Client, Assets, etc. Otherwise, those files will also copied on publish. You don't want that, do you?

@Deepfreezed
Copy link

I was still running into this issue on publish. You need to run npm run build command on 'Publish'. If you run it on 'Build' it will build twice and mess-up the wwwroot file copy references.

Or if it still does not work, just build npm before publish so the manifest is there and ignore npm commands in Visual Studio.

<!-- Ensure Node.js is installed -->
<Target Name="DebugEnsureNodeEnv" BeforeTargets="Build;Publish;PublishBuildAssets" Condition=" !Exists('node_modules') ">
  <Exec Command="node --version" ContinueOnError="true">
    <Output TaskParameter="ExitCode" PropertyName="ErrorCode" />
  </Exec>
  <Error Condition="'$(ErrorCode)' != '0'" Text="Node.js is required to build and run this project. To continue, please install Node.js from https://nodejs.org/, and then restart your command prompt or IDE." />
  <Message Importance="high" Text="Restoring dependencies using 'npm'. This may take several minutes..." />
  <Exec Command="npm install" />    
</Target>  

<Target Name="PublishBuildAssets" BeforeTargets="Publish" Condition=" '$(Configuration)' == 'Release' ">
  <Exec Command="npm run build" />
</Target>

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
bug Something isn't working
Projects
None yet
Development

No branches or pull requests

3 participants